【问题标题】:DragSortListView Cannot Drag Down on SwipeRefreshLayoutDragSortListView 无法在 SwipeRefreshLayout 上向下拖动
【发布时间】:2015-01-20 16:08:07
【问题描述】:

我在 SwipeRefreshLayout 中使用 DragSortListView (https://github.com/bauerca/drag-sort-listview) 以使其能够用于“下拉刷新”和可拖动的列表视图。这是我的 XML:

<android.support.v4.widget.SwipeRefreshLayout
    android:layout_below="@id/div_subtitle"
    android:id="@+id/srl_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <com.mobeta.android.dslv.DragSortListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        dslv:drag_enabled="true"
        dslv:track_drag_sort="false"
        android:divider="@null"
        dslv:use_default_controller="false"
        tools:listitem="@layout/list_kkategori" />
</android.support.v4.widget.SwipeRefreshLayout>

这是我的 listview 元素的 XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:paddingRight="@dimen/right_margin"
    android:paddingLeft="@dimen/left_margin"
    android:background="@color/background"
    android:layout_height="50dp">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/container_side_dropshadow">

        <ImageView
            android:id="@+id/iv_handler"
            android:layout_width="50dp"
            android:scaleType="fitXY"
            android:layout_height="20dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:src="@drawable/draghandler" />

        <TextView
            android:id="@+id/tv_nama"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/textBlack"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_toRightOf="@id/iv_handler"
            android:text="Nama Kategori"
            android:textSize="17sp" />

        <View
            android:layout_width="match_parent"
            android:layout_height="0.5dp"
            android:layout_alignParentBottom="true"
            android:background="@color/dividerColor"
            android:layout_marginLeft="@dimen/left_divider_margin"
            android:layout_marginRight="@dimen/right_divider_margin" />

    </RelativeLayout>

</RelativeLayout>

这是我在片段的onCreateView 上调用的 DragSortListView 初始化:

dslv = (DragSortListView) v.findViewById(android.R.id.list);
dslv.addHeaderView(View.inflate(getActivity(), R.layout.list_header, null), null, false);
dslv.addFooterView(View.inflate(getActivity(), R.layout.list_footer, null), null, false);

dslvController = new DragSortController(dslv);
dslvController.setDragHandleId(R.id.iv_handler);
dslvController.setRemoveEnabled(false);
dslvController.setSortEnabled(true);
dslvController.setDragInitMode(DragSortController.ON_DOWN);
dslvController.setRemoveMode(DragSortController.FLING_REMOVE);
dslv.setFloatViewManager(dslvController);
dslv.setOnTouchListener(dslvController);
dslv.setDragEnabled(true);

但是,DragSortListView 不知何故无法向下拖动任何列表项,但向上拖动功能仍然有效。我怀疑当我向下拖动列表元素时 DragSortListView 中的 onTouchListener 被 SwipeRefreshLayout 的 onTouchListener 覆盖。

这个问题有什么解决方案或变通方法吗?我的应用程序中需要这两个功能,即滑动刷新和拖动列表视图。

【问题讨论】:

    标签: android listview drag-and-drop pull-to-refresh swiperefreshlayout


    【解决方案1】:

    使用dslvController.setDragInitMode(DragSortController.ON_LONG_PRESS); 而不是dslvController.setDragInitMode(DragSortController.ON_DOWN);


    我的错,仍然有下拉问题。一种肮脏的解决方法是在向下拖动之前稍微向上移动项目。我知道这有点糟糕,我正在阅读 SwipeRefreshLayout 上的文档,如果我发现任何东西会更新。对不起,错误的解决方案。

    【讨论】:

      【解决方案2】:

      我也遇到过同样的问题,但在我的应用中,列表有两种状态:第一种 - 用户可以拖放内容,第二种 - 用户可以滑动以刷新整个列表。

      所以,我找到了如何在我的列表处于拖放状态时防止滑动刷新操作的方法。重点是重写 SwipeRefreshLayout 的 canChildScrollUp() 函数,默认情况下会阻止任何 AbsListView 的滑动行为,除非该操作在列表的第一行位于顶部时完成。我正在检查子视图是否是 DragSortListView 的实例,如果 list.isDragEnabled() 则返回 true。您也可以在这里实现任何其他逻辑。

      这是我的 CustomSwipeRefreshLayout:

      public class CustomSwipeRefreshLayout extends SwipeRefreshLayout {
      
      private View mTarget;
      
      public CustomSwipeRefreshLayout(Context context) {
          super(context);
      }
      
      public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
          super(context, attrs);
      }
      
      @Override
      public boolean canChildScrollUp() {
          ensureTarget();
          if (mTarget != null && mTarget instanceof DragSortListView)
              return super.canChildScrollUp()||((DragSortListView)mTarget).isDragEnabled();
          return super.canChildScrollUp();
      }
      
      /** 
      * Had to copy the method from SwipeRefreshLayout
      **/
      private void ensureTarget() {
          // Don't bother getting the parent height if the parent hasn't been laid
          // out yet.
          if (mTarget == null) {
              for (int i = 0; i < getChildCount(); i++) {
                  View child = getChildAt(i);
                  if (! (child instanceof ImageView)) {
                  // In fact, refresh icon is instanseof CircleImageView, but the
                  // class is private, so I decided to compare with ImageView. 
                      mTarget = child;
                      break;
                  }
              }
          }
      }
      

      }

      希望对某人有所帮助。

      【讨论】:

      • 为此,您可以修改 DragSortListView 类并为 mDragState 创建一个 getter。然后在canChildScrollUp() 方法中,您可以检查以下内容:((DragSortListView)mTarget).getDragState() != DragSortListView.IDLE在您不拖动时始终显示滑动刷新操作。这样您就不必依赖isDragEnabled() 方法了。
      猜你喜欢
      • 2014-11-23
      • 1970-01-01
      • 1970-01-01
      • 2022-08-10
      • 2017-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      相关资源
      最近更新 更多