【问题标题】:Remove item listview with Slide - Like Gmail使用幻灯片删除项目列表视图 - 像 Gmail
【发布时间】:2013-01-18 12:14:09
【问题描述】:

我正在开发一个在列表视图中包含商店列表的应用程序。我需要当我向右(或向左)滑动listview 的项目时,该项目应该从列表视图中删除。

我有我的列表视图,只需要执行它的函数。

提前致谢。

【问题讨论】:

  • 就像平板电脑一样,您可以通过向左或向右滑动来从当前任务列表中删除任务。?
  • 这里有一个链接可以显示/指导你如何做到这一点:Swipe to dismiss.

标签: android android-listview


【解决方案1】:

这就是我实现这种效果的方式。我们有一个 ListView lvSimple,我们将 onTouchListener 添加到我们的lvSimple。这是我的工作代码。

float historicX = Float.NaN, historicY = Float.NaN;
static final int DELTA = 50;
enum Direction {LEFT, RIGHT;}
...
ListView lvSimple = (ListView) findViewById(R.id.linLayout);
...
lvSimple.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                historicX = event.getX();
                historicY = event.getY();
                break;

            case MotionEvent.ACTION_UP:
                if (event.getX() - historicX < -DELTA) {
                    FunctionDeleteRowWhenSlidingLeft();
                    return true;
                }
                else if (event.getX() - historicX > DELTA) {
                    FunctionDeleteRowWhenSlidingRight();
                    return true;
                }
                break;

            default:
                return false;
        }
        return false;
    }
});

当我们向左滑动时,函数FunctionDeleteRowWhenSlidingLeft()被调用,FunctionDeleteRowWhenSlidingRight()-分别向右滑动。在此功能中,您需要粘贴动画代码。

