/** 画面から消す際の処理を表します。 */ @Override public void setVisibility(int visibility) { // 画面表示時 if (visibility != View.VISIBLE) { // 画面から消す時は長押しをキャンセルし、画面端に強制的に移動します。 cancelLongPress(); setScale(SCALE_NORMAL); if (mIsMoveAccept) { moveToEdge(false); } mAnimationHandler.removeMessages(FloatingAnimationHandler.ANIMATION_IN_TOUCH); mLongPressHandler.removeMessages(LongPressHandler.LONG_PRESSED); } super.setVisibility(visibility); }
/** 初回描画時の座標設定を行います。 */ @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(this); // 画面端に移動しない場合は指定座標に移動 if (mMoveDirection == FloatingViewManager.MOVE_DIRECTION_NONE) { mParams.x = mInitX; mParams.y = mInitY; moveTo(mInitX, mInitY, mInitX, mInitY, false); } else { mParams.x = 0; mParams.y = mMetrics.heightPixels - mStatusBarHeight - getMeasuredHeight(); moveToEdge(false); } mIsDraggable = true; mWindowManager.updateViewLayout(this, mParams); return true; }
/** {@inheritDoc} */ @Override public boolean dispatchTouchEvent(@NonNull MotionEvent event) { // Viewが表示されていなければ何もしない if (getVisibility() != View.VISIBLE) { return true; } // タッチ不能な場合は何もしない if (!mIsDraggable) { return true; } // 現在位置のキャッシュ mScreenTouchX = event.getRawX(); mScreenTouchY = event.getRawY(); final int action = event.getAction(); // 押下 if (action == MotionEvent.ACTION_DOWN) { // アニメーションのキャンセル cancelAnimation(); mScreenTouchDownX = mScreenTouchX; mScreenTouchDownY = mScreenTouchY; mLocalTouchX = event.getX(); mLocalTouchY = event.getY(); mIsMoveAccept = false; setScale(SCALE_PRESSED); // タッチトラッキングアニメーションの開始 mAnimationHandler.updateTouchPosition(getXByTouch(), getYByTouch()); mAnimationHandler.removeMessages(FloatingAnimationHandler.ANIMATION_IN_TOUCH); mAnimationHandler.sendAnimationMessage(FloatingAnimationHandler.ANIMATION_IN_TOUCH); // 長押し判定の開始 mLongPressHandler.removeMessages(LongPressHandler.LONG_PRESSED); mLongPressHandler.sendEmptyMessageDelayed(LongPressHandler.LONG_PRESSED, LONG_PRESS_TIMEOUT); // 押下処理の通過判定のための時間保持 // mIsDraggableやgetVisibility()のフラグが押下後に変更された場合にMOVE等を処理させないようにするため mTouchDownTime = event.getDownTime(); } // 移動 else if (action == MotionEvent.ACTION_MOVE) { // 移動判定の場合は長押しの解除 if (mIsMoveAccept) { mIsLongPressed = false; mLongPressHandler.removeMessages(LongPressHandler.LONG_PRESSED); } // 押下処理が行われていない場合は処理しない if (mTouchDownTime != event.getDownTime()) { return true; } final float moveThreshold = MOVE_THRESHOLD_DP * mMetrics.density; // 移動受付状態でない、かつX,Y軸ともにしきい値よりも小さい場合 if (!mIsMoveAccept && Math.abs(mScreenTouchX - mScreenTouchDownX) < moveThreshold && Math.abs(mScreenTouchY - mScreenTouchDownY) < moveThreshold) { return true; } mIsMoveAccept = true; mAnimationHandler.updateTouchPosition(getXByTouch(), getYByTouch()); } // 押上、キャンセル else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { // 判定のため長押しの状態を一時的に保持 final boolean tmpIsLongPressed = mIsLongPressed; // 長押しの解除 mIsLongPressed = false; mLongPressHandler.removeMessages(LongPressHandler.LONG_PRESSED); // 押下処理が行われていない場合は処理しない if (mTouchDownTime != event.getDownTime()) { return true; } // アニメーションの削除 mAnimationHandler.removeMessages(FloatingAnimationHandler.ANIMATION_IN_TOUCH); // 拡大率をもとに戻す setScale(SCALE_NORMAL); // 動かされていれば画面端に戻す if (mIsMoveAccept) { moveToEdge(true); } // 動かされていなければ、クリックイベントを発行 else { if (!tmpIsLongPressed) { final int size = getChildCount(); for (int i = 0; i < size; i++) { getChildAt(i).performClick(); } } } } // タッチリスナを通知 if (mOnTouchListener != null) { mOnTouchListener.onTouch(this, event); } return true; }