0

我在 a 中有两个RecylerViews在 a 中LinearLayout具有垂直方向ScrollView。两者RecyclerViews都想在TextViews. 这种安排是这样的,在开始时,TextViews只有第一个RecyclerView出现,而在滚动时,第二个RecyclerView出现。

我的期望是,由于TextViews第二个中的任何一个都不RecyclerView可见,它们将不会被创建,并且一旦它们出现,onBindViewHolder将被调用以重用现有的ViewHolders. 然而,所有的个体ViewHolders都是被创造(onCreateView被称为)的。难道我做错了什么?因为如果这是预期的,那么设置一个通用的 ViewPool 是没有意义的,是吗?

活动代码

public class MainActivity extends AppCompatActivity {
    private List<String> names = Arrays.asList(
        "Name 1", "Name 2", "Name 3", "Name 4", "Name 5", "Name 6"
    );

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();

        RecyclerView recycler1 = (RecyclerView) findViewById(R.id.recycler1);
        RecyclerView recycler2 = (RecyclerView) findViewById(R.id.recycler2);

        recycler1.setLayoutManager(new LinearLayoutManager(this));
        recycler2.setLayoutManager(new LinearLayoutManager(this));

        recycler1.setRecycledViewPool(viewPool);
        recycler2.setRecycledViewPool(viewPool);

        recycler1.setNestedScrollingEnabled(false);
        recycler2.setNestedScrollingEnabled(false);

        recycler1.setAdapter(new SampleAdapter(new ArrayList<>(names), 1));
        recycler2.setAdapter(new SampleAdapter(new ArrayList<>(names), 2));
    }

    private class SampleAdapter extends RecyclerView.Adapter {
        private final List<String> mSampleList;
        private final int mRecyclerId;

        SampleAdapter(List<String> sampleList, int recyclerId) {
            mSampleList = sampleList;
            mRecyclerId = recyclerId;
        }

        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            Log.i("TESTING", "creating a new view for parent Id: " + mRecyclerId);
            TextView textView = (TextView) getLayoutInflater().inflate(R.layout.text_view_name, null);
            return new SampleViewHolder(textView);
        }

        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            Log.i("TESTING", "binding existing view for parent Id: " + mRecyclerId + " for position: " +
                position);
            ((SampleViewHolder)holder).bind(mSampleList.get(position));
        }

        public int getItemCount() {
            return mSampleList.size();
        }
    }

    private class SampleViewHolder extends RecyclerView.ViewHolder {
        private TextView mText;
        public SampleViewHolder(TextView itemView) {
            super(itemView);
            mText = itemView;
        }

        public void bind(String s) {
            mText.setText(s);
        }
    }
}

布局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scroll_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <LinearLayout
        android:id="@+id/recycler_containers"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorAccent"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recycler2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/colorPrimary"/>

    </LinearLayout>
</ScrollView>

文本视图

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/name_text_view"
    android:layout_width="match_parent"
    android:layout_height="400dp"
    android:paddingTop="40dp"
    android:paddingRight="40dp"
    android:paddingBottom="40dp"
    android:paddingLeft="40dp"
    android:textColor="@color/white"
    android:gravity="center">

</TextView>
4

1 回答 1

0

首先,RecyclerView在 a 内部使用ScrollView从来都不是一个好主意。一个 ScrollView 将布局它的孩子,在你的例子中是一个 LinearLayout,它也将布局它的孩子:2 个 RecyclerViews。

我将从下往上开始:两个 RecyclerView 都与它们的父级一样高,或者更少,因为它们被告知要 wrap_content。它们都得到了布局,并且在 LinearLayout 中,它具有两个 RecyclerView 的高度。如果 LinearLayout 大于屏幕,则 ScrollView 将使所有内容都可滚动。您现在拥有一个显示全部内容且可滚动的高大布局。

注意事项:滚动视图不会回收任何视图。如果视图不在屏幕上,它可能不会被绘制,但视图本身不会根据此信息“采取行动”,因为所有视图都知道它当前显示给用户。基本上,两个 RecyclerView 都在 LinearLayout 中正确布局到它们的全高,这将拉伸到所需的高度。RecyclerViews 知道它们是可见的——并且需要绑定它们的所有子视图。这是你的问题”。

设置一个通用的 ViewPool 没有意义,是吗?

由于两个 RecyclerView 都是“可见的”,因此没有回收和重用。由于位于 ScrollView 内而不滚动的 RecyclerView 将不会回收其视图。您是对的,没有进行回收,共享的 ViewPool 也没用。


使用您描述的布局,您应该完全摆脱 ScrollView 并使用单个 RecyclerView 正确滚动和回收视图。无论您需要 ScrollView 做什么,都可以使用 RecyclerView 来完成。ScrollView 用于静态布局,RecyclerView 用于列表。

如果您有多个 Fragment 或 ViewPagers 之类的东西,那么共享 ViewPools 旨在用于不同屏幕上的许多相同视图。

于 2017-02-26T17:21:26.193 回答