LayoutInflater neden belirlediğim layout_width ve layout_height düzen parametrelerini yok sayar?


168

LayoutInflater'ın beklendiği gibi çalışmasını sağlamakta ciddi bir sorun yaşadım ve diğer insanlar da: Çalışma zamanında görünüm eklemek için layoutinflator nasıl kullanılır? .

LayoutInflater neden belirttiğim düzen parametrelerini yok sayıyor? Örneğin, neden kaynak XML'imdeki layout_widthve layout_heightdeğerleri onurlandırılmıyor?


Doğru- bu acıyor mu yoksa yanlış yer mi seçtim? Sadece sonuçlarımı paylaşacağımı düşündüm. SSS sayfasından özel olarak bahsedilmemelidir ..
andig

3
ilk sorunun son paragrafına bakınız. bir soru olarak gönderin ve ardından öğreticiyi bir cevap olarak gönderin. elbette, bu soruyu öğreticiyi cevaba yapıştırarak ve yapıştırarak düzenleyebilirsiniz. Bunu düzeltirsen oylayacağım.
bigstones

Yanıtlar:


381

LayoutInflater belgelerine atıfta bulunarak ve küçük bir örnek tanıtım projesi ayarlayarak bu sorunu araştırdım . Aşağıdaki öğreticiler kullanarak bir mizanpajın dinamik olarak nasıl doldurulacağını gösterir LayoutInflater.

Başlamadan önce hangi LayoutInflater.inflate()parametrelerin nasıl göründüğüne bakın:

  • resource : Yüklenecek bir XML mizanpaj kaynağının kimliği (ör. R.layout.main_page)
  • root : Oluşturulan hiyerarşinin üst attachToRootöğesi (isteğe bağlı) veya isteğe bağlı görünüm , döndürülen hiyerarşinin kökü (eğer ise ) için truebir dizi LayoutParamsdeğer sağlayan bir nesne olabilir .attachToRootfalse
  • attachToRoot : Şişirilmiş hiyerarşinin root parametresine eklenip eklenmeyeceği ? False olursa, root yalnızca XML'deki LayoutParamskök görünüm için doğru alt sınıfını oluşturmak için kullanılır .

  • Döndürür : Şişirilmiş hiyerarşinin kök görünümü. Kök sağlanmışsa ve attachToRootise true, bu köktür; aksi takdirde şişirilmiş XML dosyasının köküdür.

Şimdi örnek düzen ve kod için.

Ana düzen ( main.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</LinearLayout>

Bu kapsayıcıya, düzen parametreleri XML'den başarıyla uygulandığında küçük kırmızı kare olarak görünen ayrı bir TextView eklenir red.xml:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="25dp"
    android:layout_height="25dp"
    android:background="#ff0000"
    android:text="red" />

Şimdi LayoutInflaterbirkaç çağrı parametresi varyasyonu ile kullanılır

public class InflaterTest extends Activity {

    private View view;

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);
      ViewGroup parent = (ViewGroup) findViewById(R.id.container);

      // result: layout_height=wrap_content layout_width=match_parent
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view);

      // result: layout_height=100 layout_width=100
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view, 100, 100);

      // result: layout_height=25dp layout_width=25dp
      // view=textView due to attachRoot=false
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, false);
      parent.addView(view);

      // result: layout_height=25dp layout_width=25dp 
      // parent.addView not necessary as this is already done by attachRoot=true
      // view=root due to parent supplied as hierarchy root and attachRoot=true
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, true);
    }
}

Parametre varyasyonlarının gerçek sonuçları kodda belgelenmiştir.

ÖZET: çağrılması LayoutInflaterXML düzen parametreleri göz ardı şişirmek çağrısına kök yol belirtmeden. Kök ile şişirmek çağrıldığında eşit değildir nullve attachRoot=truedüzen parametrelerini yükler, ancak kök nesneyi yeniden döndürerek yüklenen nesnede daha fazla düzen değişikliği yapılmasını önler (kullanarak bulamazsanız findViewById()). Büyük olasılıkla kullanmak isteyeceğiniz çağrı kuralı şu şekildedir:

loadedView = LayoutInflater.from(context)
                .inflate(R.layout.layout_to_load, parent, false);

Düzen sorunlarına yardımcı olması için Düzen Denetçisi önemle tavsiye edilir.


20
Mükemmel cevap. 3 yıldır Android'de çalışıyor ve sayıyorum ve yine de bundan öğrenecek bir şeyler vardı.
Reuben Scratton

Merhaba aynı şeyi R.layout ile şişirmek yerine java kodu ile yapmanın herhangi bir yolu var. çünkü düzenim yok. Java kodu ile görünüm oluşturduk ve 300 kez aynı görünümü eklemek istiyor.
Raj

1
@andig: Activitybir alt sınıfıdır Contextve cevabım örnekler kapsamındadır Activityyüzden yerini daha basit hale getirmek için, getBaseContext()birlikte this, bu cevabın uğruna, bu eşdeğer olarak.
Marcin Orlowski

5
kapsayıcıda layout_width ve layout_height "match_parent" olarak ayarlanmış; yorumda "// sonuç: layout_height = wrap_content layout_width = match_parent" yazıyor. Ben eksik mi?
Marian Paździoch

1
Araştırma yaptığınız ve sonuçları paylaştığınız için teşekkürler! Ayrıca, Marian'ın sorusunu ikinci olarak ele aldım.
LarsH

5

andig, LayoutInflater'ın layout_params öğenizi yoksaymasının yaygın bir nedeninin, bir kök belirtilmediğinden kaynaklanabileceği doğrudur. Birçok insan kök için boş kalacağını düşünüyor. Bu, oluşturma sırasında köke erişiminizin olmadığı bir iletişim kutusu gibi birkaç senaryo için kabul edilebilir. Bununla birlikte, takip edilmesi gereken iyi bir kural, kökünüz varsa, LayoutInflater'a vermenizdir.

Bu konuda buradan kontrol edebileceğiniz ayrıntılı bir blog yazısı yazdım:

https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/


1
This is acceptable for a few scenarios such as a dialogtüm ihtiyacım
buydu

0

yukarıdaki ana cevaba eklemek istiyorum
Takip etmeye çalıştım ama benim recyclerView
hedefe ulaşmak için şişirdikten sonra bir sonraki satır eklemek zorunda kaldım her öğeyi bir ekrana uzatmaya başladı

itemLayoutView.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));

Zaten xml ile bu params ekledim ama düzgün çalışmadı
ve bu çizgi ile tüm ok

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.