Comment ajouter un point de vue dynamique d'un élément de liste au moment de l'exécution?
Mon problème est que je ne sais pas si je doit utiliser plusieurs d'affichage de liste ou une coutume élément listview adaptateur qui peut se développe de façon dynamique. Par exemple, pour un utilisateur particulier, ils peuvent avoir de multiples activités:
- Prendre une photo
- Dis quelque chose
- Check-in
- ...
Apparemment, cette liste peut croît à mesure que l'utilisateur a fait plus d'activités. La plupart du temps, j'ai souvent créer un élément personnalisé de l'adaptateur qui s'étend de BaseAdapter
et l'utilisation de la ItemHolder
modèle comme suit:
public class PlaceItemAdapter extends BaseAdapter {
private Activity context;
private List<Place> places;
private boolean notifyChanged = false;
public PlaceItemAdapter(Activity context, List<Place> places) {
super();
this.context = context;
this.places = places;
}
public int getCount() {
return places.size();
}
public Object getItem(int position) {
return places.get(position);
}
public long getItemId(int position) {
return position;
}
public static class ItemViewHolder {
TextView nameTextView;
TextView typesTextView;
TextView ratingTextView;
ImageView mapIconImageView;
}
public View getView(int position, View convertView, ViewGroup parent) {
ItemViewHolder holder;
LayoutInflater inflater = context.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.place_item, null);
holder = new ItemViewHolder();
holder.nameTextView = (TextView) convertView.findViewById(R.id.place_item_xml_textview_name);
holder.typesTextView = (TextView) convertView.findViewById(R.id.place_item_xml_textview_address);
holder.ratingTextView = (TextView) convertView.findViewById(R.id.place_item_xml_textview_rating);
holder.mapIconImageView = (ImageView) convertView.findViewById(R.id.place_item_xml_imageview_location_icon);
convertView.setTag(holder);
}
else {
holder = (ItemViewHolder) convertView.getTag();
}
holder.nameTextView.setText(places.get(position).getName());
holder.typesTextView.setText(places.get(position).getAddress());
holder.ratingTextView.setText(Integer.toString(places.get(position).getRating()));
/*
* This task is time consuming!
* TODO: find a workaround to handle the image
*/
//holder.mapIconImageView.setImageBitmap(DownloadImageHelper.downloadImage(places.get(position).getIconUrl()));
holder.mapIconImageView.setImageResource(R.drawable.adium);
return convertView;
}
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
notifyChanged = true;
}
}
À l'aide de cette méthode, le nombre GUI widgets est fixe, ce qui signifie que je ne peux pas faire mon élément listview ressembler à l'image ci-dessous.
public static class ItemViewHolder {
TextView nameTextView;
TextView typesTextView;
TextView ratingTextView;
ImageView mapIconImageView;
}
Mon approche initiale était de créer une dynamique en vue imbriquée à l'intérieur d'un élément adaptateur, cependant, il va produire en double point de vue. Pour éviter les doublons de vue, j'ai mis convertView
à null, ce qui signifie que chaque fois qu'il se charge, il va créer un nouveau ItemViewHolder
qui mange tout l'ensemble de ma mémoire. 🙁 Donc, comment pourrais-je gérer cette situation? Un minimum de travail exemple serait grandement apprécié.
Double Vue
public class FriendFeedItemAdapter extends BaseAdapter {
private List<FriendFeedItem> items;
private Activity context;
private static LayoutInflater inflater;
public ImageLoader imageLoader;
private ItemViewHolder viewHolder;
public FriendFeedItemAdapter(Activity context, List<FriendFeedItem> items) {
this.context = context;
this.items = items;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new ImageLoader(context.getApplicationContext());
}
public int getCount() {
return items.size();
}
public Object getItem(int position) {
return items.get(position);
}
public long getItemId(int position) {
return position;
}
public static class ItemViewHolder {
TableLayout table;
ImageView imageViewUserPicture;
TextView textViewUsername;
TextView textViewWhatUserDo;
TextView textViewWhere;
TextView textViewTime;
ImageView imageViewSnapPictureBox;
TextView textViewWriteOnWallMessageBox;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.friend_list_feed_item, null);
viewHolder = new ItemViewHolder();
viewHolder.table = (TableLayout) convertView.findViewById(R.id.friend_list_feed_item_xml_tablelayout_table);
viewHolder.imageViewUserPicture = (ImageView) convertView.findViewById(R.id.friend_list_feed_item_xml_imageview_user_picture);
viewHolder.textViewUsername = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_username);
viewHolder.textViewWhatUserDo = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_what_user_do);
viewHolder.textViewWhere = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_where);
viewHolder.textViewTime = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_at_what_time);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ItemViewHolder) convertView.getTag();
}
imageLoader.displayImage(items.get(position).getFriendPictureUrl(), viewHolder.imageViewUserPicture);
viewHolder.textViewUsername.setText(items.get(position).getFriendName());
viewHolder.textViewWhere.setText("at " + items.get(position).getPlaceName());
viewHolder.textViewTime.setText("@" + items.get(position).getActivityTime());
if (items.get(position).getChallengeType() == Challenge.Type.CHECK_IN) {
viewHolder.textViewWhatUserDo.setText("has checked in.");
}
else if (items.get(position).getChallengeType() == Challenge.Type.SNAP_PICTURE) {
viewHolder.textViewWhatUserDo.setText("has snap a picture.");
//add picture box
View rowView = inflater.inflate(R.layout.snap_picture_row_item, null);
viewHolder.imageViewSnapPictureBox = (ImageView) rowView.findViewById(R.id.snap_picture_row_item_xml_imageview_picture);
imageLoader.displayImage(items.get(position).getActivitySnapPictureUrl(), viewHolder.imageViewSnapPictureBox);
viewHolder.table.addView(rowView);
}
else if (items.get(position).getChallengeType() == Challenge.Type.WRITE_ON_WALL) {
viewHolder.textViewWhatUserDo.setText("has written a message on wall.");
//add message box
View rowView = inflater.inflate(R.layout.write_on_wall_row_item, null);
viewHolder.textViewWriteOnWallMessageBox = (TextView) rowView.findViewById(R.id.write_on_wall_row_item_xml_textview_wall_message);
viewHolder.textViewWriteOnWallMessageBox.setText(items.get(position).getActivityComment());
viewHolder.table.addView(rowView);
}
else if (items.get(position).getChallengeType() == Challenge.Type.QUESTION_ANSWER) {
viewHolder.textViewWhatUserDo.setText("has answered a question.");
}
else { //Challenge.Type.OTHER
viewHolder.textViewWhatUserDo.setText("has done some other challenges.");
}
return convertView;
}
}
Utilisation De La Mémoire Complète
public View getView(int position, View convertView, ViewGroup parent) {
ItemViewHolder holder = null;
LayoutInflater inflater = context.getLayoutInflater();
convertView = inflater.inflate(R.layout.friend_list_feed_item, null);
//create holder
holder = new ItemViewHolder();
//default field
holder.table = (TableLayout) convertView.findViewById(R.id.friend_list_feed_item_xml_tablelayout_table);
holder.imageViewUserPicture = (ImageView) convertView.findViewById(R.id.friend_list_feed_item_xml_imageview_user_picture);
holder.textViewUsername = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_username);
holder.textViewWhatUserDo = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_what_user_do);
holder.textViewWhere = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_where);
holder.textViewTime = (TextView) convertView.findViewById(R.id.friend_list_feed_item_xml_textview_at_what_time);
convertView.setTag(holder);
holder.imageViewUserPicture.setImageURI(items.get(position).getFriendPictureUri());
holder.textViewUsername.setText(items.get(position).getFriendName());
holder.textViewWhere.setText("at " + items.get(position).getPlaceName());
holder.textViewTime.setText("@" + items.get(position).getActivityTime());
if (items.get(position).getChallengeType() == Challenge.Type.CHECK_IN) {
holder.textViewWhatUserDo.setText("has checked in.");
}
else if (items.get(position).getChallengeType() == Challenge.Type.SNAP_PICTURE) {
holder.textViewWhatUserDo.setText("has snap a picture.");
//add picture box
View rowView = inflater.inflate(R.layout.snap_picture_row_item, null);
holder.imageViewSnapPictureBox = (ImageView) rowView.findViewById(R.id.snap_picture_row_item_xml_imageview_picture);
holder.imageViewSnapPictureBox.setImageURI(items.get(position).getActivitySnapPictureUri());
holder.table.addView(rowView);
}
else if (items.get(position).getChallengeType() == Challenge.Type.WRITE_ON_WALL) {
holder.textViewWhatUserDo.setText("has written a message on wall.");
//add message box
View rowView = inflater.inflate(R.layout.write_on_wall_row_item, null);
holder.textViewWriteOnWallMessageBox = (TextView) rowView.findViewById(R.id.write_on_wall_row_item_xml_textview_wall_message);
holder.textViewWriteOnWallMessageBox.setText(items.get(position).getActivityComment());
holder.table.addView(rowView);
}
else if (items.get(position).getChallengeType() == Challenge.Type.QUESTION_ANSWER) {
holder.textViewWhatUserDo.setText("has answered a question.");
}
else { //Challenge.Type.OTHER
holder.textViewWhatUserDo.setText("has done some other challenges.");
}
return convertView;
}
OriginalL'auteur Chan | 2011-12-27
Vous devez vous connecter pour publier un commentaire.
Si vous avez un petit nombre de variantes possibles (sur vos captures d'écran, je peux voir les 2 différents éléments de la liste), Vous avez deux variantes possibles:
De l'installation nombre de différents types de cette méthode, et de fournir type pour chaque article, et vous pouvez utiliser convertView.
Créer "plein" élément de la liste d'afficher et de définir la visibilité pour les éléments que vous ne voulez pas voir en particulier l'article.
Un peu de code pour #2:
voir mon édité répondre
C'est le chemin à parcourir. Je préfère utiliser une interface
ItemViewType
qui fournit les méthodes pour la création de la vue (dans le cas convertView estnull
) et de la liaison de données à la vue. La mise en œuvre de classes de déclarer leursViewHolder
comme l'intérieur de la classe. Vous pouvez étendre l'interface avec une accpets méthode pour vous aider dans votre adaptateurgetItemViewType
Merci beaucoup pour l'exemple. C'est une réponse que j'ai été à la recherche pour une longue période de temps.
Je suis d'accord que mon exemple n'est pas bon pour le "code de production", mais c'est la meilleure façon de montrer à l'idée de la carte avec plusieurs types de vues.
OriginalL'auteur Jin35
Un adaptateur personnalisé permettrait de résoudre votre problème. C'est parce que vous pouvez changer les points de vue qui sont ajoutés à chaque ligne dans la liste, parce que vous pouvez changer le contenu par l'intermédiaire de la logique que vous mettre en œuvre dans la coutume adaptateur.
Lorsque le getView() la méthode retourne un point de vue qui n'est pas nulle, cela signifie que pour cette ligne, il y a un point de vue qui est déjà là. En tant que tel, si c'est le cas, vous pouvez ou ne souhaitez pas modifier le contenu de ce point de vue spécifique. Ou vous pourriez créer une nouvelle marque de point de vue avec du contenu dynamique pour cette ligne particulière.
Une chose à noter est que getView() sera appelée autant de fois qu'il y a des articles se trouvant dans votre carte.
OriginalL'auteur JoxTraex
Voici une idée qui va probablement vous permettre d'introduire autant de types d'éléments que vous le souhaitez sans avoir à modifier la carte chaque fois que vous faites:
... et puis l'étendre AbstractItem et ajouter des instances de l'adaptateur, pas besoin d'ajouter de si les clauses de getView ().
OriginalL'auteur Ivan Bartsov