रूट लेआउट के सापेक्ष व्यू के निर्देशांक प्राप्त करना


142

क्या मुझे एंड्रॉइड में अपनी गतिविधि के रूट लेआउट के सापेक्ष एक दृश्य x और y स्थिति मिल सकती है?

जवाबों:


138

यह एक समाधान है, हालांकि चूंकि एपीआई समय के साथ बदलते हैं और ऐसा करने के अन्य तरीके भी हो सकते हैं, अन्य उत्तरों की जांच करना सुनिश्चित करें। एक दावा करने में तेज़ है, और दूसरा आसान होने का दावा करता है।

private int getRelativeLeft(View myView) {
    if (myView.getParent() == myView.getRootView())
        return myView.getLeft();
    else
        return myView.getLeft() + getRelativeLeft((View) myView.getParent());
}

private int getRelativeTop(View myView) {
    if (myView.getParent() == myView.getRootView())
        return myView.getTop();
    else
        return myView.getTop() + getRelativeTop((View) myView.getParent());
}

मुझे बताएं कि क्या वह काम करता है।

इसे पुनरावर्ती रूप से प्रत्येक माता-पिता के कंटेनर से शीर्ष और बाएं स्थान जोड़ना चाहिए। Pointयदि आप चाहते हैं तो आप इसे लागू भी कर सकते हैं ।


getRelativeLeft () यह ऐड कास्ट है, लेकिन जब मैं ऐड (व्यू) या (बटन) ((ऑब्जेक्ट) myView.getParent ())। getRelativeTop () करता हूं, तो यह भी सही नहीं है
पेंगवांग सेप

मैंने कुछ ऐसा ही किया, लेकिन मैंने getId == R.id.myRootView द्वारा रूट दृश्य के लिए जाँच की।
फूफू

1
Log.i ("RelativeLeft", "" + getRelativeLeft (findViewById (R.id.tv))); Log.i ("RelativeTop", "" + getRelativeTop (findViewById (R.id.tv))); मुझे सब मिल गया 0 है; textView लेआउट में निम्नानुसार है <TextView android: Layout_width = "fill_parent" android: layout_height = "wra_content" android: text = "string / hello" Android: id = "@ + id / tv / android: layout_marginBottom =" 69dip " Android: Layout_marginLeft = "69dip" />
पेंगवांग

इस तरह से आकर्षक दृष्टिकोण (इसे मैन्युअल रूप से गणना करना) ने मेरे लिए काम किया इसलिए मैंने इस उत्तर को स्वीकार कर लिया।
फूफू

3
एंड्रॉइड एपी पहले से ही रूट के सापेक्ष समन्वय प्रदान करता है। यहां देखें stackoverflow.com/a/36740277/2008214
carlo.marinangeli

155

Android API पहले से ही इसे प्राप्त करने के लिए एक विधि प्रदान करता है। इसे इस्तेमाल करे:

Rect offsetViewBounds = new Rect();
//returns the visible bounds
childView.getDrawingRect(offsetViewBounds);
// calculates the relative coordinates to the parent
parentViewGroup.offsetDescendantRectToMyCoords(childView, offsetViewBounds); 

int relativeTop = offsetViewBounds.top;
int relativeLeft = offsetViewBounds.left;

यहाँ डॉक्टर है


16
यह स्वीकृत उत्तर होना चाहिए। स्टैक ओवरफ्लो की कोई संभावना नहीं, और गणित की त्रुटियों की कोई संभावना नहीं। धन्यवाद!
जीली

मैं सहमत हूं, यह स्वीकृत उत्तर होना चाहिए - केवल 92 अप-वोट जाने के लिए।
स्तब्ध

मैं टूलबार में एक दृश्य के निर्देशांक ढूंढना चाहता था। यह एक तरीका है जो एंड्रॉइड के लिए खाते में लगातार काम करता है: 19 से 27 तक फिट बैठता है सिस्टमविंडोज़ और विभिन्न एपीआई संस्करण। इसलिए धन्यवाद! यह सही जवाब है।
डेविड फेरैंड

त्रुटिपूर्ण रूप से काम किया
रावा

बहुत अच्छी तरह से काम किया है, बस यह उल्लेख करना चाहते हैं कि parentViewGroupपदानुक्रम में कोई भी माता-पिता हो सकते हैं, इसलिए यह स्क्रॉल व्यू के लिए भी पूरी तरह से काम करता है।
सिरा लैम

93

कृपया view.getLocationOnScreen(int[] location);( Javadocs देखें ) का उपयोग करें । उत्तर पूर्णांक सरणी (x = location[0]और y = location[1]) में है।


