【问题标题】:SwipeListView only one item opened at a timeSwipeListView 一次只打开一项
【发布时间】:2014-03-24 08:27:55
【问题描述】:

这个问题指的是在此处找到的 SwipeListView 组件:https://github.com/47deg/android-swipelistview

在尝试了我在网上找到的几个实现和修复后,我决定稍微修改一下源代码。

我将在此处发布此内容,因为我知道这是一个已知问题,并且我发现的所有版本最终都证明存在一些问题。

SwipeListViewTouchListener.java 发生了以下变化:

...
/**
     * Create reveal animation
     *
     * @param view      affected view
     * @param swap      If will change state. If "false" returns to the original
     *                  position
     * @param swapRight If swap is true, this parameter tells if movement is toward
     *                  right or left
     * @param position  list position
     */
    private void generateRevealAnimate(final View view, final boolean swap, final boolean swapRight, final int position) {
        int moveTo = 0;
        if (opened.get(position)) {
            if (!swap) {
                moveTo = openedRight.get(position) ? (int) (viewWidth - rightOffset) : (int) (-viewWidth + leftOffset);
            }
        } else {
            if (swap) {
                moveTo = swapRight ? (int) (viewWidth - rightOffset) : (int) (-viewWidth + leftOffset);
            }
        }
        final boolean aux = !opened.get(position);
        if(swap) {
            opened.set(position, aux);
            openedRight.set(position, swapRight);
        }

        animate(view).translationX(moveTo).setDuration(animationTime).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                swipeListView.resetScrolling();

                if (swap) {
                    if (aux) {
                        swipeListView.onOpened(position, swapRight);
                    } else {
                        swipeListView.onClosed(position, openedRight.get(position));
                    }
                }
                // if (aux || !swap) {
                // resetCell();
                // }
            }
        });
    }
...

/**
     * Close all opened items
     */

    void closeOtherOpenedItems() {
        if (opened != null && downPosition != SwipeListView.INVALID_POSITION) {
            int start = swipeListView.getFirstVisiblePosition();
            int end = swipeListView.getLastVisiblePosition();
            for (int i = start; i <= end; i++) {
                if (opened.get(i) && i != downPosition) {
                    closeAnimate(swipeListView.getChildAt(i - start).findViewById(swipeFrontView), i);
                }
            }
        }

    }
...

/**
     * @see View.OnTouchListener#onTouch(android.view.View,
     * android.view.MotionEvent)
     */
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
...
closeOtherOpenedItems();
view.onTouchEvent(motionEvent);
return true;
}

其余未提及的代码都是一样的。

高度赞赏任何 cmets,此更改使您不必在扩展列表的活动中实现 SwipeListViewOnTouchListener

【问题讨论】:

  • 太棒了,谢谢!它还解决了其他问题,例如:github.com/47deg/android-swipelistview/issues/131
  • 运行良好,没有任何问题。
  • tnx 解决了我的问题...
  • 我应该对“OnTouch”进行哪些更改?我应该在哪里添加代码?
  • 嗨,Adrian,我非常希望这段代码能成为 47deg 项目的一部分。如果您没有时间,玩具介意我提交一份带有此内容的 PR(我会根据您的需要向您提供)

标签: android swipe ontouchlistener swipe-gesture


【解决方案1】:

缺点:不会关闭openAnimate()打开的行

   BaseSwipeListViewListener swipeListViewListener = new BaseSwipeListViewListener() {
    int openItem = -1;

    @Override
    public void onStartOpen(int position, int action, boolean right) {
        super.onStartOpen(position, action, right);

        if (openItem > -1)
            swipeListView.closeAnimate(openItem);

        openItem = position;
    }
   }

或者更好的方法:

 @Override
    public void onStartOpen(int position, int action, boolean right) {
        super.onStartOpen(position, action, right);
        swipeListView.closeOpenedItems();
    }

并将监听器设置为listView:

   swipeListView.setSwipeListViewListener(swipeListViewListener);

【讨论】:

    【解决方案2】:

    您的修复工作有效,但有一种方法可以在不影响原始代码的情况下做到这一点:

    swipeListView.setSwipeListViewListener(new BaseSwipeListViewListener() {
        int openItem = -1;
        int lastOpenedItem = -1;
        int lastClosedItem = -1;
    
        @Override
        public void onOpened(int position, boolean toRight) {
            lastOpenedItem = position;
            if (openItem > -1 && lastOpenedItem != lastClosedItem) {
                swipeListView.closeAnimate(openItem);
            }
            openItem = position;
        }
    
        @Override
        public void onStartClose(int position, boolean right) {
            Log.d("swipe", String.format("onStartClose %d", position));
            lastClosedItem = position;
        }
    }
    

    但是,您应该发送拉取请求以应用您的代码,因为这样可以修复错误。

    来源:https://github.com/47deg/android-swipelistview/issues/46

    【讨论】:

    • 感谢您的建议,因为这不是最近的帖子,我现在不记得了,但很有可能我也尝试过您的修复,起初工作但一路失败,所以到目前为止,我发布的内容似乎没有显示错误。
    • @spacebiker:嗨,是否可以关闭已在列表中打开的特定项目。我使用了 closeAnimate(postion) 但它不起作用。
    【解决方案3】:

    如果您要修改 swipelistview 库本身,我有一个更简单的解决方案。

    onTouch 方法中的SwipeListViewTouchListener.java 中,在case MotionEvent.ACTION_DOWN: 的开头添加以下if 块

    if(lastOpenedPosition != downPosition && opened.get(lastOpenedPosition)) {
        closeAnimate(lastOpenedPosition);
        return false;
    }
    

    创建一个int lastOpenedPosition字段并将其初始化为0,并在if (aux)块内的generateRevealAnimate方法中添加:

    lastOpenedPosition = position;
    

    我还将配置变量(在 res/values/swipelistview_attrs.xml 中)添加到 SwipeListView 并将其添加到 onTouch if 块,以添加关闭和打开此功能的功能。 这基本上导致如果在打开一行时触摸列表,则该行将关闭。恕我直言,这比仅在您完成打开另一行后才关闭的行具有更好的功能。

    【讨论】:

    • 您好,谢谢您的回复,实际上我之前确实遇到过您的解决方案,它有效,但并非一直有效。我需要能够以更高准确度工作的东西。我在这里给出的是最适合我的。
    • 有意思,你还记得这在什么情况下不起作用吗?
    • 这不是最近的东西,因为你可以看到帖子很旧。我遇到的问题是列表动画的随机崩溃和错误。
    【解决方案4】:
    swipeListView.setSwipeListViewListener(new BaseSwipeListViewListener() {
    //...
      @Override
      public void onClickBackView(int position) {
        //DELETE ITEM
        adapter.notifyDataSetChanged();
        swipeListView.closeOpenedItems();
      }
    //...
    });
    

    【讨论】:

      【解决方案5】:

      是的,原代码的 SwipeListView 可以同时打开很多项。您这里的代码段可以一次打开一项吗?或者当打开另一个项目时,打开的项目将被关闭?

      【讨论】:

      • 打开一个项目并尝试打开另一个项目后,前一个项目将在您打开另一个项目时关闭。
      猜你喜欢
      • 2022-01-14
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-21
      相关资源
      最近更新 更多