Soru RelativeLayout'ta görünümler nasıl programlanır?


Aşağıdakileri program aracılığıyla (XML aracılığıyla bildirimde bulunmak yerine) elde etmeye çalışıyorum:

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

Başka bir deyişle, ikincisini nasıl yapabilirim TextView ilkinin altında görünür, ancak bunu kodda yapmak istiyorum:

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

Güncelleştirme:

Sağol, TreeUK. Genel yönü anlıyorum, ama hala çalışmıyor - "B" "A" ile örtüşüyor. Neyi yanlış yapıyorum?

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

219
2018-02-21 09:04


Menşei


Kod örneğinizde, aslında RelativeLayout.BELOW, tv1.getId (); - Tristan Warner-Smith
ID'leri çocuğunuzun görüşlerine bildirmeniz gerekir: tv1.setId (1); tv2.setId (2); Ana görünümler alt görünümleri otomatik olarak bir Kimlik alamaz ve Kimlik için varsayılan değer NO_ID'dir. Id'in hidayet görünümünde benzersiz olması gerekmez - yani 1, 2, 3, vb. Kullanmanız gereken tüm iyi değerlerdir - ve bunları RelativeLayout'ta çalışmak için göreli demirleme için kullanmanız gerekir. - sechastain


Cevaplar:


Birlikte yapabildiğim kadarıyla, LayoutParams kullanarak görünümü eklemelisiniz.

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

Tüm krediler, tüm öğelerinizi programatik olarak konumlandırmak için ids'leri onlara atamanız gerekir.

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

Sonra addRule(RelativeLayout.RIGHT_OF, tv1.getId());


190
2018-02-21 11:57



AMAN TANRIM! Bu setId () bir "uzun" süre için benim sorunumdu - maclir
Benim durumumda, bir alt görüntünün kimliklerini belirlemenin yanı sıra, alt görünüme alt görünüm eklemek ve diğer alt görüntünün kurallarını ayarlamadan önce childview'de requestLayout () öğesini çağırmak, işleri gerçekleştirdi. Umarım bu birisine yardım eder - 2cupsOfTech
Birinin hala bunu takip etmesi durumunda: Bir koleksiyon koleksiyonuna sahip olduğumda tek tek ekliyorum ve bir öğenin göründüğü görünümlerden biri olduğundan emin olamam. below zaten eklendi, hala doğru şekilde oluşturulduğundan nasıl emin olunur? Anladığım kadarıyla addView düzenin yeniden oluşturulmasına neden olur, bu nedenle henüz bir eklenmiş olmayan bir öğe için yaparsam, o kimliğe sahip öğe henüz mevcut olmadığı için kilitlenir. - Megakoresh
set (id) generateViewId () ile birlikte kullanılmalıdır. API level 17'de eklendi. setId (int) 'de kullanmak için uygun bir değer üretir. Bu değer, R.id için aapt tarafından yapım zamanında üretilen ID değerleri ile çarpışmayacaktır. Örnek: tv [l_idx] .setId (View.generateViewId ()); - AndrewBloom


Uzun hikayeyi kısaltın: Göreceli düzende, öğeleri yerleşimin içinde konumlandırırsınız.

  1. yeni bir RelativeLayout.LayoutParams oluştur

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

    (ne olursa olsun ... ebeveyni doldurun veya içeriği sarın, gerekiyorsa mutlak sayıları veya bir XML kaynağına bakın)

  2. Kural ekle: Kurallar ebeveyn veya hiyerarşideki diğer "kardeşler" ile ilgilidir.

    lp.addRule(RelativeLayout.BELOW, someOtherView.getId())
    lp.addRule(RelativeLayout.ALIGN_PARENT_LEFT)
    
  3. Sadece düzen paramslarını uygulayın: Bunu yapmanın en 'sağlıklı' yolu:

    parentLayout.addView(myView, lp)
    

Dikkat et: Düzen düzeni geri aramalardan değiştirmeyin. Bunu yapmak caziptir çünkü görüşlerin gerçek boyutlarını alması budur. Ancak, bu durumda beklenmedik sonuçlar bekleniyor.


58
2018-01-04 09:36



Bir görünüme paramik değerler koyabildiğin ve bir adaya bir Görünüm ekleyebileceğin hiçbir fikrim yoktu.parentLayout.addView(myView, lp). Bunu her zaman iki satır kodla yaptım. Teşekkür ederim! - Matt
unexpected results are expected lol - Mike Baxter
Bu benim için çalıştı ve çok yardımcı oldu, ama çocuğu bir şeyin altına hizalamanın ve sonra o çocuğun için yukarıdaki sınırı ayarlamanın bir yolu var mı? Ya da aşağıdaki marjı aşağıda olduğu gibi ayarlayabilir ve doğru şekilde ayarlayabilir miyim? - VarnerBeast14
Tabii ki var. SetMargins (sol, üst, sağ, alt) ile marjları (ne yazık ki, programatik API XML kadar rahat değildir) ayarlayabilirsiniz. LayoutParams'da. Dolgu işleminin, mizanpajın değil, görünümün bir özelliği olduğunu unutmayın. - Meymann
Bu cevap açıktır. - Don Larynx


Sadece bu problemle 4 saat geçirdim. Sonunda fark ettin ki görüntüleme kimliği olarak sıfır kullanmamalıdır. NO_ID == -1 olarak izin verildiğini düşünürdünüz, ama eğer görüşünüze verirseniz, şeyler haywire gitmeye eğilimlidir ...


29
2017-09-29 16:26



Ben de aynısını görüyorum. API 7 kullanıyorum ve javadoc'u görüntülediğimde, setID (int), kimliğin pozitif bir tam sayı olması gerektiğini bildiriyor. Bu, kodlarda zorlanması gereken bir şeydir, sadece dokümanlar içinde yorumlanmaz. developer.android.com/reference/android/view/... - OYRM
@OYRM Android bir karışıklıktır - Space monkey
Muhtemelen bana bir zaman TON'u kurtardın. Teşekkürler! - nope4561759
Kıçımı kurtardın, teşekkürler. - hornet2319


aramak

tv1.setId(1) 

sonra

tv1.setText("A");

5
2018-03-23 12:15



Eğer sorabilirsem, sebebi nedir? Bir sorun yaşıyorum ama ImageView yanı sıra ImageView .setId () çağırmak için merak ediyorum. - b729sefc
FYI - Ben viewset eklemeden önce ve hemen çalıştı, hiçbir fikrim neden ..setId () denir .. lol - b729sefc


Android 22 minimum çalıştırılabilir örnek

enter image description here

Kaynak:

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

Tarafından oluşturulan varsayılan proje ile çalışır android create project .... Minimum yapı koduyla GitHub deposu.


5
2018-02-02 21:43



Bu örneği 3'e genişletebilir misiniz TextView? Denedim ve üçüncü TextView kayıp. - Zizheng Wu
@ZizhengWu Yönetdim, kod düzenledi. - Ciro Santilli 新疆改造中心 六四事件 法轮功


Deneyin:

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

3
2017-12-13 09:25



Güzel en kullanışlı örnek. Teşekkürler. - Vyacheslav


ViewGroup.MarginLayoutParams ile bu yaklaşım benim için çalıştı:

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

2
2017-11-11 20:16





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

}

1
2017-11-07 19:14