मैं एंड्रॉइड में गतिशील रूप से देखने की स्थिति कैसे निर्धारित कर सकता हूं?


102

मैं कोड के माध्यम से देखने की स्थिति कैसे बदल सकता हूं? जैसे इसकी X, Y स्थिति बदलना। क्या यह संभव है?

जवाबों:


117

हनीकॉम्ब (एपीआई स्तर 11) से नीचे की किसी भी चीज़ के लिए आपको उपयोग करना होगा setLayoutParams(...)

यदि आप Honeycomb करने के लिए अपने समर्थन की सीमा और कर सकते हैं आप उपयोग कर सकते हैं setX(...), setY(...), setLeft(...), setTop(...), आदि


40
सेटटॉप के डॉक्स से () developer.android.com/reference/android/view/… : sets the top position of this view relative to its parent. This method is meant to be called by the layout system and should not generally be called otherwise, because the property may be changed at any time by the layout.- तो शायद यही कारण है कि एक अच्छा विचार नहीं है;)
katzenhut

47

हां, आप Android में देखने की स्थिति को गतिशील रूप से सेट कर सकते हैं। इसी तरह आपके पास अपनी xml फ़ाइल का एक है ImageView। तो LinearLayoutआप इसके माध्यम से अपनी स्थिति निर्धारित कर सकते हैं। LayoutParamsलेकिन LayoutParamsअपने xml फ़ाइल में लिए गए लेआउट के अनुसार लेना सुनिश्चित करें LayoutParams। लिया गया लेआउट के अनुसार अलग-अलग हैं ।

यहाँ सेट करने के लिए कोड है:

    LayoutParams layoutParams=new LayoutParams(int width, int height);
    layoutParams.setMargins(int left, int top, int right, int bottom);
    imageView.setLayoutParams(layoutParams);

मुझे उम्मीद है कि यह आपको स्थिति निर्धारित करने में मददगार होगा।


15
यह भी ध्यान दें कि आपको android.widget.LinearLayout.LayoutParams आयात करना होगा; क्योंकि डिफ़ॉल्ट व्यूग्रुप का लेआउटपराम है
डेविड टी।

यह एंड्रॉइड 8+ पर काम नहीं करता है। क्या आपने भी ऐसी ही समस्या का सामना किया है?
MyFlashLab

कोई भी विचार क्यों एंड्रायड डिजाइनरों ने एक्स, वाई का उपयोग करने से चीजों को स्थिति में रखने के लिए प्रचारकों को रखने के लिए इस तरह की परेशानी में जाते हैं। अंततः सब कुछ उस तरह से खींचना पड़ता है। यह बताता है कि एंड्रॉइड उन लोगों द्वारा डिज़ाइन किया जा रहा है जो कोड नहीं कर सकते हैं।
पॉल मैकार्थी

33

अलग-अलग मान्य उत्तर पहले से ही हैं, लेकिन कोई भी ठीक से सुझाव नहीं देता है कि कौन सी विधि का उपयोग करें, किस मामले में, इसी एपीआई स्तर प्रतिबंधों को छोड़कर

  • यदि आप एक लेआउट चक्र की प्रतीक्षा कर सकते हैं और अभिभावक दृश्य समूह MarginLayoutParams(या उपवर्ग) का समर्थन करता है , तो सेट marginLeft/ marginTopतदनुसार।

  • यदि आपको तुरंत और दृढ़ता से स्थिति को बदलने की आवश्यकता है (उदाहरण के लिए एक पॉपअपमेनू एंकर के लिए), इसके अलावा layout(l, t, r, b)उसी निर्देशांक के साथ कॉल करें । यह पूर्वसूचना देता है कि लेआउट सिस्टम बाद में क्या पुष्टि करेगा।

  • तात्कालिक (अस्थायी) परिवर्तनों (जैसे एनिमेशन) के लिए, इसके बजाय setX()/ का उपयोग करें setY()। ऐसे मामलों में जहां मूल आकार WRAP_CHILDREN पर निर्भर नहीं करता है, यह उपयोग करने के लिए ठीक हो सकता है setX()/ setY()विशेष रूप से।

  • कभी उपयोग setLeft()/ setRight()/ setBottom()/ setTop(), नीचे देखें।

