web-dev-qa-db-fra.com

Android - Ajout dynamique de vues dans la vue

J'ai une mise en page pour une vue -

<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>

Ce que je veux faire, c'est dans mon activité principale avec un layout comme celui-ci

<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>

Je souhaite parcourir mon modèle de données et injecter plusieurs vues, dont la première présentation, dans la présentation principale. Je sais que je peux le faire en construisant les contrôles complètement dans le code, mais je me demandais s'il existait un moyen de créer de manière dynamique les vues afin que je puisse continuer à utiliser une présentation au lieu de tout mettre dans le code.

139
Josh

Utilisez la LayoutInflater pour créer une vue basée sur votre modèle de présentation, puis insérez-la dans la vue où vous en avez besoin.

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));

Vous devrez peut-être ajuster l'index où vous souhaitez insérer la vue.

De plus, définissez les LayoutParams selon la manière dont vous souhaitez qu'il s'adapte à la vue parent. par exemple. avec FILL_PARENT ou MATCH_PARENT, etc.

215
Mark Fisher

Voir la classe 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);
34
Gabriel Negut

Cela ressemble à ce que vous voulez vraiment d'un ListView avec un adaptateur personnalisé pour gonfler la présentation spécifiée. En utilisant ArrayAdapter et la méthode notifyDataSetChanged(), vous avez le contrôle total sur la génération et le rendu des vues.

Jetez un coup d'œil à ces tutoriels

19
Aleadam

Pour que la réponse de @Mark Fisher soit plus claire, la vue insérée gonflée doit être un fichier xml situé dans le dossier de présentation, mais sans mise en forme (ViewGroup) comme LinearLayout, etc. Mon exemple:

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"/>

Ensuite, le point d’insertion doit être une présentation semblable à 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>

Ensuite, le code devrait être

@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);
}

La raison pour laquelle je publie cette réponse très similaire est que, lorsque j'ai essayé d'implémenter la solution de Mark, je me suis retrouvé coincé sur le fichier xml que je devrais utiliser pour insert_point et la vue enfant. J'ai d'abord utilisé la présentation dans la vue des enfants et cela ne fonctionnait absolument pas, ce qui m'a pris plusieurs heures à comprendre. J'espère donc que mon exploration pourra faire gagner du temps aux autres.

11
York Yang
// 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
Tienanhvn