प्रोग्रामिक रूप से RelativeLayout में दृश्य कैसे प्रस्तुत करें?


234

मैं निम्नलिखित प्रोग्रामेटिक रूप से प्राप्त करने की कोशिश कर रहा हूं (बजाय XML के माध्यम से घोषित):

<RelativeLayout...>
   <TextView ...
      android:id="@+id/label1" />
   <TextView ...
      android:id="@+id/label2"
      android:layout_below: "@id/label1" />
</RelativeLayout>

दूसरे शब्दों में, मैं TextViewपहले वाले से नीचे दूसरा प्रकट कैसे कर सकता हूं , लेकिन मैं इसे कोड में करना चाहता हूं:

RelativeLayout layout = new RelativeLayout(this);
TextView label1 = new TextView(this);
TextView label2 = new TextView(this);
...
layout.addView(label1);
layout.addView(label2);
setContentView(layout);

अपडेट करें:

धन्यवाद, TreeUK। मैं सामान्य दिशा को समझता हूं, लेकिन यह अभी भी काम नहीं करता है - "बी" ओवरलैप्स "ए"। मैं क्या गलत कर रहा हूं?

RelativeLayout layout = new RelativeLayout(this);
TextView tv1 = new TextView(this);
tv1.setText("A");

TextView tv2 = new TextView(this);
tv2.setText("B");
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
        RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.FILL_PARENT);
lp.addRule(RelativeLayout.RIGHT_OF, tv1.getId());

layout.addView(tv1);        
layout.addView(tv2, lp);

आपके कोड नमूने में, आप वास्तव में RelativeLayout.BELOW, tv1.getId () का नियम नहीं जोड़ रहे हैं;
ट्रिस्टन वार्नर-स्मिथ

48
आपको अपने बच्चे के विचारों को आईडी प्रदान करने की आवश्यकता है: tv1.setId (1); tv2.setId (2); माता-पिता के विचार बच्चे के विचारों को अपने आप एक आईडी प्रदान नहीं करते हैं, और एक आईडी के लिए डिफ़ॉल्ट मान NO_ID है। Id का दृश्य में अद्वितीय होना जरूरी नहीं है - इसलिए 1, 2, 3, आदि उपयोग करने के लिए सभी अच्छे मूल्य हैं - और आपको RelativeLayout में काम करने के लिए रिश्तेदार एंकरिंग के लिए उनका उपयोग करना होगा।
16

जवाबों:


196

जो कुछ मैं एक साथ करने में सक्षम हूं, उससे आपको लेआउटप्रैम का उपयोग करके दृश्य जोड़ना होगा।

LinearLayout linearLayout = new LinearLayout(this);

RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
        LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
relativeParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);

parentView.addView(linearLayout, relativeParams);

धर्मनिरपेक्षता का सारा श्रेय, आपकी वस्तुओं को प्रोग्रामिक रूप से स्थिति में लाने के लिए, आपको उन्हें आईडी आवंटित करना है।

TextView tv1 = new TextView(this);
tv1.setId(1);
TextView tv2 = new TextView(this);
tv2.setId(2);

फिर addRule(RelativeLayout.RIGHT_OF, tv1.getId());


1
मेरे मामले में, एक चाइल्डव्यू की आईडी सेट करने के अलावा, अन्य चाइल्डव्यू के नियमों को सेट करने से पहले चाइल्डव्यू को पेरेंटव्यू में जोड़ने और चाइल्डव्यू पर रिक्वेस्ट लाइएटआउट () कॉल करने के लिए काम किया। आशा है कि यह किसी की मदद करता है
2cupsOfTech

