【问题标题】:When drag item out of visible space in recyclerview in nestedscrollview - nestedscrollView doesn't scroll当在nestedscrollview的recyclerview中将项目拖出可见空间时-nestedscrollView不滚动
【发布时间】:2017-07-28 21:17:55
【问题描述】:

我有两个项目,它们是静态的和带有可拖动项目的 recyclerview。两种类型的视图都由 LinearLayout 包装。 LinearLayout 被 NestedScrollView 包裹起来。

XML解释:

<NestScrollView>
  <LinearLayout>
    <View></View>
    <View></View>
    <RecyclerView></RecyclerView>
  </LinearLayout>
</NestScrollView>

图片说明:

我从本教程中提取的拖动项目的实现:https://medium.com/@ipaulpro/drag-and-swipe-with-recyclerview-6a6f0c422efd#.yc7me2ikf

问题是当我将他的孩子拖出屏幕时,RecyclerView 不滚动。 (但是,如果我没有 NestedScrollView 作为父母,RecyclerView 将按预期工作。)

我搜索了与此相关的所有问题,但没有找到任何解决方案。

【问题讨论】:

  • 同意下面的答案,这不是一个好习惯。请尝试改变您的方法。
  • 你是否在你的 recyclerView 中添加了 NestedScrollingEnabled=false?
  • 我建议你摆脱嵌套的滚动视图,将文本视图放在父视图中,并将该视图作为标题添加到 recyclerView 中。以下是如何将标头添加到 recyclerview (stackoverflow.com/questions/26448717/…)
  • 您最终找到解决方案了吗?如果没有嵌套滚动视图,我的折叠工具栏将无法工作
  • 有没有人试图覆盖 interpolateOutOfBoundsScroll?

标签: android drag-and-drop android-nestedscrollview


【解决方案1】:

recyclerView 放入NestedScrollView 不是一个好习惯。我建议您将其他视图用作RecyclerView 项目。正如您所说,我确信这会解决您的问题“但是,如果我没有 NestedScrollView 作为父级,RecyclerView 会按预期工作。

【讨论】:

  • 好的,但我必须有滚动,我还必须有 recyclerview
  • @deadfish 向导是对的,你不应该把滚动视图放在滚动视图里面,就像你不把listView放在滚动视图里面一样,会导致问题
【解决方案2】:

通过将android:fillViewport="true" 添加到回收器,使 NestedScrollView 和 RecyclerView 一起玩得很好

当您开始拖动项目或到达屏幕边缘时,您还可以使用mRecyclerView.setNestedScrollingEnabled(false) 关闭回收器的嵌套行为。这将导致嵌套视图本身滚动,以便用户继续向下循环。

完成后,再次将嵌套滚动设置为 true。

或者您需要考虑委托谁获得触摸事件,就像我为另一个问题 here 概述的那样。对于您的示例,它可能很简单:

  • 当拖动开始时调用nestedScrollView.requestDisallowInterceptTouchEvent(true);
  • 当拖动结束时requestDisallowInterceptTouchEvent(false) 重新启用滚动视图

如果 requestDisallowInterceptTouchEvent 无法正常工作,那么您可以创建 NestedScrollView 的子类并覆盖 onInterceptTouchEvent 就像我的链接答案一样

【讨论】:

  • 很遗憾,fillViewportsetNestedScrollingEnabled 都没有解决问题
  • 你试过拦截触摸事件吗? (见编辑)
【解决方案3】:

我也遇到过同样的问题。我将其他视图用作回收站视图。
首先,我们必须在 getItemViewType() 中返回两个视图。

public int getItemViewType(int position)
{
if(position == 0)
{
return HEADERVIEW;
}   
return LISTVIEW;
}

现在,我们将另一个视图添加为列表中的 HeaderView,因此我们将调整列表计数:

@Override public int getItemCount() 
{ 
       return arrayList.size()+1;
}

现在在 getItemViewType() 的基础上正确绑定 onBindViewHolder 中的视图

@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) 
{
if(viewHolder.getItemViewType() == HEADERVIEW )
{
HeaderViewHolder headerViewHolder = (HeaderViewHolder)viewHolder;
headerViewHolder.headertextview.SetText("LongText");
}
else
{
MyHolder myHolder = (MyHolder) viewHolder;
myHolder.name.setText(arrayList.get(i-1).name);
}

现在在 Item Touch Listener Callback 中,我们必须调整 onMove() 方法:

public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { 
// get the viewHolder's and target's positions in your adapter data, swap them
if(viewHolder.getItemViewType() != target.getItemViewType())
{
return false; 
}
int fromPosition = viewHolder.getAdapterPosition();
int toPosition = target.getAdapterPosition();
if(dragFrom == -1) 
{ 
dragFrom =  fromPosition; 
}
dragTo = toPosition;
if(dragFrom != -1 && dragTo != -1 && dragFrom != dragTo) 
{
reallyMoved(dragFrom, dragTo);
dragFrom = dragTo = -1;
}
// and notify the adapter that its dataset has changed
adapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());                
return true;
}

现在如果所有逻辑都正确,那么我们移动项目并调用 onreallyMoved() 方法:

private void reallyMoved(int dragFrom, int dragTo) 
{
if(dragFrom == 0 || dragTo == arrayList.size())
{
 return;
}
Collections.swap(arrayList, dragFrom-1, dragTo-1);
}

如果您想了解更多信息,请查看my blog post

【讨论】:

    【解决方案4】:

    另一种解决方案是使用 linearLayout 而不是 NestedScrollView。在其根目录下,将 recyclerView 与参数 : sethasFixedSize(true) 放在您的 Java 文件中,并在 xml 中使用 match_parent 高度。

    回顾:

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <RecyclerView
            ...
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
     </LinearLayout>
    

    别忘了设置 recyclerView.setHasFixedSize(true);在你的 Java 文件中

    【讨论】:

      【解决方案5】:

      使用类似的东西:

             <FrameLayout
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              app:layout_behavior="@string/appbar_scrolling_view_behavior">
      
             <android.support.v4.widget.NestedScrollView
                  android:id="@+id/view_noRecord"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  app:layout_behavior="@string/appbar_scrolling_view_behavior">
      
                  <TextView
                      android:id="@+id/tv_no_record"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_gravity="top"
                      android:layout_marginBottom="@dimen/_20sdp"
                      android:gravity="center_horizontal"
                      android:padding="@dimen/_10sdp"
                      android:text="@string/no_data_found"
                      android:visibility="gone"
                      app:layout_behavior="@string/appbar_scrolling_view_behavior" />
              </android.support.v4.widget.NestedScrollView>
      
              <android.support.v7.widget.RecyclerView
                  android:id="@+id/common_recycler_view"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:fadeScrollbars="true"
                  android:scrollbars="vertical"
                  android:visibility="gone"
                  app:layout_behavior="@string/appbar_scrolling_view_behavior" />
      
      
      
          </FrameLayout>
      

      或者尝试将布局中的内容作为 RecyclerView 的标题

      <LinearLayout>
          <View></View>
          <View></View>
        </LinearLayout>
      

      【讨论】:

      • 我可以将标题添加到 recyclerview,但我不想将它们视为列表的子项。整个布局必须是可滚动的。
      • 通过添加标题可以让整个布局也可以滚动,我最近也是这样做的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-01
      • 2015-09-11
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多