Android 保存和检索膨胀视图';回收视图中的s大小

Android 保存和检索膨胀视图';回收视图中的s大小,android,android-layout,android-recyclerview,Android,Android Layout,Android Recyclerview,我有一个RecyclerView,它有一个交错的布局管理器作为布局管理器。我的布局有两个跨距(COL),其中的项目可能有不同的高度。 充气项目在LinearLayout容器中有一个ImageView和一些其他视图 我想在视图的图像完全加载后保存膨胀(或者应该说绑定?)视图的大小(高度和宽度)。因为此操作使我知道在将图像放置到布局中之后,LinearLayout最终占据了多少宽度和高度- 滚动后,此容器可再次回收和装订。我想要实现的是,根据之前计算的高度和宽度值,在绑定后立即保存绑定布局的大小,因

我有一个RecyclerView,它有一个交错的布局管理器作为布局管理器。我的布局有两个跨距(COL),其中的项目可能有不同的高度。 充气项目在LinearLayout容器中有一个ImageView和一些其他视图

我想在视图的图像完全加载后保存膨胀(或者应该说绑定?)视图的大小(高度和宽度)。因为此操作使我知道在将图像放置到布局中之后,LinearLayout最终占据了多少宽度和高度-

滚动后,此容器可再次回收和装订。我想要实现的是,根据之前计算的高度和宽度值,在绑定后立即保存绑定布局的大小,因为这使recyclerView的项目位置更加稳定。他们不太可能四处走动

我的ViewHolder中有mWidth和mHeight成员,它们基本上存储这些值。但是,我丢失了适配器中的项目位置和相应的ViewHolder之间的同步。例如,当第八项第一次可见时,我计算它的高度为380px,这是正确的。在再次循环和绑定第8个位置后,我的视图的高度恢复为300 px,这是不正确的

代码: 基本活性来源于活性

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,但我不知道这个方法是计算大小的最合适的地方)

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

我建议您寻找一种不同的方法来解决项目移动的问题,这不取决于视图大小,但如果您希望以这种方式继续,这是我建议的解决方案:

不要依赖或保存支架上的大小值,因为这会被回收,您将需要创建一个对象“描述符”,其中包含每个位置的值(宽度和高度),并将其保存在HashMap或类似的东西上,保存这些值,因为您已经这样做了,我在“onViewAttachedToWindow”上了解到了这一点

在构造函数上初始化数组:

descriptors = new HashMap<Integer, Descriptor>();
在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());
   ...
}

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

如果不想移动项目,为什么不使用
GridLayoutManager
或禁用“四处移动”?我有两个跨距(列),但与网格不同,列中的项目可能具有不同的高度。因此,为什么不使用
GAP\u HANDLING\u NONE
禁用项目移动?GAP\u HANDLING\u NONE不禁用项目移动,至少不是以我想要的方式,或者它有一个bug。它确实会转移项目,即使策略是“间隙处理”或“无”,可能只有在项目具有不同高度时才如此。你可以在这里看到我的另一个问题,它有一个youtube链接,显示了我说的话。您可以看到两行都在移动,并带有间隙。\u HANDLING\u NONE,视频顶部的间隙问题很好奇您的目的是什么?如果希望UI更稳定,可以将RecyclerView设置为#setHasFixedSize为false。视窗架随时都会被回收,你为什么要记住它们呢。如果您的最终目的是禁用项目移动,我想您应该从数据排序、图像大小处理等方面入手。onViewAttachedToWindow有时无法提供正确的高度。它只是给出了以前的预回收高度。
descriptors = new HashMap<Integer, Descriptor>();
public void onBindViewHolder(ItemListViewHolders holder, int position) {
   ....
   holder.image.setTag(position);
   ...
}
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());
   ...
}