使用视图类型并不是最简单的方法。有时最好不要使用 ViewType,而是实现一个可以做所有事情的类层次结构。
好的,我们的任务是在列表中显示家具项目 - 椅子、床等。先实现对象模型:
public abstract class FurnitureBase {
@LayoutRes
abstract public int getLayoutFileResource();
abstract public HolderFurnitureBase getHolder(View convertView);
}
public class FurnitureChair extends FurnitureBase {
public double price;
public Material material;
...
public FurnitureChair(double price, Material material) {
...
}
@Override
public int getLayoutFileResource() {
return R.layout.item_furniture_chair;
}
@Override
public HolderFurnitureBase getHolder(View convertView) {
return new HolderFurnitureChair(convertView);
}
}
public class FurnitureBed extends FurnitureBase {
public double price;
public BedSize size;
...
public FurnitureBed(double price, BedSize size) {
...
}
@Override
public int getLayoutFileResource() {
return R.layout.item_furniture_bed;
}
@Override
public HolderFurnitureBase getHolder(View convertView) {
return new HolderFurnitureBed(convertView);
}
}
接下来,创建持有者:
public abstract class HolderFurnitureBase
{
public HolderFurnitureBase(View convertView) { };
public abstract void renderItem(FurnitureBase item);
}
public class HolderFurnitureChair extends HolderFurnitureBase
{
private final ImageViewAccent mIconAction;
private final TextViewPrimaryDark mPrice;
...
public HolderFurnitureChair(View convertView)
{
// just init views
super(convertView);
this.mIconAction = convertView.findViewById(R.id.item_furniture_chair_icon_action;
this.mPrice = convertView.findViewById(R.id.item_furniture_chair_text_price);
}
public void renderItem(FurnitureBase item)
{
FurnitureChair chair = (FurnitureChair ) item;
mIconAction.setImageResource(chair.getProductTypeIcon());
mPrice.setText(Utils.Formatter.formatMoney(chair.price, chair.priceCurrency));
}
}
public class HolderFurnitureBed extends HolderFurnitureBase
{
private final TextView mSize;
private final TextViewPrimaryDark mPrice;
...
public HolderFurnitureBed(View convertView)
{
// just init views
super(convertView);
this.mSize = convertView.findViewById(R.id.item_furniture_bed_text_size;
this.mPrice = convertView.findViewById(R.id.item_furniture_bed_text_price);
}
public void renderItem(FurnitureBase item)
{
FurnitureBed bed = (FurnitureBed) item;
mSize.setText(bed.getSizeText());
mPrice.setText(Utils.Formatter.formatMoney(bed.getPrice(), bed.getPriceCurrency()));
}
}
并在适配器中收集所有魔法:
public final class AdapterFurniture extends ArrayAdapter<FurnitureBase>
{
public AdapterFurniture(Context context, List<FurnitureBase> items) {
super(context, R.layout.item_furniture_bed, items);
}
@NonNull
@Override
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent)
{
FurnitureBase item = getItem(position);
HolderFurnitureBase holder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(item.getLayoutFileResource(), parent, false);
holder = item.getHolder(convertView);
}
else {
holder = (HolderFurnitureBase) convertView.getTag();
}
holder.renderItem(getItem(position));
convertView.setTag(holder);
return convertView;
}
}
就是这样。无需计算视图类型,添加沙发和扶手椅时无需更改适配器等等 - 只需扩展新项目的基类和新持有人的持有人基类,应用程序就准备好了测试人员享受:)