RecyclerView显示不同item的解决办法
recyclerview和adapter使用方法很简单,在此不再赘述。
当RecyclerView需要显示不同item时,一般来说有两种解决方法。
场景示例:假设列表中需要显示音乐和广告,实体如下
public class Music{
private String name;
//...省略其他信息}
public class Ad{
private String merchant;
private String content;
//...省略其他信息}
方法一:
在一个xml文件中绘制两种item显示样式,不需要哪个就让哪个gone掉,具体方法如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@color/white"
android:orientation="vertical">
<LinearLayout
android:id="@+id/llMusic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="@+id/llAd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tvMerchant"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
在onBindViewHolder
中根据需要让另一个类型gone掉就可以了
@Override
public void onBindViewHolder(@NonNull ExampleViewHolder holder, int position) {
ExampleItem item = getItem(position);
if(item instanceof Music){
holder.llMusic.setVisibility(View.VISIBLE);
holder.llAd.setVisibility(View.GONE);
//进行其他视图显示设置
} else {
holder.llMusic.setVisibility(View.GONE);
holder.llAd.setVisibility(View.VISIBLE);
//进行其他视图显示设置
}
}
但是这个方法有一个缺点,就是效率不高造成资源浪费,原因是每一个item都有llMusic和llAd,但其实每个item只需要显示其中一个。
方法二:
总体思路:创建两个资源文件item和两个ViewHolder,在adapter中根据viewType创建对应的viewHolder。
item_music.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@color/white"
android:orientation="vertical">
<TextView
android:id="@+id/tvName"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
item_ad.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="@color/white"
android:orientation="vertical">
<TextView
android:id="@+id/tvMerchant"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tvContent"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
创建两个viewHolder类:
先创建一个抽象基类BaseViewHolder
private abstract class BaseViewHolder extends RecyclerView.ViewHolder{
public BaseViewHolder(View itemView){
super(itemView);
}
}
再分别创建两个ViewHolder继承BaseViewHolder
private class MusicViewHolder extends BaseViewHolder{
TextView name;
public MusicViewHolder(View itemView){
super(itemView);
name = (TextView) itemView.findViewById(R.id.tvName);
}
}
private class AdViewHolder extends BaseViewHolder{
TextView merchant;
TextView content;
public AdViewHolder(View itemView){
super(itemView);
merchant= (TextView) itemView.findViewById(R.id.tvMerchant);
content= (TextView) itemView.findViewById(R.id.tvContent);
}
}
在adapter中的用法
@Override
public int getItemViewType(int position){
if(data.getItem(position) instanceof Music){
return R.layout.item_music;
}else return R.layout.item_ad;
}
@Override
public void onBindViewHolder(BaseViewHolder holder, int position){
Object item = data.get(position);
if (item instanceof Music){
//设置相关内容
}else{
//设置相关内容
}
}