রিলেটিভলআউট প্রোগ্রামে ভিউগুলি কীভাবে রাখবেন?


234

আমি নিম্নলিখিত প্রোগ্রামটিমেটিকভাবে অর্জন করার চেষ্টা করছি (এক্সএমএলের মাধ্যমে ঘোষণার পরিবর্তে):

<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);

হালনাগাদ:

ধন্যবাদ, ট্রিউক আমি সাধারণ দিকটি বুঝতে পারি, তবে এটি এখনও কাজ করে না - "বি" "এ" কে ওভারল্যাপ করে। আমি কি ভুল করছি?

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);

আপনার কোডের নমুনায়, আপনি আসলে রিলেটিভলআউট.বিলো, টিভি 1.getId () এর নিয়মটি যুক্ত করছেন না;
ত্রিস্তান ওয়ার্নার-স্মিথ

48
আপনার সন্তানের ভিউগুলিতে আপনাকে আইডি সরবরাহ করতে হবে: tv1.setId (1); tv2.setId (2); মূল মতামতগুলি স্বয়ংক্রিয়ভাবে শিশুদের একটি আইডি দেখায় না এবং কোনও আইডির জন্য ডিফল্ট মান NO_ID নয়। আইডির ভিউয়ারিয়ালি ভিউতে অনন্য হতে হবে না - সুতরাং 1, 2, 3, ইত্যাদি সমস্ত ব্যবহার করার জন্য সূক্ষ্ম মান - এবং আপনার অবশ্যই এগুলি আপেক্ষিক ল্যাঙ্গআউটে কাজ করার জন্য ব্যবহার করতে হবে।
সেকায়স্টাইন

উত্তর:


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 টি যুক্ত করা উচিত It এটি সেটআইডি (ইনট) ব্যবহারের জন্য উপযুক্ত একটি মান উত্পন্ন করে। এই মানটি আর.আইডি-র জন্য উপযুক্তভাবে তৈরির সময় আইডি মানগুলির সাথে সংঘর্ষ করবে না। উদাহরণ: টিভি [l_idx] .setId (View.generateViewId ());
অ্যান্ড্রুব্লুম 13

এই উত্তরটি খুব খারাপভাবে লেখা হয়েছে। লিনিয়ার বিন্যাসের জন্য রিলেশনাল লেআউট প্যারামিটারগুলি ব্যবহার করার পিছনে যুক্তি কী? এবং কেন আপনি প্যারেন্ট ভিউতে লিনিয়ার লেআউট যুক্ত করছেন?
pcodex

আরে @ প্রব, এই উত্তরটি এখন 9 বছরের পুরানো। আজকের প্রয়োজনের জন্য উত্তরটি কীভাবে উন্নত করা যেতে পারে সে সম্পর্কে আপনার যদি কিছু ইতিবাচক প্রতিক্রিয়া থাকে তবে দয়া করে সম্পাদনা বোতামটি চাপুন এবং এটি সুপারিশ করুন Tr
ত্রিস্তান ওয়ার্নার-স্মিথ

60

দীর্ঘ গল্প সংক্ষিপ্তভাবে কাটা: আপেক্ষিক বিন্যাসের সাহায্যে আপনি বিন্যাসের অভ্যন্তরে উপাদান স্থাপন করুন।

  1. একটি নতুন রিলেটিভলআউট.লায়আউটপ্যারাম তৈরি করুন

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

    (যাই হোক না কেন ... পিতামাতা বা মোড়ানো বিষয়বস্তু পূরণ করুন, আপনার অবশ্যই যদি নিখুঁত সংখ্যা, বা কোনও এক্সএমএল উত্সের উল্লেখ)

  2. বিধিগুলি যুক্ত করুন: বিধিগুলি পিতামাতার বা হায়ারার্কির অন্যান্য "ভাইদের" কাছে নির্দেশ করে।

    lp.addRule(RelativeLayout.BELOW, someOtherView.getId())
    lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
  3. কেবল বিন্যাসের প্যারামগুলি প্রয়োগ করুন: এটি করার সবচেয়ে 'স্বাস্থ্যকর' উপায়টি হ'ল:

    parentLayout.addView(myView, lp)