पृष्ठभूमि : mLeft/ mTop/ mBottom/ mRightफ़ील्ड लेआउट में संबंधित लेआउटप्रैम से भरे हुए हैं ()। एंड्रॉइड व्यू लेआउट सिस्टम द्वारा लेआउट को अंतर्निहित और अतुल्यकालिक रूप से कहा जाता है। इस प्रकार, MarginLayoutParamsस्थिति स्थायी रूप से सेट करने के लिए सबसे सुरक्षित और साफ तरीका प्रतीत होता है। हालाँकि, अतुल्यकालिक लेआउट लैग कुछ मामलों में एक समस्या हो सकती है, उदाहरण के लिए जब किसी कर्सर को रेंडर करने के लिए एक दृश्य का उपयोग किया जाता है, और यह एक ही समय में पॉपअपमेनू एंकर के रूप में फिर से तैनात और सेवा करने वाला होता है। इस मामले में, कॉलिंग layout()ने मेरे लिए ठीक काम किया।

समस्याओं setLeft()और साथ setTop()हैं:

  • उन्हें अकेले कॉल करना पर्याप्त नहीं है - आपको कॉल करने setRight()और setBottom()दृश्य को फैलाने या सिकोड़ने से बचने की भी आवश्यकता है ।

  • इन विधियों का कार्यान्वयन अपेक्षाकृत जटिल दिखता है (= उनमें से प्रत्येक के कारण हुए दृश्य आकार में परिवर्तन के लिए कुछ काम करना)

  • वे इनपुट क्षेत्रों के साथ अजीब मुद्दों का कारण बनते हैं: EditText सॉफ्ट न्यूमेरिक कीबोर्ड कभी-कभी अंकों की अनुमति नहीं देता है

setX()और setY()लेआउट सिस्टम के बाहर काम करते हैं, और इसी मान को लेआउट सिस्टम द्वारा निर्धारित बाएं / टॉप / बॉटम / राइट मानों के लिए एक अतिरिक्त ऑफसेट के रूप में माना जाता है, तदनुसार दृश्य को स्थानांतरित करना। वे एनिमेशन के लिए जोड़े गए हैं (जहां एक लेआउट चक्र के माध्यम से जाने के बिना तत्काल प्रभाव की आवश्यकता होती है)।


हैलो स्टीफन। क्या आप कुछ पुस्तकों या लेखों की सलाह दे सकते हैं जहां मैं समझ सकता हूं कि एंड्रॉइड लेआउट सिस्टम कैसे काम करता है। मैं समझता हूं कि लेआउट का अनुक्रम () onMeasure () onDraw () कॉल, लेकिन इसे और अधिक विवरण जानना चाहते हैं। अग्रिम धन्यवाद
सर्गेई ब्रजनिक

दुर्भाग्य से मैं नहीं कर सकता - सबसे अच्छा और सबसे निश्चित संदर्भ वास्तविक एंड्रॉइड स्रोत कोड O :) लगता है
स्टीफन हस्टीन

मैं दृश्य बदलने के लिए setY का उपयोग करता हूं, यह अगले लेआउट चक्र में बदलता है, तत्काल नहीं?
संकेत

आपने यह कैसे निर्धारित किया?
स्टीफन हास्टीन

यह की कीमत उनका कहना है कि marginLeftका उपयोग करके सेट किया जा सकता setLayoutParamsके साथ एक new FrameLayout.LayoutParams(width, height)है जिस पर आप सेटmarginLeft
lucidbrot

18

NineOldAndroids नाम की एक लाइब्रेरी है , जो आपको वर्जन एक के बाद एक सभी तरह से हनीकॉम्ब एनीमेशन लाइब्रेरी का उपयोग करने की अनुमति देती है।

इसका मतलब है कि आप बाएं, दाएं, ट्रांसलेशनएक्स / वाई को थोड़ा अलग इंटरफेस के साथ परिभाषित कर सकते हैं।

यहाँ दिया गया है कि यह कैसे काम करता है:

ViewHelper.setTranslationX(view, 50f);

