NestedScrollView 中的多个 Recyclerview 不会发生视图回收
View Recycling not happens with Multiple Recyclerview inside NestedScrollView
我在管理 NestedScrollView
中的多个 Recyclerview
回收时遇到了问题。让我告诉你我想做什么 -
- 我有两个框架布局,即 frame1 和 frame2。
- 我有两个包含 recyclerview 的片段,第一个片段的 recyclerview 水平显示项目,而第二个片段的 recyclerview 垂直显示列表。
- 现在我将两个
FrameLayout
都放在 NestedScroolView
中,frame1 recyclerview 正在正确回收所有视图,但 frame2 recylerview 没有回收视图,不知道为什么?它首先加载所有项目然后显示在屏幕上。
一些代码:
MainActivity.java
FragmentTransaction transaction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentA frag1=new FragmentA();
FragmentB frag2=new FragmentB();
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame1, frag1);
transaction.addToBackStack(frag1.getClass().getName());
transaction.commit();
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame2, frag2);
transaction.addToBackStack(frag2.getClass().getName());
transaction.commit();
}
main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="@+id/frame1"
android:layout_width="match_parent"
android:layout_height="185dp" />
<FrameLayout
android:id="@+id/frame2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
片段A:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.recycler_view, container, false);
mDataListView = (RecyclerView) v.findViewById(R.id.data_list_view);
mDataListView .setHasFixedSize(true);
final GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), getActivity().getResources().getInteger(R.integer.playlist_categories_columns), GridLayoutManager.VERTICAL, false);
mDataListView .setNestedScrollingEnabled(false);
}
}));
return v;
}
片段B:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.recycler_view, container, false);
mDataListView = (RecyclerView) v.findViewById(R.id.data_list_view);
mDataListView .setHasFixedSize(true);
final GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1, GridLayoutManager.HORIZONTAL, false);
mDataListView .setLayoutManager(gridLayoutManager);
mDataListView .setNestedScrollingEnabled(false);
}
}));
return v;
}
recycler_view.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/data_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
我希望我的问题很清楚。
根据我的经验,我发现 NestedScrollView
中的多个 recyclerview's
无法回收视图。
但我想出了根据我的要求显示多个 Recyclerview 的解决方案,我想在顶部显示一个水平 Recyclerview,在其下方显示一个垂直 Recyclerview,所以我分享的内容可能对某人有所帮助。
我删除了 NestedScrollView
作为 Recyclerview's
的父项,并将水平 Recyclerview
作为垂直 Recyclerview
的 HeaderView
。
代码:
public class ListHeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
ArrayList<String> data;
public ListHeaderAdapter (ArrayList<String> data) {
this.data = data;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_ITEM) {
//inflate your layout and pass it to view holder
return new VHItem(null);
} else if (viewType == TYPE_HEADER) {
//inflate your layout and pass it to view holder
return new VHHeader(null);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int pos = position - 1; // for handling of Header view(use pos to fetch data from list)
if (holder instanceof VHItem) {
String dataItem = data.get(pos);
//cast holder to VHItem and set data
} else if (holder instanceof VHHeader) {
//cast holder to VHHeader and set data for header.
}
}
@Override
public int getItemCount() {
return data.size()+ 1; // for handling of Header view
}
@Override
public int getItemViewType(int position) {
if (isHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
}
public boolean isHeader(int position) {
return position == 0;
}
class VHItem extends RecyclerView.ViewHolder {
TextView title;
public VHItem(View itemView) {
super(itemView);
}
}
class VHHeader extends RecyclerView.ViewHolder {
Button button;
public VHHeader(View itemView) {
super(itemView);
}
}
}
注意:可以实现相同的逻辑以在任何位置显示水平 RecyclerView's
我在管理 NestedScrollView
中的多个 Recyclerview
回收时遇到了问题。让我告诉你我想做什么 -
- 我有两个框架布局,即 frame1 和 frame2。
- 我有两个包含 recyclerview 的片段,第一个片段的 recyclerview 水平显示项目,而第二个片段的 recyclerview 垂直显示列表。
- 现在我将两个
FrameLayout
都放在NestedScroolView
中,frame1 recyclerview 正在正确回收所有视图,但 frame2 recylerview 没有回收视图,不知道为什么?它首先加载所有项目然后显示在屏幕上。
一些代码:
MainActivity.java
FragmentTransaction transaction;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
FragmentA frag1=new FragmentA();
FragmentB frag2=new FragmentB();
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame1, frag1);
transaction.addToBackStack(frag1.getClass().getName());
transaction.commit();
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame2, frag2);
transaction.addToBackStack(frag2.getClass().getName());
transaction.commit();
}
main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="@+id/frame1"
android:layout_width="match_parent"
android:layout_height="185dp" />
<FrameLayout
android:id="@+id/frame2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
片段A:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.recycler_view, container, false);
mDataListView = (RecyclerView) v.findViewById(R.id.data_list_view);
mDataListView .setHasFixedSize(true);
final GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), getActivity().getResources().getInteger(R.integer.playlist_categories_columns), GridLayoutManager.VERTICAL, false);
mDataListView .setNestedScrollingEnabled(false);
}
}));
return v;
}
片段B:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.recycler_view, container, false);
mDataListView = (RecyclerView) v.findViewById(R.id.data_list_view);
mDataListView .setHasFixedSize(true);
final GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1, GridLayoutManager.HORIZONTAL, false);
mDataListView .setLayoutManager(gridLayoutManager);
mDataListView .setNestedScrollingEnabled(false);
}
}));
return v;
}
recycler_view.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/data_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
我希望我的问题很清楚。
根据我的经验,我发现 NestedScrollView
中的多个 recyclerview's
无法回收视图。
但我想出了根据我的要求显示多个 Recyclerview 的解决方案,我想在顶部显示一个水平 Recyclerview,在其下方显示一个垂直 Recyclerview,所以我分享的内容可能对某人有所帮助。
我删除了 NestedScrollView
作为 Recyclerview's
的父项,并将水平 Recyclerview
作为垂直 Recyclerview
的 HeaderView
。
代码:
public class ListHeaderAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
ArrayList<String> data;
public ListHeaderAdapter (ArrayList<String> data) {
this.data = data;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_ITEM) {
//inflate your layout and pass it to view holder
return new VHItem(null);
} else if (viewType == TYPE_HEADER) {
//inflate your layout and pass it to view holder
return new VHHeader(null);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int pos = position - 1; // for handling of Header view(use pos to fetch data from list)
if (holder instanceof VHItem) {
String dataItem = data.get(pos);
//cast holder to VHItem and set data
} else if (holder instanceof VHHeader) {
//cast holder to VHHeader and set data for header.
}
}
@Override
public int getItemCount() {
return data.size()+ 1; // for handling of Header view
}
@Override
public int getItemViewType(int position) {
if (isHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
}
public boolean isHeader(int position) {
return position == 0;
}
class VHItem extends RecyclerView.ViewHolder {
TextView title;
public VHItem(View itemView) {
super(itemView);
}
}
class VHHeader extends RecyclerView.ViewHolder {
Button button;
public VHHeader(View itemView) {
super(itemView);
}
}
}
注意:可以实现相同的逻辑以在任何位置显示水平 RecyclerView's