मामले में कोई भी अभी भी इसका अनुसरण करता है: जब मेरे पास विचारों का एक संग्रह होता है जिसे मैं एक-एक करके जोड़ रहा हूं और मुझे यकीन नहीं हो सकता है कि एक आइटम के सेट होने belowका एक दृश्य पहले ही जोड़ा जा चुका है, यह कैसे सुनिश्चित करें कि यह अभी भी रेंडर करता है सही ढंग से? मेरी समझ addViewसे लेआउट को फिर से प्रस्तुत करने का कारण बनता है, इसलिए यदि मैं ऐसा किसी आइटम के लिए करता हूं, जिसके रिश्तेदार को अभी तक नहीं जोड़ा गया है, तो यह उस आईडी के साथ आइटम के बाद से क्रैश होने वाला है जो अभी तक मौजूद नहीं है।
मेगाकोरेश

1
सेट (आईडी) का उपयोग एपीआई स्तर 17 में जनरेट व्यूआईडी () के साथ किया जाना चाहिए। यह सेटआईड (इंट) में उपयोग के लिए उपयुक्त मूल्य उत्पन्न करता है। यह मान R.id के लिए aapt द्वारा निर्मित समय पर बनाए गए ID मानों से नहीं टकराएगा। उदाहरण: टीवी [l_idx] .setId (View.generateViewId ());
एंड्रयूब्लूम

यह उत्तर बहुत बुरी तरह से लिखा गया है। रैखिक लेआउट के लिए RelationalLayout मापदंडों का उपयोग करने के पीछे तर्क क्या है? और आप पेरेंट व्यू में रैखिक लेआउट क्यों जोड़ रहे हैं?
PCodex

अरे @Prab, यह जवाब अब 9 साल पुराना है। आप कैसे जवाब आज की जरूरतों के लिए सुधार किया जा सकता पर कुछ सकारात्मक प्रतिक्रिया है, तो संपादित करें बटन हिट करने के लिए स्वतंत्र लग रहा है और यह सुझाव कृपया 👍
ट्रिस्टन वार्नर स्मिथ

60

लंबी कहानी को छोटा काटें: सापेक्ष लेआउट के साथ आप तत्वों को लेआउट के अंदर रखते हैं।

  1. एक नया RelativeLayout.LayoutParams बनाएँ

    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(...)

    (जो भी हो ... माता-पिता या रैप सामग्री, पूर्ण संख्याओं को भरें अगर आपको चाहिए, या किसी XML संसाधन का संदर्भ दें)

  2. नियम जोड़ें: नियम पदानुक्रम में माता-पिता या अन्य "भाइयों" को संदर्भित करते हैं।

    lp.addRule(RelativeLayout.BELOW, someOtherView.getId())
    lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
  3. बस लेआउट पैरा लागू करें: यह करने के लिए सबसे 'स्वस्थ' तरीका है:

    parentLayout.addView(myView, lp)

बाहर देखें : लेआउट कॉलबैक से लेआउट न बदलें। ऐसा करना ललचाता है क्योंकि ऐसा तब होता है जब विचारों को उनके वास्तविक आकार मिलते हैं। हालाँकि, उस स्थिति में, अप्रत्याशित परिणाम अपेक्षित हैं।


