Android, использующий макеты в качестве шаблона для создания нескольких экземпляров макета

#android #xml #layout #reusability

#Android #xml #макет #возможность повторного использования

Вопрос:

Хорошо, итак, я понимаю, как использовать тег include, но я столкнулся с проблемой.

По сути, я хочу иметь макет, определенный в xml, в котором есть пара TextView s и an ImageView . Затем я хочу выполнить итерацию по массиву и заполнить поля в макете xml в зависимости от того, что находится в массиве (который заполняется во время выполнения). Таким образом, создается несколько копий макета xml и заполняются поля уникальными данными. Теперь я понятия не имею, как вы можете повторно использовать это LinearLayout таким образом, поскольку TextView s и ImageView s внутри него имеют постоянный идентификатор, и мне нужно сделать несколько копий этого макета.

Есть ли какой-нибудь способ раздуть ресурс, а затем сделать его копию, которая будет работать … Так

 LinearLayout one = new LinearLayout(inflater.inflate(R.layout.home, container, false));
 

^ К сожалению, такого конструктора нет.

Единственный другой способ — сделать все это программно, но я бы предпочел иметь свойства представлений и LinearLayout в xml, а не в коде. Как будто я хочу LinearLayout , чтобы это был шаблон, который вы можете копировать, я думаю… На самом деле не уверен, возможно ли это.

Ответ №1:

Вы можете легко это сделать, вам просто нужно разбить его. Сначала вы загружаете макет, в который хотите вставить свои динамические представления. Затем вы раздуваете свой вложенный просмотр и заполняете его столько раз, сколько вам нужно. Затем вы добавляете представление в свой родительский макет и, наконец, устанавливаете представление содержимого действия в родительский вид.

Вот пример:

 LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LinearLayout parent = (LinearLayout) inflater.inflate(R.layout.main, null);

for (int i = 0; i < 3; i  ) {
    View custom = inflater.inflate(R.layout.custom, null);
    TextView tv = (TextView) custom.findViewById(R.id.text);
    tv.setText("Custom View "   i);
    parent.addView(custom);
}

setContentView(parent);
 

вот main.xml файл, который я вставляю в:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

</LinearLayout>
 

и вот custom.xml представление, которое я раздуваю, заполняю и динамически вставляю:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

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

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_launcher" />

        <TextView
            android:id="@ id/text"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>
 

Комментарии:

1. Большое спасибо! Вот и все… Я думаю, мне нужно разобраться с различными вызовами inflate(….).

2. Спасибо! Хороший пример inflater тоже!

3. Есть ли способ просто скопировать макет во время цикла вместо использования inflator.inflate() на каждой итерации? Мне кажется, что раздувание очень дорого по сравнению с простым копированием.

4. да, это оно. Спасибо

5. Любой способ использовать это во фрагменте? getActivity().setContentView(родитель все портит, но я вижу результат. Также я, кажется, часто получаю эту ошибку после реализации этого android.content.res.Resources $NotFoundException: идентификатор строкового ресурса # 0x7f0e00a2

Ответ №2:

Для тех, кто все еще ищет аналогичное решение, по-видимому, вы также можете использовать include непосредственно в xml и при этом иметь возможность ссылаться на них в коде:

 LinearLayout row1 = (LinearLayout) findViewById(R.id.row1)
TextView text1 = row1.findViewById(R.id.text);

LinearLayout row2 = (LinearLayout) findViewById(R.id.row2)
TextView text2 = row2.findViewById(R.id.text);
 

Источник: Ромен Гай