在回收站视图中查找视图是不是在屏幕上
Posted
技术标签:
【中文标题】在回收站视图中查找视图是不是在屏幕上【英文标题】:Find if a view is on screen in a recyclerview在回收站视图中查找视图是否在屏幕上 【发布时间】:2018-08-24 15:02:27 【问题描述】:我正在开发一款 androidTV 应用。所以我有一个包含 5 个项目的水平线性布局的 recyclerview。在 OnBindViewHolder 期间,我调用 viewholder.bind() 并在其中动态更改各个项目的宽度。然后我调用 getLocalVisibleRect() 来查看哪些视图实际上在屏幕上。这是问题所在。它适用于初始屏幕,但是当我向下滚动回收视图时,它与它们是否在屏幕上的结果不一致。这是我设置项目长度的地方,并尝试将其设置为可聚焦,无论它是否在屏幕上。
private void setProgramDataToView(Programme programme, TextView textView)
textView.setText(getEPGText(programme));
textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
Rect r = new Rect();
boolean v = textView.getLocalVisibleRect(r);
textView.setFocusable(v);
textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
);
ViewGroup.LayoutParams layoutParams = textView.getLayoutParams();
layoutParams.width = timeLineHelper.getDurationProgram(programme);
textView.setLayoutParams(layoutParams);
我尝试在更改长度之前或之后将 GlobalLayoutListener 更改为,看起来并没有什么不同。而且由于它适用于最初的 recyclerview 项目,因此逻辑似乎有效。看起来这可能是一种竞争条件,但是在滚动某些项目时会给出正确的结果,而其余的则非常不一致。例如,它会说屏幕上的视图不在屏幕上,而屏幕外的视图在屏幕上。任何帮助将不胜感激。
【问题讨论】:
您有什么理由不使用findFirstVisibleItemPosition
和findLastVisibleItemPosition 来确定屏幕上的视图吗?
recyclerview 是垂直的,但是每个项目都有一个水平的线性布局,这就是我希望看到哪些线性布局子项在屏幕上。我继承了这段代码,所以不确定他们为什么这样做。我发布了我的解决方案。
我知道你继承了代码,但是你能改变它吗?我可以发布一个简单的方法来检查屏幕上的 RecyclerView
布局是否可以使用。这是一种标准的做法。
我现在有一个对我有用的方法,但我也想看看你的方法是否更好。目前我的非常密集,因为它经常设置可聚焦性(每次按下 DPAD_RIGHT 时)。
我可以给你一个方法,当被调用时,它将返回屏幕上第一个和最后一个 RecyclerView
孩子的适配器位置。你能用它吗?
【参考方案1】:
这是您发布的isViewOnScreen()
方法的替代方法。它使用RecyclerView
的布局管理器将可见视图括起来,然后检查以确保相关视图的适配器位置被这些位置括起来。见doc for these methods。
private boolean isViewOnScreen(RecyclerView rv, View view)
// Assuming a LinearLayoutManager but it could be another type.
LinearLayoutManager lm = (LinearLayoutManager) recyclerView.getLayoutManager();
int firstVisiblePosition = lm.findFirstVisibleItemPosition();
int lastVisiblePosition = lm.findLastVisibleItemPosition();
int viewPosition = lm.getPosition(view);
return viewPosition >= firstVisiblePosition && viewPosition <= lastVisiblePosition;
【讨论】:
当我们到达getPosition
线时,这对我来说崩溃了【参考方案2】:
我最终只是在使用 recyclerview 的片段中检查 OnKeyDown 期间屏幕上显示了哪些视图。这在计算方面有点过分,但对我的情况有效。这样可以确保在检查视图是否在屏幕上之前完全绘制视图。
private boolean setOnScreenViewsFocusable(View focus)
View parentView = (View) focus.getParent();
if (parentView.getId() != View.NO_ID && parentView.getId() == R.id.channel_item)
LinearLayout parentLayout = (LinearLayout) parentView;
for (int i = 1; i < 6; i++)
parentLayout.getChildAt(i).setFocusable(isViewOnScreen(parentLayout.getChildAt(i)));
return false;
private boolean isViewOnScreen(View view)
Rect r = new Rect();
return view.getGlobalVisibleRect(r);
【讨论】:
以上是关于在回收站视图中查找视图是不是在屏幕上的主要内容,如果未能解决你的问题,请参考以下文章