Android: 使 Recyclerview 表现得像 LinearLayout

Android: make Recyclerview behave like LinearLayout

我有这样的布局:

<LinearLayout>
   <TextView/>
   <LinearLayout> <-- needs to be a dynamic list
      <JohnDoeView/>
      <JohnDoeView/>
   </LinearLayout>
   <TextView/>
   <LinearLayout> <-- needs to be a another dynamic list
      <JohnDoeView/>
      <JohnDoeView/>
      <JohnDoeView/>
   </LinearLayout>
</LinearLayout>

这会产生下图,我可以一起滚动 WHOLE 布局。

但是当我尝试用 RecyclerView 替换那些 LinearLayout 时,我得到 两个 单独的滚动区域,就像两个固定的滚动框独立.

<LinearLayout>
   <TextView/>
   <RecyclerView/>
   <TextView/>
   <RecyclerView/>
</LinearLayout>

如何获得与 LinearLayout 相同的效果,但具有 Dynamic 内容??

我看到两个解决方案。

  1. 将整个布局插入 ScrollView
  2. 使用单个 RecyclerView.

解决方案 1

为此,您需要使 RecyclerView 包装其内容。遗憾的是,您不能只输入 android:layout_height="wrap_content",因为 RecyclerView 不支持它。幸运的是,有定制的解决方案。我一直在用,效果很好。

例如,有 this 自定义 LinearLayoutManager,您可以将其分配给两个 RecyclerView。只需按照我链接的页面中的说明进行操作即可。

解决方案 2

您可以使用一个 RecyclerView。这可能需要更努力的工作,因为您必须:

  • 将您的适配器合并为一个;
  • 将您的分隔符分配到某个位置(TextViewSwitch 或其他)。

这当然是可能的,只需看一下 RecyclerView 上有多个子类型的(许多)示例之一。

LinearLayout 可以处理动态变化。如果您使用 android:animateLayoutChanges 属性,它甚至可以为它们设置动画。 ListViewRecycler 当项目数量很大时(即远远超过屏幕可以显示的数量)很有趣,以避免有很多不可见的视图。

如果你真的想使用一个 RecyclerView 你可以只使用一个,多个 view types,例如一份用于 TextView,一份用于 JohnDoeView

尝试使用这种布局结构,

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">

<LinearLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

<LinearLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:layout_weight="1"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

您不需要嵌套 RecyclerViewListView 或任何其他滚动视图。您只需要外部视图是 RecyclerView。内部列表可以通过非常简单的 ListLayout class 进行管理,每个子列表都有一个适配器。

public class ListLayout extends LinearLayout {
    private Adapter mAdapter;
    private Observer mObserver = new Observer();

    public ListLayout(Context context) {
        super(context);
    }

    public ListLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ListLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public Adapter getAdapter()
    {
        return mAdapter;
    }

    public void setAdapter(Adapter adapter) {
        if (mAdapter != null)
            mAdapter.unregisterDataSetObserver(mObserver);

        mAdapter = adapter;
        adapter.registerDataSetObserver(mObserver);
        mObserver.onChanged();
    }

    private class Observer extends DataSetObserver {

        @Override
        public void onChanged() {
            final List<View> oldViews = new ArrayList<View>(getChildCount());

            for (int i = 0; i < getChildCount(); i++)
                oldViews.add(getChildAt(i));

            final Iterator<View> iter = oldViews.iterator();

            removeAllViews();

            for (int i = 0; i < mAdapter.getCount(); i++) {
                View convertView = iter.hasNext() ? iter.next() : null;
                View newView = mAdapter.getView(i, convertView, ListLayout.this);
                addView(newView);
            }
            super.onChanged();
        }

        @Override
        public void onInvalidated() {
            removeAllViews();
            super.onInvalidated();
        }
    }
}

https://gist.github.com/sevar83/0e27c26142f2fba97d57