在Android中中断最后一次触摸事件

在Android中中断最后一次触摸事件,android,android-listview,android-contextmenu,Android,Android Listview,Android Contextmenu,当用户长时间单击列表项时,我的应用程序将ListPopupWindow显示为上下文菜单。显示关联菜单后,背景仍然可用,直到用户抬起手指为止。你可以在附加的GIF中看到行为。 我想知道如何打断这段对话 TrackListAdapter.java: private final float[] longClickLastTouchDownXY = new float[2]; @Override @CallSuper public void onBindViewHolder(VH holder, in

当用户长时间单击列表项时,我的应用程序将ListPopupWindow显示为上下文菜单。显示关联菜单后,背景仍然可用,直到用户抬起手指为止。你可以在附加的GIF中看到行为。 我想知道如何打断这段对话

TrackListAdapter.java:

private final float[] longClickLastTouchDownXY = new float[2];

@Override
@CallSuper
public void onBindViewHolder(VH holder, int position) {
    holder.itemView.setOnTouchListener((v, event) -> {
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            longClickLastTouchDownXY[0] = event.getX();
            longClickLastTouchDownXY[1] = event.getY();
        }
        return false;
    });
    holder.itemView.setOnLongClickListener(v -> {
        if (onItemLongClickListener != null) {
            onItemLongClickListener.onItemLongClick((ViewGroup) v,
                    (int) longClickLastTouchDownXY[0], (int) longClickLastTouchDownXY[1],
                    holder.getAdapterPosition());
            return true;
        }
        return false;
    });
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View layout = inflater.inflate(R.layout.list_track, container, false);
    ButterKnife.bind(this, layout);


    tracksList.setAdapter(tracksAdapter);
    tracksAdapter.setOnItemLongClickListener(this::showTrackContextMenu);

    return layout;
}

private void showTrackContextMenu(ViewGroup rootView, float x, float y, int itemPosition) {
    Track selectedTrack = tracksAdapter.get(itemPosition);
    ListPopupWindow popupWindow = new ListPopupWindow(requireContext());
    ListPopupWindowAdapter adapter = new ListPopupWindowAdapter(requireContext(), R.menu.track_menu);
    popupWindow.setAdapter(adapter);

    View tempView = new View(requireContext());
    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(0, 0);
    tempView.setLayoutParams(lp);
    tempView.setX(x - rootView.getPaddingLeft());
    tempView.setY(y - rootView.getPaddingTop());
    rootView.addView(tempView);

    popupWindow.setAnchorView(tempView);
    popupWindow.setModal(true);
    popupWindow.setOnDismissListener(() -> rootView.removeView(tempView));
    popupWindow.show();
}
TrackListFragment.java:

private final float[] longClickLastTouchDownXY = new float[2];

@Override
@CallSuper
public void onBindViewHolder(VH holder, int position) {
    holder.itemView.setOnTouchListener((v, event) -> {
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            longClickLastTouchDownXY[0] = event.getX();
            longClickLastTouchDownXY[1] = event.getY();
        }
        return false;
    });
    holder.itemView.setOnLongClickListener(v -> {
        if (onItemLongClickListener != null) {
            onItemLongClickListener.onItemLongClick((ViewGroup) v,
                    (int) longClickLastTouchDownXY[0], (int) longClickLastTouchDownXY[1],
                    holder.getAdapterPosition());
            return true;
        }
        return false;
    });
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View layout = inflater.inflate(R.layout.list_track, container, false);
    ButterKnife.bind(this, layout);


    tracksList.setAdapter(tracksAdapter);
    tracksAdapter.setOnItemLongClickListener(this::showTrackContextMenu);

    return layout;
}

private void showTrackContextMenu(ViewGroup rootView, float x, float y, int itemPosition) {
    Track selectedTrack = tracksAdapter.get(itemPosition);
    ListPopupWindow popupWindow = new ListPopupWindow(requireContext());
    ListPopupWindowAdapter adapter = new ListPopupWindowAdapter(requireContext(), R.menu.track_menu);
    popupWindow.setAdapter(adapter);

    View tempView = new View(requireContext());
    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(0, 0);
    tempView.setLayoutParams(lp);
    tempView.setX(x - rootView.getPaddingLeft());
    tempView.setY(y - rootView.getPaddingTop());
    rootView.addView(tempView);

    popupWindow.setAnchorView(tempView);
    popupWindow.setModal(true);
    popupWindow.setOnDismissListener(() -> rootView.removeView(tempView));
    popupWindow.show();
}
这在理论上应该是可行的,我没有测试: 用于冻结RecyclerView的垂直滚动:

private final float[] longClickLastTouchDownXY = new float[2];

@Override
@CallSuper
public void onBindViewHolder(VH holder, int position) {
    holder.itemView.setOnTouchListener((v, event) -> {
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            longClickLastTouchDownXY[0] = event.getX();
            longClickLastTouchDownXY[1] = event.getY();
        }
        return false;
    });
    holder.itemView.setOnLongClickListener(v -> {
        if (onItemLongClickListener != null) {
            onItemLongClickListener.onItemLongClick((ViewGroup) v,
                    (int) longClickLastTouchDownXY[0], (int) longClickLastTouchDownXY[1],
                    holder.getAdapterPosition());
            return true;
        }
        return false;
    });
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View layout = inflater.inflate(R.layout.list_track, container, false);
    ButterKnife.bind(this, layout);


    tracksList.setAdapter(tracksAdapter);
    tracksAdapter.setOnItemLongClickListener(this::showTrackContextMenu);

    return layout;
}

