在回收站视图中访问对象的正确高度

Posted

技术标签:

【中文标题】在回收站视图中访问对象的正确高度【英文标题】:Accessing the correct height of a object in a recycler view 【发布时间】:2016-03-20 18:43:35 【问题描述】:

所以,我正在尝试根据同一视图持有者中另一个对象的高度,在我的回收站视图的 onBindViewHolder 方法中更改 ImageView 的高度。当我使用getHeight() 访问高度时,前几个元素的结果是 0 - 很可能是因为它们现在没有被绘制。

这个问题的general solution 对我不起作用,因为回收器视图创建并绑定了很多视图,为每个视图添加了一个GlobalLayoutListener,这似乎把事情搞砸了,给了我错误的结果(例如只是改变第一个元素的高度)。

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) 

    final ViewHolderDouble doubleHolder = (ViewHolderDouble) holder;

    if (secProduct != null) 
        final ViewTreeObserver observer = doubleHolder.linearLayoutSD.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() 
            @Override
            public void onGlobalLayout() 

                int difference = doubleHolder.firstCardView.getHeight() - doubleHolder.secCardView.getHeight();

                if (difference > 0) 
                    ImageView rightImage = doubleHolder.imageViewR;
                    rightImage.getLayoutParams().height = rightImage.getHeight() + difference;
                    rightImage.requestLayout();
                 else if (difference < 0) 
                    ImageView leftImage = doubleHolder.imageViewL;
                    leftImage.getLayoutParams().height = leftImage.getHeight() + (difference * -1);
                    leftImage.requestLayout();
                

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) 
                    doubleHolder.linearLayoutSD.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                 else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) 
                    doubleHolder.linearLayoutSD.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                
            
        );
    

在绘制视图后,有什么方法可以访问doubleHolder.firstCardViewdoubleHolder.secCardView 的高度,所以我得到正确的高度而不是0?

【问题讨论】:

【参考方案1】:

不久前我有非常相似的任务,所以我是这样做的。

首先,适配器。我在onBindViewHolder 中没有做太多,我只是用内容运行方法“displayItem”——填充实际的View

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) 
    if (position >= contentItems.size()) 
        return;
    

    ((ContentItemCardView)viewHolder.itemView).displayItem(contentItems.get(position));

关键部分发生在ContentItemCardView,在我的例子中是extends CardView。这是它的简短版本:

public class ContentItemCardView extends CardView 

    @InjectView(R.id.previewImageView)
    ImageView previewImageView;

    @InjectView(R.id.titleTextView)
    TextView titleTextView;

    public ContentItemCardView(Context context)
        super(context);
        ButterKnife.inject(this);
    

    .....

    public void displayItem(ContentItem contentItem) 
        ....
        titleTextView.setText(contentItem.Title);
        displayPreview(contentItem);
        ....
    

    public void displayPreview(ContentItem contentItem) 
        int requiredHeight = determineHeight(.....);
        previewImageView.getLayoutParams().height = requiredHeight;
        previewImageView.requestLayout();
        ....
    

    public int determineHeight() 
        ....
    

所以我们剩下的就是拥有正确的determineHeight()(假设它应该比填充的titleTextView高两倍):

public int determineHeight() 
    final Resources resources = getResources();
    int screenWidth = resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ?
            resources.getDisplayMetrics().widthPixels :
            resources.getDisplayMetrics().heightPixels; 

    int widthMeasureSpec = MeasureSpec.makeMeasureSpec(screenWidth, MeasureSpec.AT_MOST);
    int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

    titleTextView.measure(widthMeasureSpec, heightMeasureSpec);

    return titleTextView.getMeasuredHeight() * 2;
               

所以您只需要明确设置计算出的高度和requestLayout()

        int requiredHeight = determineHeight(.....);
        previewImageView.getLayoutParams().height = requiredHeight;
        previewImageView.requestLayout();

希望对你有帮助。

【讨论】:

以上是关于在回收站视图中访问对象的正确高度的主要内容,如果未能解决你的问题,请参考以下文章

处理物品的正确方法点击回收站视图

Android - 无法将视图设置为卡片内的 match_parent 高度以进行回收器视图

从 mvvm 获取的数据在第一次访问时不会在回收站视图中更新

如何访问回收站视图中的按钮?

回收站视图 - 在空对象引用上

如何实现回收滚动视图?