21

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

链接:检查视图可见性

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

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

现在这可能是因为从未绘制过视图(如 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

当然,我很有可能完全走错了路——基本上我只是想确保滚动视图自身定位,以便可以完整地看到已经变得可见的视图。

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

4

2 回答 2

20

好的,感谢 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);
    }

现在只好打扫一下...

于 2013-04-08T19:02:02.987 回答
11

因此,如果我没看错,那么您遇到的问题是您想找出布局中某些视图的尺寸,以了解您是否与 parent 有交集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 一起为此编写测试。检查出来

于 2013-04-08T09:41:37.660 回答