我有一个RecyclerView,它有一个staggeredGridLayoutManager作为布局管理器。我的布局有2个跨度(cols),里面的项目可能有不同的高度。 膨胀的项目在LinearLayout容器中有一个ImageView和一些其他视图。
我想保存Inflated(或者我应该说是binded?)视图图像完全加载后View的大小(高度和宽度)。因为此操作让我知道在将图像放置在布局中之后,LinearLayout在最后占用的宽度和高度。
滚动后,此容器可以再次回收并粘贴。我想要实现的是根据先前计算的高度和宽度值,在绑定之后立即保存绑定布局的大小,因为这使得recyclerView的项目位置更加稳定。他们不太可能四处走动。
我的ViewHolder中有mWidth和mHeight成员,它们基本上存储了这些值。但是,我在适配器中的项目位置和相应的ViewHolder之间丢失了同步。例如,我将第8个项目的高度计算为380px,当它首次变为可见时,这是正确的。再次回收并绑定第8个位置后,我的视图高度检索为300像素,这是不正确的。
代码: BasicActivity派生自Activity ..
public ItemsRVAdapter(BasicActivity activity, JSONArray items){
this.items = items;
this.activity = activity;
this.itemControl = new Items(activity);
}
OnCreate中:
@Override
public ItemListViewHolders onCreateViewHolder(ViewGroup viewGroup, int i) {
View layoutView =activity.getLayoutInflater().inflate(R.layout.list_element_items, viewGroup, false);
ItemListViewHolders rcv = new ItemListViewHolders(layoutView);
return rcv;
}
OnViewAttachedToWindow(我在不同的地方尝试过相同的代码,比如onViewRecycled,但我不知道这个方法是计算大小的最合适的地方)
@Override
public void onViewAttachedToWindow(ItemListViewHolders holder)
{
holder.layoutCapsule.measure(LinearLayout.MeasureSpec.makeMeasureSpec(0, LinearLayout.MeasureSpec.UNSPECIFIED), LinearLayout.MeasureSpec.makeMeasureSpec(0, LinearLayout.MeasureSpec.UNSPECIFIED));
if(holder.image.getDrawable() != null){
holder.height = holder.layoutCapsule.getHeight();
holder.width = holder.layoutCapsule.getWidth();
}else{
holder.height = 0;
holder.width = 0;
}
}
onBindViewHolder:只有相关部分。这里我配对了位置值和我的数组的成员索引
@Override
public void onBindViewHolder(ItemListViewHolders holder, int position) {
try {
//JSONObject item = items.getJSONObject(holder.getAdapterPosition());
JSONObject item = items.getJSONObject(position);
holder.image.setImageDrawable(null);
ViewGroup viewGroup = holder.layoutCapsule; //Main Container
...
}
}
答案 0 :(得分:2)
我建议寻找一种不同的方法来解决您的问题,这些项目不会因视图大小而移动,但如果您想这样做,这是我建议的解决方案:
不要依赖或保存持有者的大小值,因为这会被回收,你需要创建一个对象"描述符"使用每个位置的值(宽度和高度)并将它们保存在HashMap或类似的东西上,保存已经存在的值,我理解" onViewAttachedToWindow"。
class Descriptor(){
int width;
int height;
void setWidth(int width){
this.width = width;
}
int getWidth(){
return width;
}
void setHeight(int height){
this.height = height;
}
int getHeight(){
return height;
}
在构造函数上初始化数组:
descriptors = new HashMap<Integer, Descriptor>();
onBindViewHolder中的保存视图标记上的位置以在OnViewAttachedToWindow上使用它
public void onBindViewHolder(ItemListViewHolders holder, int position) {
....
holder.image.setTag(position);
...
}
在onViewAttachedToWindow上填充值
public void onViewAttachedToWindow(ItemListViewHolders holder){
...
int position = (Integer)holder.image.getTag();
Descriptor d = descriptors.get(position);
if(d == null){
d = new Descriptor();
descriptors.put(position, d);
}
d.setWidth(holder.layoutCapsule.getWidth());
d.setHeight(holder.layoutCapsule.getHeight());
...
}
然后在你需要按位置获取它的方法上使用描述符上的大小数据,你将在用户向下滚动时创建描述符,这也可以假设数据在生命周期中保持相同的位置。适配器。