确定视图是不是在屏幕上 - Android

Posted

技术标签:

【中文标题】确定视图是不是在屏幕上 - Android【英文标题】:Determine if a view is on screen - Android确定视图是否在屏幕上 - Android 【发布时间】:2013-03-30 05:58:54 【问题描述】:

我有点坚持这个 - 首先,以下链接很有用,但是我提出了一些可见性问题:

链接:Check view visibility

我有一个滚动视图(父视图)和许多子视图(LinearLayout -> TableLayout)等。我在 XML 中设置了许多项目为 View.GONEandroid:visibility="gone") .

我有一些简单的代码可以使用getVisibility() 来确定它是否可见,但是当我将项目设置为View.VISIBLE 并尝试立即getDrawingRect() 时,我得到一个全线为零的矩形。任何进一步的点击都会获得正确的坐标。

现在这可能是因为从未绘制过视图(如 XML 中定义的那样)导致它不返回任何坐标,但是我在尝试确定屏幕可见性之前确实设置了 View.VISIBLE。是不是我需要从 onDraw() 中获得某种回调?或者也许设置代码中隐藏项的视图可见性。有点烦人;(

一些代码:

Rect scrollBounds = new Rect();
scroll.getHitRect(scrollBounds);

Rect viewBounds = new Rect();

if (view.getVisibility() == View.GONE) 
    view.setVisibility(View.VISBLE)


    viewBounds.getDrawingRect(viewBounds);
    if (!Rect.intersects(scrollBounds, viewBounds) 
        // do somthing
     

布局区域如下:

ScrollView LinearLayout TableLayout Button HiddenView

当然,我很有可能完全走错了路 - 基本上我只是想确保滚动视图自行定位,以便可以看到整个可见的视图。

如果需要任何其他信息,请告诉我!

【问题讨论】:

【参考方案1】:

好的,感谢 OceanLife 为我指明了正确的方向!确实需要回调,ViewTreeObserver.OnGlobalLayoutListener() 成功了。我最终针对我的片段类实现了监听器,并在我需要的地方拾取了它。感谢您对多次调用的警告,我使用removeOnGlobalLayoutListener() 方法解决了这个问题 - 很有魅力。

代码:

...

// vto initialised in my onCreateView() method

vto = getView().getViewTreeObserver();
vto.addOnGlobalLayoutListener(this);

...

@Override
    public void onGlobalLayout() 

        final int i[] = new int[2];
        final Rect scrollBounds = new Rect();

        sView.getHitRect(scrollBounds);
        tempView.getLocationOnScreen(i);

        if (i[1] >= scrollBounds.bottom) 
            sView.post(new Runnable() 
                @Override
                public void run() 
                    sView.smoothScrollTo(0, sView.getScrollY() + (i[1] - scrollBounds.bottom));
                
            );
        

        vto.removeOnGlobalLayoutListener(this);
    

现在只需要做一些清理工作......

【讨论】:

酷。如果有帮助,请随意勾选箭头/+1。干杯。 是的,我试图这样做,但我的声望点不允许我这样做:(【参考方案2】:

所以,如果我没看错的话,你遇到的问题是你想找出布局中某个视图的尺寸,以确定你是否与父级 ScrollView 有交集。

我认为您所看到的(正如您所提到的)是绘制正在调度的视图的指令,然后在某种竞争条件下,渲染器解析布局的测量值 视图对象获得真实尺寸的实际渲染。找出视图在屏幕上具有何种尺寸的一种方法是使用布局树侦听器。在利用 Google Charts API 时,我们使用此观察器来解析屏幕的尺寸,这需要定义像素宽度和高度......当然,这在 Android 上可能是开发人员面临的最大问题。所以请注意(双关语);

final ViewTreeObserver vto = chart.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() 

  /**
   * @see android.view.ViewTreeObserver.OnGlobalLayoutListener#onGlobalLayout()
   */
  @SuppressWarnings("deprecation")
  @Override
  public void onGlobalLayout() 
    if (view.getVisibility() == View.GONE) 
      view.setVisibility(View.VISBLE)
      viewBounds.getDrawingRect(viewBounds);
      if (!Rect.intersects(scrollBounds, viewBounds) 
        // do something
       
    
  
);

警告onGlobalLayout 将在渲染器接近最终解决方案时被多次调用。最后一个电话是我们接听的电话。

这将为您提供一种在绘制视图上执行操作的机制,例如获取视图组件的宽度和高度。希望对您有所帮助。

旁白:Square 的聪明人设计了一个 FEST hamcrest 库,可以让您与 Robotium 一起为此编写测试。 Check it out.

【讨论】:

刚刚注意到方法是deprecated。唔。希望它的更换说明是明确的。 是的,你是对的,我想找到尺寸的原因是检查视图是否在屏幕上相对于 ScrollView 的位置可见 - 如果不是,我想推动滚动视图.下班后我会尽快查看 ViewTreeObserver!谢谢:P

以上是关于确定视图是不是在屏幕上 - Android的主要内容,如果未能解决你的问题,请参考以下文章

如果没有表格视图结果,则在屏幕上显示“无结果”

Java:确定小程序是不是显示在屏幕上

如何使用默认查看按钮确定用户是不是在锁定屏幕上查看通知

在回收站视图中查找视图是不是在屏幕上

如何使用 selenium java/python 确定元素是不是在特定时间显示在屏幕上?

UIScrollview,当完全缩小时是不是可以在屏幕上移动视图?