13
यह गतिविधि के रूट लेआउट के लिए स्क्रीन पर स्थिति को लौटाता है।
फूफू

10
इसमें View.getLocationInWindow (int []) भी है, जो विंडो के सापेक्ष दृश्य की स्थिति लौटाता है।
रुबिकॉन

क्या आप मुझे बता सकते हैं कि यह विधि कैसे काम करती है। यह एक शून्य देता है कि हम कैसे आउटपुट या x प्राप्त करते हैं, स्क्रीन पर एक दृश्य के y मान
user1106888

6
रूट लेआउट के सापेक्ष स्थिति प्राप्त करने के लिए, बस रूट लेआउट और तत्व के लिए getLocationInWindow को कॉल करें, और घटाव की शक्ति का उपयोग करें। यह स्वीकृत उत्तर की तुलना में कहीं अधिक सरल और संभव है।
मिलर

1
यह केवल स्क्रीन से संबंधित स्थान है। जड़ नहीं। जड़ के सापेक्ष यहाँ पढ़ें: stackoverflow.com/a/36740277/2008214
carlo.marinangeli

36
View rootLayout = view.getRootView().findViewById(android.R.id.content);

int[] viewLocation = new int[2]; 
view.getLocationInWindow(viewLocation);

int[] rootLocation = new int[2];
rootLayout.getLocationInWindow(rootLocation);

int relativeLeft = viewLocation[0] - rootLocation[0];
int relativeTop  = viewLocation[1] - rootLocation[1];

पहले मुझे रूट लेआउट मिलता है फिर दृश्य के साथ निर्देशांक अंतर की गणना करें।
आप getLocationOnScreen()इसके बजाय का उपयोग भी कर सकते हैं getLocationInWindow()


3
क्या दृश्य बढ़ाया और घुमाया गया है?
DKV

यह एकमात्र उत्तर है जो मेरे लिए काम कर रहा है। इसका उत्तर स्वीकार किया जाना चाहिए
neoexpert

36

इसे मैन्युअल रूप से गणना करने की आवश्यकता नहीं है।

बस getGlobalVanishRect का उपयोग करें जैसे:

Rect myViewRect = new Rect();
myView.getGlobalVisibleRect(myViewRect);
float x = myViewRect.left;
float y = myViewRect.top;

यह भी ध्यान दें कि केंद्र निर्देशांक के लिए, बजाय कुछ की तरह:

...
float two = (float) 2
float cx = myViewRect.left + myView.getWidth() / two;
float cy = myViewRect.top + myView.getHeight() / two;

आप बस कर सकते हैं:

float cx = myViewRect.exactCenterX();
float cy = myViewRect.exactCenterY();

एंड्रॉयड स्रोत सब को देखते हुए getGlobalVisibleRectकरता है globalOffset.set(-mScrollX, -mScrollY);, इसलिए आप बस के साथ उन मूल्यों को मिल सकता है getScollX/Yअगर आप केवल रिश्तेदार के निर्देशांक की जरूरत है।
ज़ेंडर

2
इसका उत्तर स्वीकार किया जाना चाहिए। getLocationOnScreen काम करता है और साथ ही getGlobalVanishRect भी। लेकिन getGlobalVanishRect थोड़ी अधिक जानकारी प्रदान करता है और कच्चे सरणियों के साथ काम करने की कोई आवश्यकता नहीं है। इसलिए मैं getGlobalVanishRect के साथ जाऊंगा। उपयोग सरल है। पंथ स्थिति = नया अनुपात (); view.getGlobablVisibleRect (positionRect); // x = positionRect.left // y = positionRect.top। चीयर्स
JacksOnF1re

अगर बच्चे का कुछ हिस्सा बाहर है जो इस मामले में ध्यान नहीं देगा। ऐसे मामले को कैसे हल करें?
DKV

बहुत बढ़िया जवाब! आपको बहुत - बहुत धन्यवाद!
रोहित कुमार

8

आप `का उपयोग कर सकते हैं

view.getLocationOnScreen (int [] स्थान)

, `सही ढंग से अपने विचार का स्थान पाने के लिए।

लेकिन वहाँ एक पकड़ है अगर आप इसे लेआउट से पहले फुलाया जाता है तो आप गलत स्थिति प्राप्त करेंगे।

इस समस्या का समाधान ViewTreeObserverइस प्रकार है: -

अपने दृश्य की xy स्थिति संग्रहीत करने के लिए विश्व स्तर पर सरणी घोषित करें

 int[] img_coordinates = new int[2];

और फिर ViewTreeObserverलेआउट की मुद्रास्फीति के लिए कॉलबैक प्राप्त करने के लिए अपने माता-पिता के लेआउट में जोड़ें और उसके बाद ही देखने की स्थिति प्राप्त करें अन्यथा आपको गलत xy निर्देशांक मिलेंगे

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

                            // measure your views here
                            fab.getLocationOnScreen(img_coordinates);
                        }
                    }
            );

