Zbadałem ten problem, odwołując się do dokumentacji LayoutInflater i konfigurując mały przykładowy projekt demonstracyjny. Poniższe samouczki pokazują, jak dynamicznie wypełniać układ przy użyciu LayoutInflater
.
Zanim zaczniemy, zobacz, jak LayoutInflater.inflate()
wyglądają parametry:
- zasób : identyfikator zasobu układu XML do załadowania (np.
R.layout.main_page
)
- root : opcjonalny widok, który ma być elementem nadrzędnym wygenerowanej hierarchii (jeśli
attachToRoot
jest true
), lub po prostu obiekt, który dostarcza zestaw LayoutParams
wartości dla katalogu głównego zwracanej hierarchii (jeśli attachToRoot
jest false
).
attachToRoot : czy zawyżona hierarchia powinna być dołączona do parametru głównego? Jeśli false, root jest używany tylko do tworzenia poprawnej podklasy LayoutParams
dla widoku głównego w XML.
Zwroty : widok główny zawyżonej hierarchii. Jeśli podano root i attachToRoot
jest true
, to jest to root; w przeciwnym razie jest to katalog główny zawyżonego pliku XML.
Teraz przykładowy układ i kod.
Główny układ ( 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>
Do tego kontenera dodano oddzielny TextView, 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 LayoutInflater
jest używany z kilkoma odmianami parametrów połączeń
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.
SKŁADNIA: Wywołanie LayoutInflater
bez określania głównych prowadzi do zawyżenia wywołania ignorując parametry układu z XML. Wywołanie inflate z elementem głównym nie jest równe null
i attachRoot=true
ładuje parametry układu, ale ponownie zwraca obiekt główny, co zapobiega dalszym zmianom układu w załadowanym obiekcie (chyba że można go znaleźć za pomocą findViewById()
). Dlatego najprawdopodobniej najprawdopodobniej chciałbyś użyć tej konwencji:
loadedView = LayoutInflater.from(context)
.inflate(R.layout.layout_to_load, parent, false);
Aby pomóc w rozwiązaniu problemów z układem, wysoce zalecany jest Inspektor układu .