我有多个布局会在我的RecyclerView
ViewHolder中膨胀,视图是否膨胀取决于传递给ViewHolder的数据集,我知道如何使用getItemViewType()
,但就我而言它不适用,例如,数据集包含1,2,3,它将所有视图充气到ViewHolder容器(LinearLayout)。
带有LinearLayout容器的我的ViewHolder:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardBackgroundColor="@android:color/white"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include layout="@layout/layout_header" />
<LinearLayout
android:id="@+id/lnr_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<include layout="@layout/layout_footer" />
</LinearLayout>
</android.support.v7.widget.CardView>
ViewHolder1:
在这里,我使用变量创建了视图的引用,如果视图被回收,我将仅检查变量是否不为null,例如,recyclerView我将仅重置数据。
private class ViewHolder1 extends RecyclerView.ViewHolder{
@BindView(R.id.lnr_container)
LinearLayout mLnrContainer;
private RecyclerView mRecyclerView;
private ImageView mImageView;
private LinearLayout mLayout;
public ViewHolder1(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
public void setData(JSONObject data){
mLnrContainer.removeAllViews();
if (data.has("1")){
if (mRecyclerView == null){
mRecyclerView = new RecyclerView(itemView.getContext());
// other implementation
mRecyclerView.setAdapter(new SomeAdapter(itemView.getContext(),data));
}else {
mRecyclerView.getAdapter().setData(data);
}
addView(mRecyclerView);
}
if (data.has("2")){
mImageView = new ImageView(itemView.getContext());
addView(mImageView);
}
if (data.has("3")){
mLayout = LayoutInflater.from(itemView.getContext()).inflate(R.layout.custom_layout,mLnrContainer,false);
addView(mLayout);
}
}
private void addView(View view){
mLnrContainer.addView(view);
}
}
ViewHolder2:
private class ViewHolder2 extends RecyclerView.ViewHolder{
@BindView(R.id.lnr_container)
LinearLayout mLnrContainer;
public ViewHolder2(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
public void setData(JSONObject data){
mLnrContainer.removeAllViews();
if (data.has("1")){
RecyclerView mRecyclerView = new RecyclerView(itemView.getContext(),data);
addView(mRecyclerView);
}
if (data.has("2")){
ImageView mImageView = new ImageView(itemView.getContext());
addView(mImageView);
}
if (data.has("3")){
LinearLayout mLayout = LayoutInflater.from(itemView.getContext()).inflate(R.layout.custom_layout,mLnrContainer,false);
addView(mLayout);
}
}
private void addView(View view){
mLnrContainer.addView(view);
}
}
我想知道和混淆哪个ViewHolders应该在我的代码中实现,如果ViewHolder被回收,是否有可能影响到其他差异?谢谢您的回答和建议。
答案 0 :(得分:1)
ViewHolder专门用于防止过度膨胀,在onBind中这样做会导致性能很差。
我将使用多个itemViewType
并相应地对布局进行充气,只是至少要回收一些东西。如果这些“ 1、2、3”不是互斥的,则会给出8种不同的布局组合。
修改您的RecyclerView.Adapter以反映可能的组合:
private static final int VIEWTYPE_FLAG_HAS_RECYCLER = 1;
private static final int VIEWTYPE_FLAG_HAS_IMAGEVIEW = 1 << 1;
private static final int VIEWTYPE_FLAG_HAS_LINEAR = 1 << 2;
// shared view pool
private final RecyclerView.RecycledViewPool adapterSharedRecycledViewPool = new RecyclerView.RecycledViewPool();
@Override
public int getItemViewType(int position) {
JSONObject data = dataList.get(position);
int viewType = 0;
// each type is a flag in viewType int, this returns values from 0 to 7
if(data.has("1"))
viewType = VIEWTYPE_FLAG_HAS_RECYCLER;
if(data.has("2"))
viewType |= VIEWTYPE_FLAG_HAS_IMAGEVIEW;
if(data.has("3"))
viewType |= VIEWTYPE_FLAG_HAS_LINEAR;
return viewType;
}
然后在创建视图持有者时检查标志(例如,将viewType作为构造函数参数传递):
private class ViewHolder3 extends RecyclerView.ViewHolder{
@BindView(R.id.lnr_container)
LinearLayout mLnrContainer;
private RecyclerView mRecyclerView;
private ImageView mImageView;
private LinearLayout mLayout;
public ViewHolder3(View itemView, int viewType) {
super(itemView);
ButterKnife.bind(this,itemView);
// only need to inflate extra views once
if((viewType & VIEWTYPE_FLAG_HAS_RECYCLER) > 0){
mRecyclerView = new RecyclerView(itemView.getContext());
// adapter must handle empty dataset
mRecyclerView.setAdapter(new SomeAdapter(itemView.getContext(), null));
// optimization to share views between other items
mRecyclerView.setRecycledViewPool(adapterSharedRecycledViewPool);
addView(mRecyclerView);
}
if((viewType & VIEWTYPE_FLAG_HAS_IMAGEVIEW) > 0){
mImageView = new ImageView(itemView.getContext());
addView(mImageView);
}
if((viewType & VIEWTYPE_FLAG_HAS_LINEAR) > 0){
mLayout = LayoutInflater.from(itemView.getContext()).inflate(R.layout.custom_layout,mLnrContainer,false);
addView(mLayout);
}
}
public void setData(JSONObject data){
// views must be ready now
if (data.has("1")){
mRecyclerView.getAdapter().setData(data);
}
if (data.has("2")){
// bind image view if needed
}
if (data.has("3")){
// bind data to linear layout as needed
}
}
private void addView(View view){
mLnrContainer.addView(view);
}
}
注意setRecycledViewPool
:这允许嵌套的recyclerViews共享其他嵌套的recyclerViews创建的视图。这样可以提高性能,但是someAdapter
创建的ViewHolders必须是静态类(而不是适配器的内部类),因为这允许ViewHolders在不同的RecyclerViews / Adapters之间遍历。