Dlaczego LayoutInflater ignoruje parametry układu szerokość i wysokość układu, które podałem?

Miałem poważne problemy z uruchomieniem Layoutinflatora, tak jak inni ludzie: Jak używać layoutinflator do dodawania widoków w czasie wykonywania?.

Dlaczego LayoutInflater ignoruje parametry układu, które podałem? Np. dlaczego wartości layout_width i {[1] } z moich zasobów XML nie są honorowane?

Author: Community, 2011-02-17

3 answers

Zbadałem ten problem, odwołując się do layoutinflater docs i tworząc mały przykładowy projekt demonstracyjny. Poniższe samouczki pokazują, jak dynamicznie wypełniać układ za pomocą LayoutInflater.

Zanim zaczniemy zobacz jak wyglądają LayoutInflater.inflate() parametry:

  • resource : ID dla zasobu układu XML do załadowania (np., R.layout.main_page)
  • root: opcjonalny widok, który ma być rodzicem Wygenerowanej hierarchii (Jeśli attachToRoot to true), lub po prostu obiekt, który dostarcza zestaw wartości LayoutParams dla roota zwracanej hierarchii (Jeśli attachToRoot to false.)
  • AttachToRoot : czy napompowana hierarchia powinna być dołączona do parametru root? Jeśli false, root jest używany tylko do utworzenia poprawnej podklasy LayoutParams dla widoku root w XML.

  • Returns: główny widok zawyżonej hierarchii. Jeśli root został dostarczony i attachToRoot jest true, jest to root; w przeciwnym razie jest to root nadmuchanego pliku XML.

Teraz przykładowy układ i Kod.

Układ główny (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>

Dodany do tego kontenera jest oddzielny widok tekstu, widoczny jako mały czerwony kwadrat, jeśli parametry układu zostały pomyślnie zastosowane z XML (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" />

Teraz {[4] } jest używany z kilkoma wariantami parametrów wywołania

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

Rzeczywiste wyniki zmian parametrów są udokumentowane w kodzie.

Streszczenie: Wywołanie LayoutInflater bez podania roota prowadzi do nadmuchania wywołania ignorującego parametry układu z XML. Wywołanie inflate z parametrami root nie równymi null i attachRoot=true ładuje parametry układu, ale zwraca obiekt root ponownie, co zapobiega dalszym zmianom układu w załadowanym obiekcie(chyba że można go znaleźć za pomocą findViewById()). Konwencję wywołującą, której najprawdopodobniej chciałbyś użyć, jest zatem ta: {]}

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

Aby pomóc w problemach z układem, Inspektor układu jest wysoce polecam.

 386
Author: andig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-29 01:50:25

Anddig jest poprawne, że częstym powodem ignorowania layoutinflater będzie fakt, że root nie został określony. Wiele osób uważa, że można przekazać w null dla root. Jest to dopuszczalne w kilku scenariuszach, takich jak okno dialogowe, w którym nie masz dostępu do roota w momencie tworzenia. Dobrą zasadą do naśladowania jest jednak to, że jeśli masz korzeń, daj go LayoutInflater.

Napisałem dogłębny wpis na blogu o tym, że można sprawdzić tutaj:

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

 6
Author: seanjfarrell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-19 18:26:44

Wanna add to main answer above
Próbowałem go śledzić, ale mój recycleview zaczął rozciągać każdy przedmiot na ekran
Musiałem dodać kolejną linię po napompowaniu, aby dotrzeć do celu

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

Już dodałem te paramy przez xml ale nie działa poprawnie
and with this line all is ok

 0
Author: Kirguduck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-11-08 18:30:17