【问题标题】: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?

【问题讨论】:

    标签: android android-layout android-recyclerview android-viewholder


    【解决方案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();
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2018-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-05
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 2022-01-10
      相关资源
      最近更新 更多