मुझे नहीं पता था कि आप एक दृश्य में पैरामेट्स सेट कर सकते हैं और एक दृश्य जोड़ सकते हैं यह माता-पिता को कोड की एक पंक्ति में देखें ( parentLayout.addView(myView, lp)। मैंने हमेशा कोड की दो लाइनों में किया था। धन्यवाद!
मैट

इसने मेरे लिए काम किया और बहुत मदद की, लेकिन क्या बच्चे को किसी चीज़ से नीचे संरेखित करने का कोई तरीका है और फिर उस बच्चे के लिए मार्जिन निर्धारित किया जाए? या क्या मैं उस चीज़ के लिए नीचे मार्जिन सेट कर सकता हूं जो नीचे है और क्या यह सही तरीके से समायोजित होगा?
याकूब वार्नर

ज़रूर है। आप हाशिये को सेट कर सकते हैं (दुर्भाग्य से, प्रोग्राममैटिक एपीआई सेटमर्जिन (बाएं, ऊपर, दाएं, नीचे) के साथ एक्सएमएल जितना आरामदायक नहीं है)। यह लेआउटपार्म्स में है। ध्यान दें कि पैडिंग दृश्य की एक संपत्ति है, न कि लेआउट परिमाण।
मेमन

29

इस समस्या के साथ सिर्फ 4 घंटे बिताए। अंत में एहसास हुआ कि आपको शून्य का उपयोग आईडी के रूप में नहीं करना चाहिए । आपको लगता होगा कि इसे NO_ID == -1 के रूप में अनुमति दी जाती है, लेकिन अगर आप इसे अपने विचार से जोड़ते हैं तो चीजें हयवायर जाती हैं ...


2
मैं वही देखता हूं। मैं एपीआई 7 का उपयोग कर रहा हूं, और जेवाडॉक को देखकर मुझे लगता है कि सेटिड (इंट) यह बताता है कि आईडी एक सकारात्मक पूर्णांक होना चाहिए। यह कुछ ऐसा है जिसे कोड में लागू किया जाना चाहिए, न कि केवल डॉक्स में टिप्पणी की गई है। डेवलपर
.android.com

@OYRM एंड्रॉइड एक गड़बड़ है
SpaceMonkey

आपने संभवतः मुझे समय का एक हिस्सा बचा लिया। धन्यवाद!
आरजेआर-एप्स

9

एंड्रॉइड 22 न्यूनतम रननीय उदाहरण

यहां छवि विवरण दर्ज करें

स्रोत:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class Main extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final RelativeLayout relativeLayout = new RelativeLayout(this);

        final TextView tv1;
        tv1 = new TextView(this);
        tv1.setText("tv1");
        // Setting an ID is mandatory.
        tv1.setId(View.generateViewId());
        relativeLayout.addView(tv1);

        // tv2.
        final TextView tv2;
        tv2 = new TextView(this);
        tv2.setText("tv2");
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.FILL_PARENT);
        lp.addRule(RelativeLayout.BELOW, tv1.getId());
        relativeLayout.addView(tv2, lp);

        // tv3.
        final TextView tv3;
        tv3 = new TextView(this);
        tv3.setText("tv3");
        RelativeLayout.LayoutParams lp2 = new RelativeLayout.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        );
        lp2.addRule(RelativeLayout.BELOW, tv2.getId());
        relativeLayout.addView(tv3, lp2);

        this.setContentView(relativeLayout);
    }
}

द्वारा उत्पन्न डिफ़ॉल्ट परियोजना के साथ काम करता है android create project ...न्यूनतम बिल्ड कोड के साथ GitHub रिपॉजिटरी


1
क्या आप इस उदाहरण को 3 तक बढ़ा सकते हैं TextView? मैंने कोशिश की और तीसरा TextViewगायब है।
ज़िज़ेंग वू

7

कॉल

tv1.setId(1) 

उपरांत

tv1.setText("A");

अगर मैं पूछ सकता हूँ, क्या कारण है? मुझे एक समस्या हो रही है, लेकिन मैं ImageView के साथ-साथ TextView का उपयोग कर रहा हूं इसलिए मैं सोच रहा हूं कि कब ImageView पर .setId () कॉल करें।
जोशुआ जी

FYI करें - मैंने .setId को कॉल किया () इससे पहले कि मैं दृश्य जोड़ूं और यह काम कर गया, पता नहीं क्यों .. lol
जोशुआ जी

4

प्रयत्न:

EditText edt = (EditText) findViewById(R.id.YourEditText);
RelativeLayout.LayoutParams lp =
    new RelativeLayout.LayoutParams
    (
        LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT
    );
lp.setMargins(25, 0, 0, 0); // move 25 px to right (increase left margin)
edt.setLayoutParams(lp); // lp.setMargins(left, top, right, bottom);

