web-dev-qa-db-fra.com

ListView avec disposition des lignes personnalisée - Android

Je voudrais créer un Activity contenant une liste dans laquelle les lignes ont une disposition personnalisée. J'ai donc créé le list_entry_layout.xml fichier définissant la mise en page de chaque ligne de ma liste (dans mon exemple, chaque ligne doit avoir un titre et un résumé):

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical" >

    <TextView
        Android:id="@+id/list_entry_title"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:textSize="20dp" >
    </TextView>

    <TextView
        Android:id="@+id/list_entry_summary"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:textSize="10dp" >
    </TextView>

</LinearLayout>

Mon problème est que je ne sais pas comment ajouter les données à chaque ligne de la classe ListActivity. Avec l'extrait de code suivant, je peux ajouter les titres de chaque ligne:

public class MyActivity extends ListActivity 
{

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    { 

        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_activity);

        ListView listView = (ListView) findViewById(Android.R.id.list);
        String[] values = new String[] { "Android", "iPhone", "WindowsMobile",
            "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X",
            "Linux", "OS/2" };

        ArrayAdapter<String> titleAdapter = new ArrayAdapter<String>(this, R.layout.list_entry_layout, R.id.list_entry_title, values);
        // Assign adapter to ListView
        listView.setAdapter(titleAdapter);

    }
}

Pour ajouter également le résumé, comment dois-je faire?

Si j'ajoute ce code, je visualiserai les résumés et non les titres:

String[] values = new String[] { "Android_summary", "iPhone_summary", "WindowsMobile_summary", "Blackberry_summary", "WebOS_summary", "Ubuntu_summary", "Windows7_summary", "Max OS X_summary", "Linux_summary", "OS/2_summary" };
ArrayAdapter<String> summaryAdapter = new ArrayAdapter<String>(this, R.layout.list_entry_layout, R.id.list_entry_summary, values);
// Assign adapter to ListView
listView.setAdapter(summaryAdapter);

Voici le résultat que j'aimerais obtenir:

enter image description here

22
Matteo

Vous devez créer votre propre ArrayAdapter:

private class YourAdapter extends ArrayAdapter<String> {
   // do some work
}

Ensuite, vous devez spécifier à quoi ressemblera votre ligne avec XML, exactement pour votre objectif, je vous recommande d'utiliser RelativeLayout et cela peut ressembler à ceci:

row.xml

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

    <TextView 
        Android:id="@+id/name"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignParentLeft="true"
        />

    <TextView 
        Android:id="@+id/email"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignParentLeft="true"
        Android:layout_below="@id/name"
        />

</RelativeLayout>

Donc, dans YourAdapter vous devez définir un super constucteur:

public YourAdapter() {
   super(YourActivity.this, R.layout.row, data);
}

Ensuite, pour personnaliser vos données dans ListView + une implémentation plus efficace, je vous recommande de remplacer la méthode getView() et d'utiliser également Holder design pattern.

@Override
public View getView(int position, View convertView, ViewGroup parent) {         
   ViewHolder holder = null;
   LayoutInflater inflater = getLayoutInflater();
      if (convertView == null) {
         convertView = inflater.inflate(R.layout.row, null, false);
         holder = new ViewHolder(convertView);
         convertView.setTag(holder);
      }
      else {
         holder = (ViewHolder) convertView.getTag();
      }     
      holder.getUpperText().setText(dataSource[position]);
      holder.getLowerText().setText(dataSource[position]);

   return convertView;  
}

Enfin, il suffit d'initialiser ListView et de définir Adapter:

ListView list = (ListView) findViewById(R.id.list);
list.setAdapter(new YourAdapter());


Remarque:Design pattern Holder Représente un objet arbitraire qui contient des widgets enfants de chaque ligne, vous devez donc les trouver une seule fois puis avec Holder objet vous y aura toujours accès.

L'implémentation de Holder peut ressembler à ceci:

public class ViewHolder {
   private View row;
   private TextView upperText = null, lowerText = null;

   public ViewHolder(View row) {
      this.row = row;
   }

   public TextView getUpperText() {
      if (this.upperText == null) {
         this.upperText = (TextView) inView.findViewById(R.id.someId);
      }
      return this.upperText;
   }

   public TextView getLowerText() {
      if (this.lowerText == null) {
         this.lowerText = (TextView) inView.findViewById(R.id.someId);
      }
      return this.lowerText;
   }
}


J'espère que cela aide.

32
Simon Dorociak

Vous pouvez réaliser cette mise en page en utilisant Android.R.layout.simple_list_item_2 plutôt que de créer une disposition de ligne personnalisée.

Quoi qu'il en soit, si vous souhaitez adopter une approche de disposition de ligne personnalisée, j'ai un extrait de code prêt pour vous.

Voici.

SampleActivity.Java

package org.sample;

import Java.util.ArrayList;

import Android.app.ListActivity;
import Android.content.Context;
import Android.os.Bundle;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.BaseAdapter;
import Android.widget.TextView;
import Android.widget.TwoLineListItem;

public class SampleActivity extends ListActivity {

    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        Mobile mobile;

        ArrayList<Mobile> mobiles  new ArrayList<Mobile>();

        mobile = new Mobile();
        mobile.setName("Android");
        mobile.setSummary("summary goes here");
        mobiles.add(mobile);

        mobile = new Mobile();
        mobile.setName("Blackberry");
        mobile.setSummary("summary goes here");
        mobiles.add(mobile);

        setListAdapter(new MyAdapter(this, mobiles));
    }

}

Mobile.Java

class Mobile {
    String name;
    String summary;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSummary() {
        return summary;
    }

    public void setSummary(String summary) {
        this.summary = summary;
    }

}

MyAdapter.Java

class MyAdapter extends BaseAdapter {

    private Context context;
    private ArrayList<Mobile> mobiles;

    public MyAdapter(Context context, ArrayList<Mobile> mobiles) {
        this.context = context;
        this.mobiles = mobiles;
    }

    @Override
    public int getCount() {
        return mobiles.size();
    }

    @Override
    public Object getItem(int position) {
        return mobiles.get(position);
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {


        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = (View) inflater.inflate(
                    R.layout.list_entry_layout, null);
        }

        TextView name = (TextView)convertView.findViewById(R.id.list_entry_title);
        TextView summary=(TextView)convertView.findViewById(R.id.list_entry_summary);

        name.setText(mobiles.get(position).getName());
        summary.setText(mobiles.get(position).getSummary());

        return convertView;
    }
}
13
Vipul Shah

Créez votre propre ArrayAdapter.
Voir par exemple http://www.ezzylearning.com/tutorial.aspx?tid=1763429 .

4
nhaarman