private void showTrackContextMenu(ViewGroup rootView, float x, float y, int itemPosition) {
    Track selectedTrack = tracksAdapter.get(itemPosition);
    ListPopupWindow popupWindow = new ListPopupWindow(requireContext());
    ListPopupWindowAdapter adapter = new ListPopupWindowAdapter(requireContext(), R.menu.track_menu);
    popupWindow.setAdapter(adapter);

    View tempView = new View(requireContext());
    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(0, 0);
    tempView.setLayoutParams(lp);
    tempView.setX(x - rootView.getPaddingLeft());
    tempView.setY(y - rootView.getPaddingTop());
    rootView.addView(tempView);

    popupWindow.setAnchorView(tempView);
    popupWindow.setModal(true);
    popupWindow.setOnDismissListener(() -> rootView.removeView(tempView));
    popupWindow.show();
}
RecyclerView有一个名为
SetLayoutFrozed(布尔冻结)的方法
,此方法似乎会在RecyclerView处于活动状态时阻止其TouchEvent(当您将
冻结
设置为true时)

现在我假设,当您长按列表中的某个项目时(似乎您为此创建了一个界面),会调用您的方法
showTrackContextMenu(…)
。无论如何,请尝试在该方法结束时冻结RecyclerView。像这样:

private void showTrackContextMenu(ViewGroup rootView, float x, float y, int itemPosition) {

.......
.......
.......

popupWindow.show();

//here
yourRecyclerView.setLayoutFrozen(true);

}
如果要删除冻结以便再次滚动,只需调用以下命令:

yourRecyclerView.setLayoutFrozen(false);
用于冻结ViewPager:

private final float[] longClickLastTouchDownXY = new float[2];

@Override
@CallSuper
public void onBindViewHolder(VH holder, int position) {
    holder.itemView.setOnTouchListener((v, event) -> {
        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            longClickLastTouchDownXY[0] = event.getX();
            longClickLastTouchDownXY[1] = event.getY();
        }
        return false;
    });
    holder.itemView.setOnLongClickListener(v -> {
        if (onItemLongClickListener != null) {
            onItemLongClickListener.onItemLongClick((ViewGroup) v,
                    (int) longClickLastTouchDownXY[0], (int) longClickLastTouchDownXY[1],
                    holder.getAdapterPosition());
            return true;
        }
        return false;
    });
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View layout = inflater.inflate(R.layout.list_track, container, false);
    ButterKnife.bind(this, layout);


    tracksList.setAdapter(tracksAdapter);
    tracksAdapter.setOnItemLongClickListener(this::showTrackContextMenu);

    return layout;
}

private void showTrackContextMenu(ViewGroup rootView, float x, float y, int itemPosition) {
    Track selectedTrack = tracksAdapter.get(itemPosition);
    ListPopupWindow popupWindow = new ListPopupWindow(requireContext());
    ListPopupWindowAdapter adapter = new ListPopupWindowAdapter(requireContext(), R.menu.track_menu);
    popupWindow.setAdapter(adapter);

    View tempView = new View(requireContext());
    ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(0, 0);
    tempView.setLayoutParams(lp);
    tempView.setX(x - rootView.getPaddingLeft());
    tempView.setY(y - rootView.getPaddingTop());
    rootView.addView(tempView);

    popupWindow.setAnchorView(tempView);
    popupWindow.setModal(true);
    popupWindow.setOnDismissListener(() -> rootView.removeView(tempView));
    popupWindow.show();
}
好的,我找不到一种专门用来冻结ViewPager的方法,你唯一能做的就是制作一个自定义的ViewPager并使用它,让它做你想做的事情:

class MyViewPager extends ViewPager{

private boolean frozen = false;

public MyViewPager(Context context){
super(context);
}

public MyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}

public void freezeViewPager(boolean frozen){
this.frozen = frozen;
}

@Override
 public boolean onTouchEvent(MotionEvent event) {
if(frozen){
 return false;
}else{
 return super.onTouchEvent(event);
}

}

}
然后使用上述xml格式的ViewPager,而不是使用的默认ViewPager

要冻结它:

.......

popupWindow.show();

//here freeze recyclerView
yourRecyclerView.setLayoutFrozen(true);
//here freeze view pager
myViewPager.freezeViewPager(true);
要停止冻结:

myViewPager.freezeViewPager(false);

您为recyclerview设置了什么LayoutManager?@HasanBouTaam LinearLayoutManager通过xmlYes,您的答案对于垂直拖动是正确的。我的错误是,我忘了指出使用水平滚动的ViewPager也需要这样做。ViewPager包含在父片段中当然我可以创建可锁定的ViewPager并添加方法来冻结它,就像在recyclerview中一样,但在ViewPager不使用的其他地方,我也需要这种行为。这就是为什么我要问关于中断触摸的问题。你在其他地方需要什么行为?显示上下文菜单而不拖动。对不起,我的英语不好)检查我的更新,你必须像我向你展示的那样构建自己的自定义viewpager。