it-swarm.asia

getLocationOnScreen () مقابل getLocationInWindow ()

ما هو الفرق بين الشاشة والعرض في سياق هاتين الطريقتين؟

لدي زر وأريد الحصول على إحداثي x لمركزها.

أعتقد أن هذا سيكون كافيا:

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

ولكن بعد ذلك ، ما الفرق الذي سيحدثه لو كنت قد استخدمت

getLocationOnScreen() أو getLocationInWindow()؟

(إضافة نصف عرض الزر إلى ذلك ، بالطبع)

60
Elad Benda

لا أعتقد هذه الإجابة صحيحة. إذا قمت بإنشاء مشروع جديد ، وقمت بتحرير 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. هذا يستخدم Nexus 7 الذي يعمل بنظام التشغيل 4.3. لدي نتائج مماثلة باستخدام المحاكيات التي تعمل على تشغيل إصدارات أندرويد بقدر 2.2.

سيكون لنوافذ النشاط العادي FILL_PARENTxFILL_PARENT كـ WindowManager الخاص بهم. LayoutParams ، مما ينتج عنها تخطيط لحجم الشاشة بأكملها. تم وضع النافذة أسفل (فيما يتعلق بالترتيب z ، وليس الإحداثيات y) شريط الحالة والزخارف الأخرى ، لذلك أعتقد أن المخطط الأكثر دقة سيكون:

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

إذا انتقلت إلى مصدر هاتين الطريقتين ، فسترى أن getLocationInWindow تتخطى التسلسل الهرمي لطريقة العرض الخاصة بك حتى RootViewImpl ، وتلخص إحداثيات طريقة العرض وتطرح إزاحة تمرير الأصل. في الحالة الموضحة أعلاه ، يحصل ViewRootImpl على ارتفاع شريط الحالة من WindowSession ، ويمرره عبر fitSystemWindows إلى ActionBarOverlayLayout ، مما يضيف هذه القيمة إلى ارتفاع شريط الإجراءات. يأخذ ActionBarOverlayLayout هذه القيمة المجمعة ويطبقها على طريقة عرض المحتوى الخاصة به ، والتي هي أصل التصميم الخاص بك ، كهامش.

لذلك ، يتم وضع المحتوى الخاص بك أقل من شريط الحالة ليس نتيجة للإطار الذي يبدأ عند إحداثي ص أقل من شريط الحالة ، ولكن بدلاً من ذلك كنتيجة لتطبيق الهامش على عرض محتوى نشاطك.

إذا نظرت إلى مصدر getLocationOnScreen ، فسترى أنه يستدعي فقط getLocationInWindow ثم يضيف الإطارين العلوي والأيسر للنافذة (والتي يتم تمريرها أيضًا إلى View by ViewRootImpl ، والتي تجلبها من WindowSession). في الحالة العادية ، ستكون هذه القيمتين صفرية. هناك بعض المواقف التي قد تكون فيها هذه القيم غير صفرية ، على سبيل المثال نافذة حوار يتم وضعها في منتصف الشاشة.


لتلخيص: نافذة النشاط العادي تملأ الشاشة بأكملها ، حتى المساحة الموجودة أسفل شريط الحالة والزخارف. سيعود طريقتين في السؤال نفسه إحداثيات س و ص. فقط في الحالات الخاصة مثل مربعات الحوار التي يتم فيها إزاحة النافذة فعليًا ، ستختلف هاتان القيمتان.

107
groucho

سيحصل getLocationOnScreen () على الموقع بناءً على شاشة الهاتف .

سيحصل getLocationInWindow () على الموقع بناءً على نافذة النشاط .

بالنسبة إلى النشاط العادي (النشاط ليس بملء الشاشة) ، العلاقة مع شاشة الهاتف ونافذة النشاط على النحو التالي:

| - شاشة الهاتف --------------------- |
| -------- شريط المعلومات --------------------- |
| |
| ------------------------------------------- |
| -------- نافذة النشاط ------ ------- |
| |
| |
| |
| |
| |
| |
| ------------------------------------------- |

بالنسبة إلى الإحداثي س ، تكون قيمة كلا الأسلوبين هي نفسها عادة.

بالنسبة إلى إحداثي y ، يكون للقيم اختلاف في ارتفاع شريط الحالة

23
Ivan

الجواب المقبول الحالي هو قليل الكلام. هنا أقصر.

getLocationOnScreen() و getLocationInWindow() عادةً ما ترجع نفس القيم. هذا لأن النافذة عادة ما تكون بنفس حجم الشاشة. ومع ذلك ، في بعض الأحيان تكون النافذة أصغر من الشاشة. على سبيل المثال ، في Dialog أو لوحة مفاتيح نظام مخصصة.

لذلك إذا كنت تعرف أن الإحداثيات التي تريدها مرتبطة دائمًا بالشاشة (كما في نشاط عادي) ، فيمكنك استخدام getLocationOnScreen(). ومع ذلك ، إذا كان العرض الخاص بك في نافذة قد تكون أصغر من الشاشة (مثل في مربع حوار أو لوحة مفاتيح مخصصة) ، فاستخدم getLocationInWindow().

ذات صلة

2
Suragch