在回收站视图中访问对象的正确高度
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.firstCardView
和doubleHolder.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 高度以进行回收器视图