1
सबसे उपयोगी उदाहरण है। धन्यवाद।
व्याचेस्लाव

2

ViewGroup.MarginLayoutParams के साथ इस दृष्टिकोण ने मेरे लिए काम किया:

RelativeLayout myLayout = (RelativeLayout) findViewById(R.id.my_layout);

TextView someTextView = ...

int leftMargin = Util.getXPos();
int topMargin = Util.getYPos();

RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
    new ViewGroup.MarginLayoutParams(
        RelativeLayout.LayoutParams.WRAP_CONTENT,
        RelativeLayout.LayoutParams.WRAP_CONTENT));

lp.setMargins(leftMargin, topMargin, 0, 0);

myLayout.addView(someTextView, lp);

1
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);

        final RelativeLayout relativeLayout = new RelativeLayout(this);
        final TextView tv1 = new TextView(this);
        tv1.setText("tv1 is here");
        // Setting an ID is mandatory.
        tv1.setId(View.generateViewId());
        relativeLayout.addView(tv1);


        final TextView tv2 = new TextView(this);
        tv2.setText("tv2 is here");

        // We are defining layout params for tv2 which will be added to its  parent relativelayout.
        // The type of the LayoutParams depends on the parent type.
        RelativeLayout.LayoutParams tv2LayoutParams = new  RelativeLayout.LayoutParams(
            RelativeLayout.LayoutParams.WRAP_CONTENT,
            RelativeLayout.LayoutParams.WRAP_CONTENT);

        //Also, we want tv2 to appear below tv1, so we are adding rule to tv2LayoutParams.
        tv2LayoutParams.addRule(RelativeLayout.BELOW, tv1.getId());

        //Now, adding the child view tv2 to relativelayout, and setting tv2LayoutParams to be set on view tv2.
        relativeLayout.addView(tv2);
        tv2.setLayoutParams(tv2LayoutParams);
        //Or we can combined the above two steps in one line of code
        //relativeLayout.addView(tv2, tv2LayoutParams);

        this.setContentView(relativeLayout);
    }

}

0

यदि आप वास्तव में मैन्युअल रूप से लेआउट करना चाहते हैं, तो मेरा सुझाव है कि एक मानक लेआउट का उपयोग न करें। यह सब अपने आप से करें, यहां एक कोटलिन उदाहरण दिया गया है:

class ProgrammaticalLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ViewGroup(context, attrs, defStyleAttr) { 
    private val firstTextView = TextView(context).apply {
        test = "First Text"
    }

    private val secondTextView = TextView(context).apply {
        text = "Second Text"
    }

    init {
        addView(firstTextView)
        addView(secondTextView)
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        // center the views verticaly and horizontaly
        val firstTextLeft = (measuredWidth - firstTextView.measuredWidth) / 2
        val firstTextTop = (measuredHeight - (firstTextView.measuredHeight + secondTextView.measuredHeight)) / 2
        firstTextView.layout(firstTextLeft,firstTextTop, firstTextLeft + firstTextView.measuredWidth,firstTextTop + firstTextView.measuredHeight)

        val secondTextLeft = (measuredWidth - secondTextView.measuredWidth) / 2
        val secondTextTop = firstTextView.bottom
        secondTextView.layout(secondTextLeft,secondTextTop, secondTextLeft + secondTextView.measuredWidth,secondTextTop + secondTextView.measuredHeight)
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { 
        // just assume we`re getting measured exactly by the parent
        val measuredWidth = MeasureSpec.getSize(widthMeasureSpec)
        val measuredHeight = MeasureSpec.getSize(heightMeasureSpec)

        firstTextView.measures(MeasureSpec.makeMeasureSpec(meeasuredWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))
        secondTextView.measures(MeasureSpec.makeMeasureSpec(meeasuredWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED))

        setMeasuredDimension(measuredWidth, measuredHeight)
    }
}

इससे आपको अंदाजा हो सकता है कि यह कैसे काम कर सकता है

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