【讨论】:

  • 呵呵,找了两天调试,省了!谢谢
  • 但是如何获取幻灯片行的索引?!
  • list.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id){ // 在这里做东西 SwipedPosition = position; } });
  • Swipe 位置保持 0 并删除列表中的第一项。如何获取列表视图滑动项的位置?
  • @macloving,您能否也用动画代码扩展您的答案?
【解决方案2】:

Android-Developer 的Answer 指向gist.github.com 中 Roman Nurik 的代码。此代码已过时。他在他的开源项目Dash Clock 中使用此滑动来关闭听众。

在使用 Gist.github.com 中的代码之前,您应该了解一些事情。

  1. gist.Github 中的过时代码对触摸非常敏感。如果您继续点击 ListView 中的项目,它将被删除。在更新的代码中,他修复了投掷敏感性。
  2. 如果您在 列表显示。如果您需要分隔符,请在 ListItem 布局中声明它们。
  3. 此代码仍处于测试版。买者自负。

所以我建议使用更新后的代码。你可以找到更新的源here

【讨论】:

  • 我正在使用您推荐的链接中的更新代码,但我在声明它时遇到了问题。每当我调用该行时:“new SwipeDismissListViewTouchListener.OnDismissCallback() {”它会出现“SwipeDismissListViewTouchListener.OnDismissCallback 无法解析为类型”有什么想法吗?不太确定解决方案
  • @Silmarilos 请改用new SwipeDismissListViewTouchListener.DismissCallbacks()
【解决方案3】:

您应该考虑的另一个选择是使用 Tim Roes 的 EnhancedListView 库。 [更新 - 2015 年 8 月 1 日] 随着 RecycleView 这个库的引入已被弃用。

上述 Roman Nurik 的 SwipeToDismiss 侦听器需要 API 级别 12 或更高。 Jake Wharton 移植了此代码以支持 SwipeToDismissNOA 中的所有 API 级别。

Tim Roes 进一步扩展了这个库以支持 Undo 功能。

【讨论】:

  • 信息:EnhancedListView 已弃用。
  • @iraSenthil 那你现在用的是什么,还是滑动删除? SwipetoDismissNOA 还是别的什么?
【解决方案4】:

我用 macloving 写的东西做了一个回答。目前它正在起作用,但只有在所有孩子的身高都相同的情况下才有效。

listView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // TODO Auto-generated method stub
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    historicX = event.getX();
                    historicY = event.getY();
                    return false;

                case MotionEvent.ACTION_UP:
                    if (listView.getChildAt(0) != null) {
                        int heightOfEachItem = haveListView.getChildAt(0).getHeight();
                        int heightOfFirstItem = -haveListView.getChildAt(0).getTop() + haveListView.getFirstVisiblePosition()*heightOfEachItem;
                        //IF YOU HAVE CHILDS IN LIST VIEW YOU START COUNTING
                        //listView.getChildAt(0).getTop() will see top of child showed in screen
                        //Dividing by height of view, you get how many views are not in the screen
                        //It needs to be Math.ceil in this case because it sometimes only shows part of last view
                        final int firstPosition = (int) Math.ceil(heightOfFirstItem / heightOfEachItem); // This is the same as child #0

                        //Here you get your List position, use historic Y to get where the user went first
                        final int wantedPosition = (int) Math.floor((historicY - haveListView.getChildAt(0).getTop()) / heightOfEachItem) + firstPosition;
                        //Here you get the actually position in the screen
                        final int wantedChild = wantedPosition - firstPosition;
                        //Depending on delta, go right or left
                        if (event.getX() - historicX < -DELTA) {
                            //If something went wrong, we stop it now
                            if (wantedChild < 0 || wantedChild >= List.size()|| wantedChild >= listView.getChildCount()) {

                                return true;
                            }
                            //Start animation with 500 miliseconds of time
                            listView.getChildAt(wantedChild).startAnimation(outToLeftAnimation(500));
                            //after 500 miliseconds remove from List the item and update the adapter.
                            new java.util.Timer().schedule(
                                    new java.util.TimerTask() {
                                        @Override
                                        public void run() {
                                            List.remove(wantedPosition);
                                            updateAdapter();
                                        }
                                    },
                                    500
                            );
                            return true;

                        } else if (event.getX() - historicX > DELTA) {
                            //If something went wrong, we stop it now
                            if (wantedChild < 0 || wantedChild >= List.size() || wantedChild >= listView.getChildCount()) {

                                return true;
                            }
                            //Start animation with 500 miliseconds of time
                            listView.getChildAt(wantedChild).startAnimation(outToRightAnimation(500));
                            //after 500 miliseconds remove from List the item and update the adapter.
                            new java.util.Timer().schedule(
                                    new java.util.TimerTask() {
                                        @Override
                                        public void run() {
                                            List.remove(wantedPosition);
                                            updateAdapter();
                                        }
                                    },
                                    500
                            );
                            return true;

                        }
                    }
                    return true;
                default:
                    return false;
            }
        }
    });

动画有这个功能:

private Animation outToLeftAnimation(int duration) {
    Animation outtoLeft = new TranslateAnimation(
            Animation.RELATIVE_TO_PARENT, 0.0f,
            Animation.RELATIVE_TO_PARENT, -1.0f,
            Animation.RELATIVE_TO_PARENT, 0.0f,
            Animation.RELATIVE_TO_PARENT, 0.0f);
    outtoLeft.setDuration(duration);
    outtoLeft.setInterpolator(new AccelerateInterpolator());
    return outtoLeft;
}

private Animation outToRightAnimation(int duration) {
    Animation outtoRight = new TranslateAnimation(
            Animation.RELATIVE_TO_PARENT, 0.0f,
            Animation.RELATIVE_TO_PARENT, +1.0f,
            Animation.RELATIVE_TO_PARENT, 0.0f,
            Animation.RELATIVE_TO_PARENT, 0.0f);
    outtoRight.setDuration(duration);
    outtoRight.setInterpolator(new AccelerateInterpolator());
    return outtoRight;
}

我正在尝试这个,直到现在我还没有看到错误,如果有人也可以尝试会很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    相关资源
    最近更新 更多