নজর রাখুন : লেআউট কলব্যাকগুলি থেকে বিন্যাস পরিবর্তন করবেন না। এটি করতে লোভনীয় কারণ কারণ যখন ভিউগুলি তাদের আসল আকার পায়। তবে সেক্ষেত্রে অপ্রত্যাশিত ফলাফল প্রত্যাশিত।


আমার কোনও ধারণাগুলি ছিল না যে আপনি কোনও ভিউতে প্যারাম সেট করতে পারেন এবং এর পিতামাতার সাথে একটি ভিউ যুক্ত করতে পারেন কোডের এক লাইনে (দেখুন parentLayout.addView(myView, lp) দেখুন। আমি সবসময় কোডের দুটি লাইনে এটি করেছি। ধন্যবাদ!
ম্যাট

এটি আমার পক্ষে কাজ করেছে এবং অনেক সাহায্য করেছে, তবে কি কোনও কিছুর নীচে সন্তানের সারিবদ্ধ করার এবং তারপরে সেই সন্তানের জন্য উপরের মার্জিনটি নির্ধারণ করার কোনও উপায় আছে? অথবা যে জিনিসটি নীচে রয়েছে তার জন্য আমি নীচে মার্জিনটি সেট করতে পারি এবং এটি কি সঠিকভাবে সামঞ্জস্য করবে?
জ্যাকব ভার্নার

অবশ্যই আছে। আপনি মার্জিনগুলি সেট করতে পারেন (দুর্ভাগ্যক্রমে, প্রোগ্রামেটিক এপিআই XML এর মতো স্বাচ্ছন্দ্যযুক্ত নয়) সেটমার্গিনস (বাম, উপরে, ডান, নীচে) দিয়ে। এটি লেআউটপ্যারামগুলিতে। নোট করুন যে প্যাডিংটি ভিউয়ের সম্পত্তি, বিন্যাসের প্যারামগুলিতে নয়।
মায়মান

29

এই সমস্যাটি সহ মাত্র 4 ঘন্টা অতিবাহিত করেছেন। অবশেষে বুঝতে পেরেছি যে আপনাকে অবশ্যই ভিডি আইডি হিসাবে শূন্য ব্যবহার করা উচিত নয় । আপনি ভাববেন যে এটি কোনও NO_ID == -1 হিসাবে অনুমোদিত, তবে আপনি যদি নিজের দৃষ্টিতে এটি দেন তবে জিনিসগুলি হায়াওয়াইয়ারে ঝুঁকবে ...


2
আমি একই দেখতে। আমি এপিআই 7 ব্যবহার করছি, এবং জাভাডোকটি দেখছি যে সেটআইডিডি (ইন্ট) দেখায় যে আইডিটি ইতিবাচক পূর্ণসংখ্যা হওয়া উচিত। এটি এমন কিছু যা কোডে প্রয়োগ করা উচিত, ডক্সে কেবল মন্তব্য করা নয়। বিকাশকারী.অ্যান্ড্রয়েড.
com

@ ওআইআরএম অ্যান্ড্রয়েড একটি জগাখিচুড়ি
স্পেসমুনকি

আপনি সম্ভবত আমাকে বেশিরভাগ সময় সাশ্রয় করেছেন। ধন্যবাদ!
rjr- অ্যাপস

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");

যদি আমি জিজ্ঞাসা করতে পারি, কারণ কি? আমার একটি সমস্যা হচ্ছে তবে আমি ইমেজভিউ পাশাপাশি টেক্সটভিউ ব্যবহার করছি তাই আমি ভাবছি কখন ইমেজভিউতে .setId () কল করতে পারি।
জোশুয়া জি

এফওয়াইআই - আমি ভিউ যুক্ত করার আগেই .setId () ডেকেছিলাম এবং এটি কাজ করেছিল, কেন কোন ধারণা নেই .. হ্যাঁ
জোশুয়া জি

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

ভিউগ্রুপের সাথে এই দৃষ্টিভঙ্গি.মার্গিনলাউটপ্যারামগুলি আমার পক্ষে কাজ করেছে:

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)
    }
}

এটি আপনাকে কীভাবে কাজ করতে পারে তা ধারণা দেয়

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.