आप व्यूहेल्पर क्लास से सिर्फ स्टैटिक मेथड का इस्तेमाल करते हैं, व्यू पास करते हैं और कभी भी जिस वैल्यू के लिए आप इसे सेट करना चाहते हैं।


16

मैं का उपयोग कर की सिफारिश करेंगे setTranslationXऔर setTranslationY। मैं केवल इस पर खुद को शुरू कर रहा हूं, लेकिन ये एक दृश्य को स्थानांतरित करने का सबसे सुरक्षित और पसंदीदा तरीका है। मुझे लगता है कि यह बहुत कुछ इस पर निर्भर करता है कि आप वास्तव में क्या करने की कोशिश कर रहे हैं, लेकिन यह मेरे लिए 2 डी एनीमेशन के लिए अच्छा काम कर रहा है।


13

यदि आप HoneyComb Sdk (API Level 11) का उपयोग कर रहे हैं, तो आप निम्न विधियों का उपयोग करने का प्रयास कर सकते हैं।

view.setX(float x);

पैरामीटर x इस दृश्य की दृश्य x स्थिति है।

view.setY(float y);

पैरामीटर y इस दृश्य की दृश्य y स्थिति है।

मुझे उम्मीद है कि यह आपके लिए उपयोगी होगा। :)


4
मैं 2.2 Froyo पर काम कर रहा हूं और ये तरीके इसमें उपलब्ध नहीं हैं।
अरुण बडोले

7

सभी एपीआई स्तरों के समर्थन के लिए आप इसे इस तरह से उपयोग कर सकते हैं :

ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);

क्योंकि वह स्थिति को बदलना चाहते हैं और उपरोक्त समाधान बेहतर है और एनीमेशन की आवश्यकता नहीं है
फायरज़ेनक

इसके अलावा, अनुवाद के कारण दृश्य (आंशिक रूप से) ऑफ स्क्रीन
मेवा

4

अपने माता-पिता के सापेक्ष इस दृश्य की बाईं स्थिति सेट करें:

view.setLeft(int leftPosition);

अपने माता-पिता के सापेक्ष इस दृश्य की सही स्थिति निर्धारित करें:

view.setRight(int rightPosition);

अपने माता-पिता के सापेक्ष इस दृश्य की शीर्ष स्थिति निर्धारित करें:

view.setTop(int topPosition);

इस दृश्य की निचली स्थिति को इसके माता-पिता के सापेक्ष सेट करें:

view.setBottom(int bottomPositon);

उपरोक्त विधियों का उपयोग इसके माता-पिता से संबंधित दृश्य को निर्धारित करने के लिए किया जाता है।


क्षमा करें ये विधियाँ उपलब्ध नहीं हैं। क्या आप मुझे कोई कोड भेज सकते हैं?
अरुण बडोले

4
"इस पद्धति को लेआउट सिस्टम द्वारा कहा जाता है और इसे आम तौर पर अन्यथा नहीं कहा जाना चाहिए, क्योंकि लेआउट द्वारा किसी भी समय संपत्ति को बदला जा सकता है।"
18

4

लेआउटपार्म्स का उपयोग करें। आप एक LinearLayout उपयोग कर रहे हैं यदि आप आयात android.widget.LinearLayout.LayoutParams, और आयात करने के लिए लेआउट के लिए LayoutParams की उचित संस्करण है आप उपयोग कर रहे हैं, या यह एक कारण होगा ClassCastException तो,:

LayoutParams layoutParams = new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);

NB: ध्यान दें कि आप भी imageView.setLeft (int dim) का उपयोग कर सकते हैं, लेकिन इस घटक की स्थिति सेट नहीं करें, यह केवल घटक की बाईं सीमा की स्थिति निर्धारित करेगा, शेष उसी स्थिति में रहेगा ।


तो हम मूल दृश्य को प्रभावित किए बिना दृश्य को विशिष्ट स्थिति में कैसे ले जा सकते हैं?
जेम्स

