我正在创建数据对象的回收站视图,这些对象中的每一个都会有所不同,例如。
对象1 - 字符串标题 - 字符串描述 - 图像对象2 - 字符串描述
对象3 - 图片 - 字符串链接 对象4 - 字符串描述 - 视频等
所以我需要动态创建项目布局以适应每个数据对象。我不想创建包含所有可能的视图和组件的项目布局,并显示和隐藏,因为我认为这是不好的做法。
所以我的问题是我需要使用onBindViewHolder中的位置从列表中访问一个对象,以便在ViewHolder类中构建我的布局。
我尝试使用我在onBindViewHolder类中调用的方法并传入我在其中添加自定义视图的对象,同时在内部设置内容,但这不起作用。
有谁知道如何做到这一点?
此致
答案 0 :(得分:5)
首先正确实现视图类型,如此处所述How to create RecyclerView with multiple view type? 实际上,你的问题与此重复,但我会写一些额外的组织内容来帮助你处理更多的持有者。
关于这个答案,我将使用ButterKnife和Picasso图书馆,因为它们很棒:http://jakewharton.github.io/butterknife/和http://square.github.io/picasso/
在项目holders
上创建一个包,然后在里面创建所有视图持有者,下面是持有者的示例:
使用AbstractHolder
创建public void bindData(Data data)
,然后使用适配器extends RecyclerView.Adapter<AbstractHolder>
:
创建如下所示的持有者:
示例Holder1.java
public class Holder1 extends AbstractHolder {
// that's an example of views this would use
@Bind(R.id.text) TextView text;
@Bind(R.id.image) ImageView image;
// constructor as normal:
public Holder1(View itemView){
super(itemView);
ButterKnife.bind(this, itemView); // init the views
}
// call this from the adapter
@Override public void bindData(Data data){
text.setText(data.text);
Picasso.with(itemView.getContext()).load(data.url).into(image);
}
// here you create an instance of this holder,
// this way the holder and the layout it's associated with goes together
public static Holder1 create(ViewGroup parent){
View root = LayoutInflater.from(parent.getContext()).inflate(R.layout.holder1, parent, false);
return new Holder1(root);
}
}
@Override public AbstractHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch(viewType){
case TYPE_HOLDER_1: return Holder1.create(parent);
case TYPE_HOLDER_2: return Holder2.create(parent);
case TYPE_HOLDER_3: return Holder3.create(parent);
... carry on for all types
}
}
@Override public void onBindViewHolder(AbstractHolder holder, int position) {
Object data = getItem(position);
holder.bindData(data);
}
// the get type would be similar to that:
@Override
public int getItemViewType(int position) {
Object data = getItem(position);
if( ... some condition...) return TYPE_HOLDER_1;
else if( ... other condition...) return TYPE_HOLDER_2;
else if( ... other condition...) return TYPE_HOLDER_3;
... etc ...
}
<强>结论强>
使用此方法,您的Adapter类只是一个&#34;分发中心&#34;对于可能的类型和每种类型&#34;知道&#34;如何创建自己以及如何处理其数据。
这使您的代码易于维护且组织良好。
答案 1 :(得分:1)
在适配器类中,您应该进行以下更改:
在您的情况下,您应该覆盖getItemViewType
方法
@Override
public int getItemViewType(int position) {
if (position < arrayList.size()) {
return ITEM_X_TYPE;
} else
return ITEM_Y_TYPE;
}
在您的onCreateViewHolder
:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == ITEM_X_TYPE) {
return new XVH(mView);
} else if (viewType == ITEM_Y_TYPE) {
return new YVH(mView);
}
throw new RuntimeException("type not found");
}
在onBindViewHolder
执行此操作:
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof XVH) {
XVH m = (XVH) holder;
... (continue your code)
修改强>
现在我的建议是,在onCreateViewHolder
中你应该像这样做:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.your_linear_layout_container, parent, false);
if (viewType == ITEM_X_TYPE) {
return new XVH(mView,ITEM_X_TYPE,Object one);
} else if (viewType == ITEM_Y_TYPE) {
return new XVH(mView,ITEM_Y_TYPE, Object two, Object three);
}
throw new RuntimeException(type not found");
}
所以在这里你创建了一个视图,然后将它传递给你的视图持有者,并创建视图持有者调用不同构造函数的不同实例。
然后在你的VH构造函数中你会像这样做:
public class XVH extends RecyclerView.ViewHolder implements {
int viewType;
public XVH(View itemView,int viewType,Object one) {
super(itemView);
this.viewType = viewType;
// manage your layouts here, build there here or you can inflate from other xml
}
public XVH(View itemView,int viewType,Object two, Object three) {
super(itemView);
this.viewType = viewType;
// manage your layouts here, build there here or you can inflate from other xml
}
在onBindViewHolder
中,您检查项目类型是什么,然后加载数据。
我希望这有助于你