web-dev-qa-db-ja.com

ビューが画面上にあるかどうかを確認-Android

私はこれに少しこだわっています-何よりもまず、次のリンクは役に立ちましたが、可視性に少し問題があります:

リンク: ビューの可視性を確認

私はスクロールビュー(親)といくつかのサブビュー(LinearLayout-> TableLayout)などを持っています。XML内に_View.GONE_に設定したアイテムがいくつかあります(_Android: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

もちろん、私がこれを完全に間違った方法で行っている可能性は非常に高いです。基本的には、スクロールビュー自体が配置されていることを確認して、表示されたビューが全体的に見えるようにします。

その他の情報が必要な場合は、お知らせください!

21
Hamz4h_

正しい方向に向けてくれた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);
    }

今すぐ片付けをしなければなりません...

19
Hamz4h_

したがって、私がこの権利を読んでいる場合、あなたが抱えている問題は、レイアウト内のビューの寸法を調べて、親ScrollViewとの共通部分があるかどうかを調べることです。

お気づきのように、ディスパッチされているビューを描画する命令が表示されていると思います。次に、ある種の競合状態で、レンダラーがレイアウトの測定値を解決しますおよびビューオブジェクトが実際のサイズを取得する実際のレンダリング。ビューの画面上での種類を確認する1つの方法は、レイアウトツリーリスナーを使用することです。ピクセルの幅と高さを定義する必要がある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と一緒にこのテストを作成できます。 チェックアウト

11
OceanLife