Android - динамічно додавання переглядів у режим перегляду


148

У мене макет для перегляду -

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="0px"
    android:orientation="vertical">

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_header"
        style="@style/Home.ListHeader" />

    <TextView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_none"
        android:visibility="gone"
        style="@style/TextBlock"
        android:paddingLeft="6px" />

    <ListView 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/items_list" />


</LinearLayout>

Те, що я хочу зробити, - це моя основна діяльність з таким компонуванням

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="0px"
    android:id="@+id/item_wrapper">
</LinearLayout>

Я хочу переглядати свою модель даних і вводити декілька подань, що складаються з першого макета в основний макет. Я знаю, що я можу це зробити, будуючи елементи керування повністю в коді, але мені було цікаво, чи існує спосіб динамічно будувати представлення даних, щоб я міг продовжувати використовувати макет, а не ставити все в код.


Ви можете перевірити відповідь на це stackoverflow.com/questions/3995215/…
Розкажіть, як

Відповіді:


230

Використовуйте, LayoutInflaterщоб створити подання на основі шаблону макета, а потім введіть його у подання, де вам це потрібно.

LayoutInflater vi = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = vi.inflate(R.layout.your_layout, null);

// fill in any details dynamically here
TextView textView = (TextView) v.findViewById(R.id.a_text_view);
textView.setText("your text");

// insert into main view
ViewGroup insertPoint = (ViewGroup) findViewById(R.id.insert_point);
insertPoint.addView(v, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));

Можливо, вам доведеться відрегулювати індекс, куди ви хочете вставити представлення.

Крім того, встановіть LayoutParams відповідно до того, як ви хочете, щоб він помістився у батьківському поданні. наприклад, з FILL_PARENTабо MATCH_PARENTтощо


2
саме там ви хочете розмістити динамічно генерований макет у своєму головному вікні. це біт, який ви повинні заповнити з власного коду.
Марк Фішер

Для тих, хто хоче це спробувати зараз - інфляція макета, отримана, як показано у першому рядку, все ще вирішується, але, здається, не працює, замість цього використовуєтьсяgetLayoutInflater()
Брендан

2
Використовуйте LayoutInflater vi = getLayoutInflater();з діяльності, щоб зберегти тему діяльності, яку ви не отримаєте інакше.
akarthik10

1
@MrG Ви повинні поставити окреме запитання щодо SO. Це питання стосується того, як динамічно створювати представлення даних, а не про фрагменти.
Марк Фішер

2
@Arsh Якщо у вас є нове запитання та конкретна проблема, поставте окреме запитання SO, у якому детально описуєте, який код ви спробували, який не працює, а не коментувати тут.
Марк Фішер

36

Дивіться LayoutInflaterклас.

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup parent = (ViewGroup)findViewById(R.id.where_you_want_to_insert);
inflater.inflate(R.layout.the_child_view, parent);

як додати onClicklistener до переглядів людей, які були завищені. Надайте фрагмент
Sagar Devanga

20

Схоже, що ви дійсно хочете, щоб ListView зі спеціальним адаптером надував вказаний макет. Використовуючи ArrayAdapter та метод, notifyDataSetChanged()ви маєте повний контроль над генеруванням та відображенням Views.

Погляньте на ці підручники


14

Щоб зробити відповідь @Mark Fisher більш зрозумілою, вкладене подання, що надувається, має бути файлом XML у папці макета, але без макета (ViewGroup), як LinearLayout тощо. Мій приклад:

res / layout / my_view.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/i_am_id"
    android:text="my name"
    android:textSize="17sp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"/>

Тоді точкою вставки має бути такий макет, як LinearLayout:

res / layout / activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/aaa"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/insert_point"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </LinearLayout>

</RelativeLayout>

Тоді код повинен бути

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_shopping_cart);

    LayoutInflater inflater = getLayoutInflater();
    View view = inflater.inflate(R.layout.my_view, null);
    ViewGroup main = (ViewGroup) findViewById(R.id.insert_point);
    main.addView(view, 0);
}

Причина, коли я публікую цю дуже подібну відповідь, полягає в тому, що, коли я намагався реалізувати рішення Марка, я застряг у тому, який XML-файл слід використовувати для insert_point та дочірнього представлення. По-перше, я використовував макет у дитячому представленні, і він зовсім не працював, на що мені знадобилося кілька годин. Тож сподіваюся, що моє дослідження може заощадити час інших.


@York Yang, як я можу отримати ідентифікатори vies, додані тут, якщо ми додамо більше, ніж один вид, використовуючи для циклу.
Рахул

5
// Parent layout
LinearLayout parentLayout = (LinearLayout)findViewById(R.id.layout);

// Layout inflater
LayoutInflater layoutInflater = getLayoutInflater();
View view;

for (int i = 1; i < 101; i++){
    // Add the text layout to the parent layout
    view = layoutInflater.inflate(R.layout.text_layout, parentLayout, false);

    // In order to get the view we have to use the new view with text_layout in it
    TextView textView = (TextView)view.findViewById(R.id.text);
    textView.setText("Row " + i);

    // Add the text view to the parent layout
    parentLayout.addView(textView);
}

1
Хоча цей фрагмент коду може бути вирішенням, зокрема пояснення дійсно допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду.
іві

Як я можу отримати ідентифікатори різних поглядів, створених за допомогою For Loop.
Рахул
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.