Android XML Layout'ları 'Etiketi İçeriyor' Gerçekten Çalışıyor mu?


84

Android düzen dosyalarımda <include> kullanırken öznitelikleri geçersiz kılamıyorum. Hataları aradığımda, Reddedilmiş Sayı 2863'ü buldum :

"include etiketi bozuk (düzen parametrelerini geçersiz kılmak asla işe yaramaz)"

Romain, test süitlerinde ve örneklerinde bunun işe yaradığını gösterdiğinden, yanlış bir şey yapıyor olmalıyım.

Projem şu şekilde organize edildi:

res/layout
  buttons.xml

res/layout-land
  receipt.xml

res/layout-port
  receipt.xml

Buttons.xml dosyası şunun gibi bir şey içerir:

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

  <Button .../>

  <Button .../>
</LinearLayout>

Dikey ve yatay fiş.xml dosyaları şuna benzer:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

  ...

  <!-- Overridden attributes never work. Nor do attributes like
       the red background, which is specified here. -->
  <include
      android:id="@+id/buttons_override"
      android:background="#ff0000"
      android:layout_width="fill_parent"
      layout="@layout/buttons"/>

</LinearLayout>

Neyi kaçırıyorum?


Dahil etmeyi desteklenmeyen bir şekilde kullanmaya çalıştığınızda bu soruya Android geliştirici araçları tarafından başvurulur.
ThomasW

Yanıtlar:


132

Ben sadece sorunu buldum. İlk olarak, yalnızca layout_ * niteliklerini geçersiz kılabilirsiniz, böylece arka plan çalışmayacaktır. Bu belgelenmiş bir davranış ve sadece benim açımdan bir gözetim.

Gerçek sorun LayoutInflater.java'da bulunur:

// We try to load the layout params set in the <include /> tag. If
// they don't exist, we will rely on the layout params set in the
// included XML file.
// During a layoutparams generation, a runtime exception is thrown
// if either layout_width or layout_height is missing. We catch
// this exception and set localParams accordingly: true means we
// successfully loaded layout params from the <include /> tag,
// false means we need to rely on the included layout params.
ViewGroup.LayoutParams params = null;
try {
   params = group.generateLayoutParams(attrs);
} catch (RuntimeException e) {
   params = group.generateLayoutParams(childAttrs);
} finally {
   if (params != null) {
     view.setLayoutParams(params);
   }
}

<include> etiketi layout_width ve layout_height'ın ikisini de içermiyorsa, RuntimeException oluşur ve herhangi bir günlük ifadesi bile olmadan sessizce işlenir.

Çözüm, layout_ * özniteliklerinden herhangi birini geçersiz kılmak istiyorsanız, <include> etiketini kullanırken her zaman hem layout_width hem de layout_height'ı dahil etmektir.

Örneğim şu şekilde değişmeli:

<include
      android:id="@+id/buttons_override"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      layout="@layout/buttons"/>

33
Bu gülünç. Bunu asla çalıştıramadım ve hatta yükseklik ve genişlik olduğunu varsaydığım boyutları geçersiz kılmaya çalışırken hem yüksekliğe hem de genişliğe ihtiyaç duyduğundan bahsettiğini gördüm. Ancak, geçersiz kılmaya çalıştığım tek şey marj, ki bu aslında bir boyut değil. Değiştirmek istediğim tek şey layout_marginRight iken neden ikisini de, hatta herhangi birini belirtmem gerekiyor? Grrr, Android, bazen beni çok fazla sinirlendiriyorsun.
Artem Russakovskii

1
Bilginize Android Lint, hem yükseklik hem de genişlik özelliklerini geçersiz kılmıyorsanız, size bir hata verecektir (layout_width <include> etiketinde de belirtilmediği sürece Layout parametresi layout_height yok sayılır)
ikili

10

Dahil edilen tüm özelliklerin geçersiz kılınmasına izin vermek için bir geliştirme isteği gönderdim :

Bir TextViewalanın değerleri dışında iki özdeş düzenim olduğunu varsayalım . Şu anda, ya çalışma zamanında düzeni değiştirdim ya da XML'i çoğalttım.

Örneğin "merhaba" ve "dünya" değerlerine sahip iki parametreyi layout1'e geçirmek için:

<include layout="@layout/layout1a" params="textView=hello|editText=world" />

layout1a.xml:

<merge><TextView text="@param/textView"><EditText hint="@param/editText"></merge>

Alternatif bir uygulama, kapsüllemeyi bozar ve include ifadesinin aşağıdaki gibi değerleri geçersiz kılmasına izin verir:

<include layout="@layout/layout1b" overrides="@id/textView.text=hello|@id/editText.hint=world" />

layout1b.xml:

<merge><TextView id="@+id/textView"><EditText hint="@+id/editText"></merge>


1
Yeni veri bağlama öğeleri göz önüne alındığında, <include>şimdi daha da sık kullanılıyor,
çekim

1

Eclipse'de GUI oluşturucuyu kullanırken bazen android: id etiketini eklemeyi özlediğimi fark ettim. Oluşturucudan bir TextView'a, ListView düzeninde kullandığım kimliği eklediğimden (fark ettiğimde) emin olmak.

<TextView android:text="@+id/textView1"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
...

olur

<TextView android:id="@+id/textView1"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" />
...

'Yanlış' 'yanlış' yerine :) alıyorum ve iyi çalışmayı içeriyor.

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.