【问题标题】:detect which item to delete from swipe gesture in listview检测要从列表视图中的滑动手势中删除的项目
【发布时间】:2019-10-27 07:07:19
【问题描述】:

我如何从事件中检测并查看哪个项目被刷过,这样我就可以从 arrayList 中删除特定记录并将其从那里删除,然后更新适配器?

ArrayList<User> users = ... // list of user records

adapter = new ListAdapter(getActivity(), users);

ListView listView = getView().findViewById(R.id.listView);
listView.setAdapter(adapter);

listView.setOnTouchListener((view, event) -> { // for deletion
        return false;
});

一旦删除,适配器将被刷新。

adapter.notifyDataSetChanged();

编辑

private class ListAdapter extends ArrayAdapter<User> {

    public ListAdapter(Context context, ArrayList<User> users) {
        super(context, 0, users);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup container) {
        if (convertView == null) {
            convertView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, container, false);
        }
        ((TextView) convertView.findViewById(android.R.id.text1)).setText(getItem(position).toString());
        return convertView;
    }
}

编辑 2

经过讨论,这是我的代码的样子,期待从这一点开始取得进展。

private class UserAdapter extends ArrayAdapter<User> {

    public UserAdapter(Context context, ArrayList<User> users) {
        super(context, 0, users);
    }

    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup container) {
        if (convertView == null) {
            convertView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, container, false);
        }
        ((TextView) convertView.findViewById(android.R.id.text1)).setText(getItem(position).toString());

        GestureDetector gestureDetector = new GestureDetector(this.getContext(), new GestureListener());

        convertView.setOnTouchListener(((view, event) -> {
            return gestureDetector.onTouchEvent(event);
        }));
        return convertView;
    }
}

private class GestureListener extends GestureDetector.SimpleOnGestureListener {

    private static final int SWIPE_DISTANCE_THRESHOLD = 100;
    private static final int SWIPE_VELOCITY_THRESHOLD = 100;

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        Log.d("abc", "onSingleTapUp: ");
        return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityy) {
        float distanceX = e2.getX() - e1.getX();
        float distanceY = e2.getY() - e1.getY();
        if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
            if (distanceX > 0)
                Log.d("abc", "onFling: swipe right");
            else
                Log.d("abc", "onFling: swipe left");
            return true;
        }
        return false;
    }
}

编辑 3

private class UserAdapter extends ArrayAdapter<User> {

    public UserAdapter(Context context, ArrayList<User> users) {
        super(context, 0, users);
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup container) {
        if (convertView == null) {
            convertView = getLayoutInflater().inflate(android.R.layout.simple_list_item_1, container, false);
        }
        ((TextView) convertView.findViewById(android.R.id.text1)).setText(getItem(position).toString());

        MyGestureDetector gestureDetector = new MyGestureDetector(this.getContext(), new GestureListener());
        convertView.setOnTouchListener(((view, event) -> gestureDetector.onTouchEvent(event)));

        return convertView;
    }
}

private class MyGestureDetector extends GestureDetector {

    public MyGestureDetector(Context context, OnGestureListener listener) {
        super(context, listener);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(ev);
    }
}

【问题讨论】:

  • 您最好在创建行视图时在适配器中设置监听器,而不是在整个列表视图上设置
  • 还有一些库可以帮助您实现这一点,而不是自己动手
  • 你是对的,它应该在适配器上,我在适配器上添加了代码,请你从那里帮助我。我想从简单的角度来解决这个问题,而不需要任何库来了解它是如何完成的。一旦我理解了这部分,然后我会进一步了解他们如何滑动以显示隐藏的删除按钮(我也很感激一个方向)
  • convertView.setOnTouchListener 在您退回之前。而且您已经可以通过该 getView 方法访问 int 位置来说明触摸了哪个视图...从那里,您需要一个 GestureDetector stackoverflow.com/a/12938787/2308683
  • 谢谢,实际上listView.setOnItemClickListener 让我很困惑,我们在listView 而不是convertView 上设置监听器,可以吗?

标签: android


【解决方案1】:

我不确定处理手势或制作动画的“最佳实践”,但这至少可以让您获得被滑动的视图和位置

class GestureListener extends GestureDetector.SimpleOnGestureListener {
    private final int position;
    private View v;

    public GestureListener(int position, View v) {
        this.position = position;
        this.v = v;
    }

制作监听器时,传入数据

new GestureListener(position, convertView)

然后在 onFling 中,您可以访问视图和适配器位置,以便您至少可以记录它们,但是对 Arraylist 的访问会丢失并且在侦听器中执行视图动画我确定不是最好的想法,基于我在cmets中链接的库的源代码

【讨论】:

  • 谢谢,我明白你的意思了。顺便说一句,我让我的ActivityFragment 类实现GestureDetector.OnGestureListener 不是更容易。被覆盖的方法可以访问ArrayListAdapter。我可以在convertView.setOnTouchListener 中的字段上设置this.currentPosition = position,并在onFling 中删除后从那里通知更改
  • 我认为您不应该将被触摸的位置作为字段保留在 Fragment 或活动中,但您可以在最容易访问的任何地方定义界面
  • 好的,我会接受建议,但为什么我们不应该在 Fragment 或 Activity 中保留触摸位置?
  • 因为你应该只在 onTouch 事件发生时才需要它,而不是应用程序的生命周期
  • 酷。它至少需要一个自定义布局视图,而不是带有 TextView 的简单列表项
猜你喜欢
  • 2012-12-17
  • 2018-04-17
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 2019-02-14
  • 1970-01-01
相关资源
最近更新 更多