android - 在 RecyclerView 中保存和检索膨胀 View 的大小

标签 android android-layout android-recyclerview

我有一个 RecyclerView,它有一个 staggeredGridLayoutManager 作为布局管理器。我的布局有 2 个跨度(列),其中的项目可能具有不同的高度。 膨胀的项目在 LinearLayout 容器内有一个 ImageView 和一些其他 View 。

我想在 View 的图像完全加载后保存膨胀(或者我应该说绑定(bind)?) View 的大小(高度和宽度)。因为这个操作让我知道LinearLayout在final-在layout中放置图片之后占据了多少宽高。

滚动后,这个容器可能会被回收并再次绑定(bind)。我想实现的是绑定(bind)后立即根据之前计算出的高度和宽度值保存绑定(bind)布局的大小,因为这样可以使recyclerView的项目位置更稳定。他们不太可能四处走动。

我的 ViewHolder 中有 mWidth 和 mHeight 成员,它们基本上存储了这些值。但是,我在适配器中的项目位置和相应的 ViewHolder 之间失去了同步。例如,当第 8 个项目首次可见时,我将其高度计算为 380px,这是正确的。再次回收并绑定(bind)第 8 个位置后,我的 View 高度检索为 300 px,这是不正确的。

代码: BasicActivity 派生自 Activity..

public ItemsRVAdapter(BasicActivity activity, JSONArray items){
    this.items = items;
    this.activity = activity;
    this.itemControl = new Items(activity);
}

创建时:

@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
        ...
    }
}

最佳答案

我建议寻找一种不同的方法来解决您的项目移动不依赖于 View 大小的问题,但如果您想继续这样做,这是我建议的解决方案:

不要依赖或保存 holder 上的尺寸值,因为它会被回收,您需要创建一个对象“描述符”,其中包含每个位置的值(宽度和高度),并将它们保存在 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 中保存 View 标签上的位置以在 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());
   ...
}

然后在您需要按位置获取它的方法上使用描述符上的大小数据,您将在用户向下滚动时创建描述符,这也是基于数据在生命周期内保持相同位置的假设适配器。

关于android - 在 RecyclerView 中保存和检索膨胀 View 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35615282/

相关文章:

android - 从 NDK 启动另一个 Android 应用程序?

java - viewpager 完成后调用 Activity

android - 如何在Kotlin中将listView转换为RecyclerView

java.lang.InstantiationException,实例化RecyclerView.ViewHolder

android - fragment 没有膨胀

android - 如何从 Android 应用程序在应用程序的 Facebook 墙上发布提要?

java - {Facebook 登录} java.lang.NoClassDefFoundError : android. support.v4.content.LocalBroadcastManager

android - 相机 Intent 过滤器

java - Android CircularReveal 错误 : Not working after starting another type of animator on the same view

Android:如何只适合系统窗口内的 map 对象?