檢測某個子 View 是否被手指滑動經過 (非點擊,非拖拽該 View 本身),觸發回調。
public class DetectableFrameLayout extends FrameLayout {
private View targetView;
private OnViewPassedListener listener;
public interface OnViewPassedListener {
void onViewPassed(View view, MotionEvent event);
}
public DetectableFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setTargetView(View targetView, OnViewPassedListener listener) {
this.targetView = targetView;
this.listener = listener;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (targetView != null && listener != null) {
// 獲取觸摸點在父佈局坐標系下的位置
float x = event.getX();
float y = event.getY();
// 獲取目標 View 在父佈局中的矩形區域
Rect rect = new Rect();
targetView.getHitRect(rect); // 或 getGlobalVisibleRect(rect) 配合 offset
// 判斷觸摸點是否在目標區域內
if (rect.contains((int)x, (int)y)) {
listener.onViewPassed(targetView, event);
}
}
return super.onTouchEvent(event); // 繼續分發
}
}
// XML
// Activity/Fragment
DetectableFrameLayout root = findViewById(R.id.root);
View target = findViewById(R.id.target_view);
root.setTargetView(target, (view, event) -> {
// 手指滑過 target 區域時回調
// 可根據 event.getAction() 區分 DOWN/MOVE/UP
});
若不想自定義父佈局,可在父 View 設置 `OnTouchListener`,邏輯相同。但 `onTouchEvent` 覆寫更符合「父佈局統一檢測多個子 View」的擴展需求。