【问题标题】: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 项目,因此逻辑似乎有效。看起来这可能是一种竞争条件,但是在滚动某些项目时会给出正确的结果,而其余的则非常不一致。例如,它会说屏幕上的视图不在屏幕上,而屏幕外的视图在屏幕上。任何帮助将不胜感激。

【问题讨论】:

  • 您有什么理由不使用findFirstVisibleItemPositionfindLastVisibleItemPosition 来确定屏幕上的视图吗?
  • recyclerview 是垂直的,但是每个项目都有一个水平的线性布局,这就是我希望看到哪些线性布局子项在屏幕上。我继承了这段代码,所以不确定他们为什么这样做。我发布了我的解决方案。
  • 我知道你继承了代码,但是你能改变它吗?我可以发布一个简单的方法来检查屏幕上的 RecyclerView 布局是否可以使用。这是一种标准的做法。
  • 我现在有一个对我有用的方法,但我也想看看你的方法是否更好。目前我的非常密集,因为它经常设置可聚焦性(每次按下 DPAD_RIGHT 时)。
  • 我可以给你一个方法,当被调用时,它将返回屏幕上第一个和最后一个 RecyclerView 孩子的适配器位置。你能用它吗?

标签: android android-recyclerview android-tv


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多