70

これら2つの方法のコンテキストでのスクリーンとビューの違いは何ですか?

ボタンがあり、その中心の x 座標を取得したい。

これで十分だと思います:

public int getButtonXPosition() {
    return (button.getLeft()+button.getRight())/2;
}

しかし、もし私が

getLocationOnScreen()またはgetLocationInWindow()

(もちろん、ボタンの幅の半分を追加します)

4

4 に答える 4

119

この答えは正しくないと思います。新しいプロジェクトを作成し、次のスニペットを追加して MainActivity のみを編集するとします。

public boolean dispatchTouchEvent(MotionEvent ev) {
    View contentsView = findViewById(android.R.id.content);

    int test1[] = new int[2];
    contentsView.getLocationInWindow(test1);

    int test2[] = new int[2];
    contentsView.getLocationOnScreen(test2);

    System.out.println(test1[1] + " " + test2[1]);

    return super.dispatchTouchEvent(ev);
}

コンソールに表示され108 108ます。これは、4.3 を実行する Nexus 7 を使用しています。Androidバージョンを2.2までさかのぼって実行しているエミュレーターを使用して、同様の結果が得られます。

通常のアクティビティ ウィンドウは、WindowManager.LayoutParams として FILL_PARENTxFILL_PARENT を持つため、画面全体のサイズにレイアウトされます。ウィンドウは、ステータスバーやその他の装飾の下 (y 座標ではなく z オーダーに関して) に配置されるため、より正確なグラフは次のようになると思います。

|--phone screen-----activity window---| 
|--------status bar-------------------| 
|                                     | 
|                                     | 
|-------------------------------------| 

これら 2 つのメソッドのソースをステップ実行するとgetLocationInWindow、ビューのビュー階層を RootViewImpl までトラバースして、ビュー座標を合計し、親スクロール オフセットを減算することがわかります。上記の場合、ViewRootImpl は WindowSession からステータス バーの高さを取得し、fitSystemWindows を介して ActionBarOverlayLayout に渡します。これにより、この値がアクションバーの高さに追加されます。次に、ActionBarOverlayLayout はこの合計値を取得し、レイアウトの親であるコンテンツ ビューに余白として適用します。

したがって、ウィンドウがステータス バーよりも低い y 座標から始まるためではなく、アクティビティのコンテンツ ビューにマージンが適用された結果として、コンテンツがステータス バーよりも下にレイアウトされます。

getLocationOnScreenソースをよく見ると、ウィンドウの左と上の座標を呼び出して追加するだけであることがわかります(これらは、 ViewRootImplgetLocationInWindowによってビューにも渡され、WindowSession からフェッチされます)。通常、これらの値は両方とも 0 です。画面の中央に配置されたダイアログ ウィンドウなど、これらの値が 0 以外になる場合があります。


要約すると、通常のアクティビティのウィンドウは、ステータス バーや装飾の下のスペースも含めて、画面全体に表示されます。問題の 2 つのメソッドは、同じ x 座標と y 座標を返します。ウィンドウが実際にオフセットされているダイアログなどの特別な場合にのみ、これら 2 つの値が異なります。

于 2013-11-22T21:11:45.373 に答える
35

getLocationOnScreen()電話スクリーンに基づいて場所を取得します。アクティビティ ウィンドウ
getLocationInWindow()に基づいて場所を取得します。

通常のアクティビティ(フルスクリーン アクティビティではない) の場合、電話画面とアクティビティ ウィンドウとの関係は次のようになります。

|--------phone screen--------|
|---------status bar---------|
|                            |
|----------------------------|
|------activity window-------|
|                            |
|                            |
|                            |
|                            |
|                            |
|                            |
|----------------------------|

x座標については、通常、両方のメソッドの値は同じです。座標
については、ステータス バーの高さの値に違いがあります。y

于 2013-07-16T10:06:14.490 に答える
11

現在受け入れられている回答は少し冗長です。これは短いものです。

getLocationOnScreen()getLocationInWindow()通常は同じ値を返します。これは、通常、ウィンドウが画面と同じサイズであるためです。ただし、ウィンドウが画面よりも小さい場合があります。たとえば、Dialogまたはカスタム システム キーボードで。

したがって、必要な座標が常に画面に対して相対的であることがわかっている場合 (通常のアクティビティのように)、 を使用できますgetLocationOnScreen()。ただし、ビューが画面よりも小さいウィンドウ (ダイアログやカスタム キーボードなど) にある場合は、 を使用しますgetLocationInWindow()

関連している

于 2018-03-31T09:52:28.430 に答える