439

ビューの左上隅の絶対画面ピクセル座標を取得しようとしています。しかし、私が見つけることができるすべてのメソッドは、ビューの親に相対的であるように見えるため、機能getLeft()getRight()ません0。これを行う適切な方法は何ですか?

それが役立つ場合、これは「写真を元に戻す」ゲーム用です。ユーザーがボックスを描画して複数のピースを選択できるようにしたい。私の推測では、これを行う最も簡単な方法は、とgetRawX()の間を行き来し、それらの値を、ピースを保持しているレイアウトの左上隅と比較することです。ピースのサイズがわかれば、選択されたピースの数を判断できます。でとを使用できることはわかっていますが、相対位置が返されるため、どのピースが選択されたかを判断するのが難しくなります。(不可能ではないことはわかっていますが、不必要に複雑に思えます)。getRawY()MotionEventgetX()getY()MotionEvent

編集:これは、質問の1つに従って、保持コンテナーのサイズを取得しようとするために使用したコードです。TableLayoutすべてのパズルのピースを保持するテーブルです。

TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());

編集2:これが私が試したコードで、提案された回答の詳細に従っています。

public int[] tableLayoutCorners = new int[2];
(...)

TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.requestLayout();
Rect corners = new Rect();
tableLayout.getLocalVisibleRect(corners);
Log.d(LOG_TAG, "Top left " + corners.top + ", " + corners.left + ", " + corners.right
            + ", " + corners.bottom);

cells[4].getLocationOnScreen(tableLayoutCorners);
Log.d(LOG_TAG, "Values " + tableLayoutCorners[0] + ", " + tableLayoutCorners[1]);

このコードは、すべての初期化が完了した後に追加されました。画像は、TableLayout. Cells[0] は左上ImageViewで、cells[4] を選択しました。これは、中央のどこかにあり、(0,0) の座標を持つべきではないためです。

上記のコードでは、ログにすべて 0 が記録されますが、さまざまなパズルのピースが正しく表示されているため、実際には理解できません。(私は、tableLayoutCorners とデフォルトの可視性の public int を試しましたが、どちらも同じ結果が得られました。)

これが重要かどうかはわかりませんが、ImageViewsにはもともとサイズが与えられていません。sのサイズは、ImageView表示する画像を与えると、初期化中に View によって自動的に決定されます。ロギング コードは画像が与えられ、自動的にサイズ変更された後であるにもかかわらず、これは値が 0 になることに貢献できますか? これに対抗する可能性があるため、上記のコードを追加しましたtableLayout.requestLayout()が、役に立ちませんでした。

4

10 に答える 10

684

View.getLocationOnScreen()および/またはを使用しgetLocationInWindow()ます。

于 2010-02-09T01:05:19.330 に答える
103

まず、ビューの localVisible 長方形を取得する必要があります

例:

Rect rectf = new Rect();

//For coordinates location relative to the parent
anyView.getLocalVisibleRect(rectf);

//For coordinates location relative to the screen/display
anyView.getGlobalVisibleRect(rectf);

Log.d("WIDTH        :", String.valueOf(rectf.width()));
Log.d("HEIGHT       :", String.valueOf(rectf.height()));
Log.d("left         :", String.valueOf(rectf.left));
Log.d("right        :", String.valueOf(rectf.right));
Log.d("top          :", String.valueOf(rectf.top));
Log.d("bottom       :", String.valueOf(rectf.bottom));

これが役立つことを願っています

于 2010-02-09T04:16:11.400 に答える
49

グローバル レイアウト リスナーの使用は、常にうまく機能しています。レイアウトが変更された場合、たとえば、何かが View.GONE に設定されたり、子ビューが追加/削除されたりした場合に、再測定できるという利点があります。

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);

     // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
     LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null); 

     // set a global layout listener which will be called when the layout pass is completed and the view is drawn
     mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
       new ViewTreeObserver.OnGlobalLayoutListener() {
          public void onGlobalLayout() {
               //Remove the listener before proceeding
               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
               } else {
                    mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
               }

               // measure your views here
          }
       }
     );

     setContentView(mainLayout);
 }
于 2012-11-06T22:56:24.440 に答える
18

Romain Guy のコメントに従って、これを修正する方法を次に示します。うまくいけば、この問題を抱えている他の人にも役立つでしょう。

ビューが画面に配置される前に、実際にビューの位置を取得しようとしていましたが、それが起こっていることはまったく明らかではありませんでした。これらの行は、初期化コードが実行された後に配置されたので、すべての準備が整っていると思いました。ただし、このコードはまだ onCreate(); にありました。Thread.sleep() を試してみると、onCreate() から onResume() までの実行が完了するまで、レイアウトが実際には確定されないことがわかりました。実際、レイアウトが画面上に配置される前に、コードが実行されようとしていました。コードを OnClickListener (またはその他のリスナー) に追加すると、レイアウトが終了した後にのみ起動できるため、正しい値が取得されました。


以下の行は、コミュニティの編集として提案されました。

使ってくださいonWindowfocuschanged(boolean hasFocus)

于 2010-02-09T21:16:45.083 に答える
7

上記の回答に加えて、いつ、どこに電話すればよいgetLocationOnScreenですか?

に関連するすべての情報についてはview、ビューが画面上にレイアウト (作成) された後にのみ使用できます。したがって、場所を取得するには、次のように、配置されたview.post(Runnable)後に呼び出されるコードを内部に配置します。view

view.post(new Runnable() {
            @Override
            public void run() {

               // This code will run when view created and rendered on screen

               // So as the answer to this question, you can put the code here
               int[] location = new int[2];
               myView.getLocationOnScreen(location);
               int x = location[0];
               int y = location[1];
            }
        });  
于 2020-04-30T10:08:59.607 に答える