মূল বিন্যাসের তুলনায় ভিউয়ের স্থানাঙ্কগুলি পাওয়া


142

অ্যান্ড্রয়েডে আমার ক্রিয়াকলাপের মূল বিন্যাসের তুলনায় আমি কী ভিউ এর এক্স এবং ওয়াই অবস্থান পেতে পারি?

উত্তর:


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 (), এটি ঠিক নয়।
pengwang

আমি খুব অনুরূপ কিছু করেছি তবে আমি getId == R.id.myRootView দ্বারা রুট ভিউটি পরীক্ষা করেছিলাম।
fhucho

1
লগ.আই ("রিলেটিভ লেফট", "" + getRelativeLeft (FindViewById (R.id.tv))); লগ.আই ("রিলেটিভটপ", "" + getRelativeTop (FindViewById (R.id.tv))); আমি সব 0 হয় পেতে; লেআউটটিতে টেক্সটভিউটি নিম্নরূপ <টেক্সটভিউ অ্যান্ড্রয়েড: লেআউট_উইথ = "ফিল_প্যারেন্ট" অ্যান্ড্রয়েড: লেআউট_উইচটি = "র‌্যাপ_কন্টেন্ট" অ্যান্ড্রয়েড: টেক্সট = "@ স্ট্রিং / হ্যালো" অ্যান্ড্রয়েড: আইডি = "@ + আইডি / টিভি" অ্যান্ড্রয়েড: লেআউট_মারগিনবটম = "69 ডিপ" অ্যান্ড্রয়েড: লেআউট_মার্জিন লেফট = "69 ডিপ" />
পেংগাং

এর মতো স্মার্ট অ্যাপ্রোচ (নিজেই এটি গণনা করা) আমার পক্ষে কাজ করেছিল তাই আমি এই উত্তরটি মেনে নিয়েছি।
fhucho

3
অ্যান্ড্রয়েড এপিআই ইতিমধ্যে রুটের সাথে সম্পর্কিত তুলনামূলক সরবরাহ করে। এখানে দেখুন stackoverflow.com/a/36740277/2008214
carlo.marinangeli

155

অ্যান্ড্রয়েড এপিআই ইতিমধ্যে এটি অর্জনের জন্য একটি পদ্ধতি সরবরাহ করে। এটা চেষ্টা কর:

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 পর্যন্ত ফিটসিসটেম উইন্ডো এবং বিভিন্ন এপিআই সংস্করণ So তাই আপনাকে ধন্যবাদ! এটি সঠিক উত্তর।
ডেভিড ফের্যান্ড

নির্দোষভাবে কাজ করেছেন
রাওয়া

খুব ভাল কাজ করেছে, কেবল উল্লেখ parentViewGroupকরতে চাই যে ভিউ হায়ারার্কির কোনও পিতা-মাতা হতে পারে, সুতরাং এটি স্ক্রোলভিউয়ের জন্যও পুরোপুরি কাজ করে।
সিরা লাম

93

দয়া করে ব্যবহার করুন view.getLocationOnScreen(int[] location);( জাভাদোকগুলি দেখুন )। উত্তরটি পূর্ণসংখ্যার অ্যারে (x = location[0]এবং y = location[1]) এ।


13
এটি ক্রিয়াকলাপের ক্রিয়াকলাপটি কার্যকলাপের মূল বিন্যাসে নয় returns
fhucho

10
এখানে View.getLocationInWindow (int []) রয়েছে যা উইন্ডোটির সাথে সম্পর্কিত ভিউটির অবস্থান প্রদান করে।
রুবিকন

এই পদ্ধতিটি কীভাবে কাজ করে আমাকে দয়া করে বলতে পারেন। এটি স্ক্রিনে একটি
ভিউর

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

ম্যানুয়ালি এটি গণনা করার দরকার নেই।

ঠিক এর মতো getGlobalVisibleRect ব্যবহার করুন :

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যদি আপনার কেবল আপেক্ষিক কুডিনেটের প্রয়োজন হয়।
Xender

2
এটি উত্তর গ্রহণ করা উচিত। getLocationOnScreen পাশাপাশি getGlobalVisibleRect হিসাবে কাজ করে। তবে getGlobalVisibleRect কিছুটা আরও তথ্য সরবরাহ করে এবং কাঁচা অ্যারে নিয়ে কাজ করার দরকার নেই। আমি তাই getGlobalVisibleRect সাথে যেতে চাই। ব্যবহার সহজ। রেক্ট পজিশনেক্ট = নতুন রেক্ট (); view.getGlobablVisibleRect (positionRect); // x = অবস্থানRect.left // y = পজিশনেক্ট.টপ। চিয়ার্স
জ্যাকসঅনএফএফ

যদি সন্তানের কিছু অংশ বাইরে থাকে যা এই ক্ষেত্রে বিবেচনায় নেবে না। এ জাতীয় মামলা কীভাবে সমাধান করবেন?
DKV

দুর্দান্ত উত্তর! তোমাকে অনেক ধন্যবাদ!
রোহিত কুমার

8

আপনি use ব্যবহার করতে পারেন

View.getLocationOnScreen (int [] অবস্থান)

; your আপনার দর্শনের অবস্থানটি সঠিকভাবে পেতে।

কিন্তু একটি হল ধরা যদি আপনি এটি ব্যবহার করার আগে লেআউট স্ফীত হয়ে গেলে আপনাকে ভুল অবস্থানে পাবেন।

এই সমস্যার সমাধান এর ViewTreeObserverমতো যুক্ত হচ্ছে: -

আপনার দর্শনটির এক্স ওয়াই অবস্থান সংরক্ষণের জন্য বিশ্বব্যাপী অ্যারে ঘোষণা করুন

 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

যদি কেউ এখনও এটি বের করার চেষ্টা করছে to এভাবেই আপনি কেন্দ্রের এক্স এবং ওয়াই পাবেন 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 () পদ্ধতিগুলি আহ্বান করে একটি দৃশ্যের অবস্থান পুনরুদ্ধার করা সম্ভব। প্রাক্তনটি উপাত্তকে উপস্থাপন করে এমন আয়তক্ষেত্রের বাম বা এক্স প্রদান করে। পরবর্তীটি দৃশ্যের প্রতিনিধিত্ব করে এমন আয়তক্ষেত্রের শীর্ষ বা y প্রদান করে। এই পদ্ধতিগুলি উভয়ই তার পিতামাতার তুলনায় ভিউয়ের অবস্থানটি ফিরিয়ে দেয়। উদাহরণস্বরূপ, যখন 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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.