मुझे यकीन नहीं है कि मैंने आपकी समस्या को समझ लिया है क्योंकि यदि आप एक दृश्य को स्थानांतरित करना चाहते हैं तो आप इसे इस तथ्य से बदल देंगे कि आप इसे स्थानांतरित कर रहे हैं। वैसे भी, यदि आप इसे स्वतंत्र रूप से किसी अन्य दृश्य में ले जाना चाहते हैं, तो आपको अपने मुख्य लेआउट को देखने के लिए एक फ्रेम-आउट दृश्य की आवश्यकता हो सकती है, तो इसके अंदर, आप अपने स्वतंत्र विचार रख सकते हैं (जाहिर है, यदि आप चाहते हैं कि यह आपके मुख्य दृश्य के तहत स्थानांतरित हो जाए अपने मुख्य एक से पहले फ्रेमलैट को स्थान दें)
एलेसेंड्रो मुजी

3

इसका उपयोग करें RelativeLayout, इसमें अपना दृष्टिकोण रखें, अपने दृष्टिकोण RelativeLayout.LayoutParamsसे ऑब्जेक्ट प्राप्त करें और आवश्यकतानुसार मार्जिन सेट करें। फिर requestLayout()अपने विचार पर कॉल करें । यह एकमात्र तरीका है जो मुझे पता है।


1

मैंने पाया कि @Stefan Haustein मेरे अनुभव के बहुत करीब आता है, लेकिन निश्चित रूप से 100% नहीं। मेरा सुझाव है:

  • setLeft()/ setRight()/ setBottom()/ setTop()कभी कभी काम नहीं करेगा।
  • यदि आप अस्थायी रूप से एक स्थिति सेट करना चाहते हैं (उदाहरण के लिए एनीमेशन करने के लिए, एक पदानुक्रम प्रभावित नहीं) जब दृश्य जोड़ा गया था और दिखाया गया था , तो बस उपयोग करें setX()/setY() इसके बजाय। (आप अंतर में setLeft()औरsetX() अधिक खोज कर सकते हैं )
  • और ध्यान दें कि X, Y पूर्ण प्रतीत होता है, और इसे AbsoluteLayout द्वारा समर्थित किया गया था जो अब पदावनत हो गया है। इस प्रकार, आपको लगता है कि X, Y संभवतः किसी भी अधिक समर्थित नहीं है। और हाँ, यह है, लेकिन केवल आंशिक रूप से। इसका मतलब है कि यदि आपका दृष्टिकोण जोड़ा गया है, तो सेटएक्स (), सेटी () पूरी तरह से काम करेगा ; अन्यथा, जब आप दृश्य समूह लेआउट में दृश्य जोड़ने का प्रयास करते हैं (जैसे कि फ़्रेमलेयआउट, लियरलेयआउट, रिलेटिवलैटआउट ), तो आपको इसके लेआउटपरम को मार्जिनलिफ्ट के साथ सेट करना होगा , इसके बजाय मार्जिनटॉप (सेटएक्स (), सेटवाई () इस मामले में कभी-कभी काम नहीं करेगा)।
  • MarginLeft और marginTop से देखने का सेट स्थिति एक है अनसिंक्रनाइज़्ड प्रक्रिया। इसलिए यह पदानुक्रम को अपडेट करने के लिए थोड़ा समय चाहिए । यदि आप इसके लिए निर्धारित मार्जिन के बाद सीधे दृश्य का उपयोग करते हैं , तो आपको गलत मान मिल सकता है

0

पोजिशनिंग को ध्यान में रखने वाली एक बात यह है कि प्रत्येक दृश्य के मूल दृश्य के सापेक्ष एक सूचकांक होता है। इसलिए यदि आपके पास तीन उप-साक्षात्कारों के साथ एक रेखीय लेआउट है, तो प्रत्येक उपर्युक्त मामले में प्रत्येक में एक सूचकांक होगा: 0, 1, 2।

यह आपको कुछ ऐसा करके माता-पिता के विचार में अंतिम स्थिति (या अंत) में एक दृश्य जोड़ने की अनुमति देता है:

int childCount = parent.getChildCount();
parentView.addView(newView, childCount);

वैकल्पिक रूप से आप निम्नलिखित की तरह कुछ का उपयोग कर एक दृश्य बदल सकते हैं:

int childIndex = parentView.indexOfChild(childView);
childView.setVisibility(View.GONE);

parentView.addView(newView, childIndex);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.