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

确定视图是否在屏幕上-Android,android,view,scrollview,visibility,Android,View,Scrollview,Visibility,我对这一点有点纠结——首先也是最重要的是,以下链接很有用,但是我发现了一个关于可见性的问题: 链接: 我有一个滚动视图(父视图)和许多子视图(LinearLayout->TableLayout)等。我将许多项设置为view.GONE在XML中(android:visibility=“GONE”) 我有一些简单的代码,可以使用getVisibility()来确定它是否可见。但是,当我将项目设置为View.visible并尝试立即getDrawingRect()时,我得到了一个带零的矩形。任何进一步

我对这一点有点纠结——首先也是最重要的是,以下链接很有用,但是我发现了一个关于可见性的问题:

链接:

我有一个滚动视图(父视图)和许多子视图(
LinearLayout
->
TableLayout
)等。我将许多项设置为
view.GONE
在XML中(
android: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
        • 按钮
        • HiddenView
当然,我很有可能是完全错误的——基本上我只是想确保scrollview自身的位置,这样就可以看到整个可见的视图


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

因此,如果我正确阅读此内容,您面临的问题是,您希望了解布局中某个视图的尺寸,以了解您是否与父视图<代码>滚动视图相交

我认为你看到的(正如你提到的)是绘制要调度的视图的指令,然后在某种竞争条件下,渲染器解析布局的测量值和视图对象获得实际大小的实际渲染值。找出视图在屏幕上具有何种尺寸的一种方法是使用布局树侦听器。我们使用此观察器利用谷歌图表API解决屏幕尺寸问题,这需要定义像素的宽度和高度……这在Android上可能是开发者面临的最大问题

警告:渲染器接近最终解决方案时,
onGlobalLayout
将被多次调用。最后一次调用是我们进行的调用

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


旁白:Square的聪明人设计了一个FEST hamcrest库,可以让你和Robotium一起为此编写一个测试。

好吧,多亏OceanLife为我指明了正确的方向!确实需要回调,而且
ViewTreeObserver.OnGlobalLayoutListener()
成功了。我最终针对我的片段类实现了侦听器,并在需要的地方找到了它。感谢关于多个调用的警告,我使用
removeOnGlobalLayoutListener()
方法解决了这个问题-非常有效

代码:


现在我要做一些清理…

刚刚注意到该方法已弃用。嗯。希望它的替换说明很清楚。是的,你说得对,我想找到尺寸的原因是检查相对于ScrollView位置的视图在屏幕上是否可见-如果不是,我想轻推scrollvie好的。我会在下班后尽快查看ViewTreeObserver!谢谢:PCool。如果有帮助,请随意勾选箭头/+1。干杯。是的,我尝试过这么做,但我的声誉积分不允许我:(
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
      } 
    }
  }
});
...

// 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);
    }