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?
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
totrue
), lub po prostu obiekt, który dostarcza zestaw wartościLayoutParams
dla roota zwracanej hierarchii (JeśliattachToRoot
tofalse
.) 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
jesttrue
, 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.
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/
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
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