Я досліджував цю проблему, посилаючись на документи LayoutInflater та встановлюючи невеликий зразок демонстраційного проекту. Наступні підручники показують, як динамічно заповнити макет за допомогою LayoutInflater
.
Перш ніж ми розпочнемо, подивіться, як LayoutInflater.inflate()
виглядають параметри:
- ресурс : ідентифікатор для завантаження ресурсу макета XML (наприклад,
R.layout.main_page
)
- root : Необов'язковий вигляд бути батьком згенерованої ієрархії (якщо
attachToRoot
є true
), або ж просто об'єктом, який надає набір LayoutParams
значень для кореня повернутої ієрархії (якщо attachToRoot
є false
.)
attachToRoot : чи слід приєднати завищену ієрархію до кореневого параметра? Якщо false, root використовується лише для створення правильного підкласу LayoutParams
для подання кореня у XML.
Повернення : Кореневий вид завищеної ієрархії. Якщо корінь був поставлений і attachToRoot
є true
, це корінь; інакше це корінь завищеного файлу XML.
Тепер про макет і зразок зразка.
Основний макет ( 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>
Доданий у цей контейнер окремий TextView, видно як маленький червоний квадрат, якщо параметри компонування успішно застосовані з 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" />
Тепер LayoutInflater
використовується з декількома варіантами параметрів виклику
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);
}
}
Фактичні результати зміни параметрів задокументовані в коді.
СИНОПИС: Виклик LayoutInflater
без вказівки кореня призводить до надутого виклику, ігноруючи параметри компонування з XML. Виклик надути коренем не рівним null
і attachRoot=true
не завантажує параметри макета, але повертає кореневий об'єкт знову, що запобігає подальшим змінам макета для завантаженого об'єкта (якщо ви не зможете знайти його за допомогою findViewById()
). Конвенція про дзвінки, яку ви, швидше за все, хотіли б використати, є такою:
loadedView = LayoutInflater.from(context)
.inflate(R.layout.layout_to_load, parent, false);
Щоб вирішити проблеми з компонуванням , настійно рекомендується інспектор макета .