और फिर इसे इस तरह से उपयोग करें

xposition = img_coordinates[0];
yposition =  img_coordinates[1];

3

मैंने खुद को दो उपयोगिता पद्धतियां लिखीं, जो अधिकांश स्थितियों में काम करती हैं, स्क्रॉल, अनुवाद और स्केलिंग को संभालती हैं, लेकिन रोटेशन नहीं। मैंने फ्रेमवर्क में ऑफसेटडेस्केंटेरेंट रेक्टोटो मेयर्ड्स () का उपयोग करने की कोशिश के बाद ऐसा किया, जिसमें असंगत सटीकता थी। इसने कुछ मामलों में काम किया लेकिन दूसरों में गलत परिणाम दिए।

"बिंदु" दो तत्वों के साथ एक फ्लोट सरणी है (x & y निर्देशांक), "पूर्वज" पेड़ के पदानुक्रम में "वंशज" से कहीं ऊपर एक दृश्य समूह है।

पहली विधि जो वंशज से जाती है, पूर्वज के लिए समन्वयित होती है:

public static void transformToAncestor(float[] point, final View ancestor, final View descendant) {
    final float scrollX = descendant.getScrollX();
    final float scrollY = descendant.getScrollY();
    final float left = descendant.getLeft();
    final float top = descendant.getTop();
    final float px = descendant.getPivotX();
    final float py = descendant.getPivotY();
    final float tx = descendant.getTranslationX();
    final float ty = descendant.getTranslationY();
    final float sx = descendant.getScaleX();
    final float sy = descendant.getScaleY();

    point[0] = left + px + (point[0] - px) * sx + tx - scrollX;
    point[1] = top + py + (point[1] - py) * sy + ty - scrollY;

    ViewParent parent = descendant.getParent();
    if (descendant != ancestor && parent != ancestor && parent instanceof View) {
        transformToAncestor(point, ancestor, (View) parent);
    }
}

पूर्वज से पूर्वज के वंशज के आगे:

public static void transformToDescendant(float[] point, final View ancestor, final View descendant) {
    ViewParent parent = descendant.getParent();
    if (descendant != ancestor && parent != ancestor && parent instanceof View) {
        transformToDescendant(point, ancestor, (View) parent);
    }

    final float scrollX = descendant.getScrollX();
    final float scrollY = descendant.getScrollY();
    final float left = descendant.getLeft();
    final float top = descendant.getTop();
    final float px = descendant.getPivotX();
    final float py = descendant.getPivotY();
    final float tx = descendant.getTranslationX();
    final float ty = descendant.getTranslationY();
    final float sx = descendant.getScaleX();
    final float sy = descendant.getScaleY();

    point[0] = px + (point[0] + scrollX - left - tx - px) / sx;
    point[1] = py + (point[1] + scrollY - top - ty - py) / sy;
}

2

किसी को अभी भी यह पता लगाने की कोशिश कर रहा है। इस तरह से आप केंद्र X और Y प्राप्त करते हैं view

    int pos[] = new int[2];
    view.getLocationOnScreen(pos);
    int centerX = pos[0] + view.getMeasuredWidth() / 2;
    int centerY = pos[1] + view.getMeasuredHeight() / 2;

1

मुझे बस यहीं जवाब मिला

यह कहता है: तरीकों getLeft () और getTop () को लागू करके दृश्य के स्थान को पुनर्प्राप्त करना संभव है। पूर्व बाईं ओर, या X, दृश्य को दर्शाने वाली आयत का समन्वय करता है। उत्तरार्द्ध शीर्ष, या वाई देता है, दृश्य को दर्शाने वाली आयत का समन्वय करता है। ये विधियाँ अपने माता-पिता के सापेक्ष दृश्य का स्थान लौटाती हैं। उदाहरण के लिए, जब getLeft () 20 लौटता है, तो इसका अर्थ है कि दृश्य अपने प्रत्यक्ष माता-पिता के बाएं किनारे के दाईं ओर 20 पिक्सेल स्थित है।

इसलिए उपयोग करें:

view.getLeft(); // to get the location of X from left to right
view.getRight()+; // to get the location of Y from right to left

1
यह दृश्य के तत्काल माता-पिता के सापेक्ष स्थान देता है, मूल दृश्य के लिए नहीं, जो माता-पिता आदि का माता-पिता हो सकता है ...
रूपर्ट रॉन्स्ले

क्या दृश्य बढ़ाया और घुमाया गया है?
DKV
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.