So fügen Sie eine dynamische Sicht auf ein ListView-Element zur Laufzeit?
Mein problem ist, dass ich nicht weiß, ob ich sollte, verwenden Sie mehrere Listen-Ansicht oder eine custom listview-Element adapter können wächst dynamisch. Zum Beispiel, für einen bestimmten Benutzer, können Sie mehrere Aktivitäten:
- Nehmen Sie ein Bild
- Etwas sagen
- Check-in
- ...
Anscheinend, kann diese Liste wächst als der Benutzer getan hat, mehr Aktivitäten. Die meisten der Zeit, habe ich oft erstellen Sie einen benutzerdefinierten Artikel adapter, die sich von BaseAdapter
und verwenden Sie die ItemHolder
Muster wie folgt:
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;
}
}
Mit dieser Methode die Anzahl GUI-widgets behoben wird, was bedeutet, dass ich kann nicht meine listview-Element so Aussehen wie das Bild unten.
public static class ItemViewHolder {
TextView nameTextView;
TextView typesTextView;
TextView ratingTextView;
ImageView mapIconImageView;
}
Mein Erster Ansatz war die Erstellung einer dynamischen Ansicht von verschachtelten innen ein adapter-Element, aber es produziert doppelte Aussicht. Zur Vermeidung einer doppelten Ansicht, ich habe convertView
zu null, was bedeutet, dass jedes mal, wenn es lädt, es wird eine neue erstellen ItemViewHolder
die schließlich frisst alle meine Speicher. 🙁 Wie konnte ich mit der situation umgehen? Ein minimal-Beispiel wäre sehr dankbar.
Doppelte Ansicht
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;
}
}
Umfangreiche Speichernutzung
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;
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie kleine Anzahl von möglichen Varianten (auf screenshots, die ich sehen kann, 2 unterschiedliche Elemente der Liste) haben Sie zwei mögliche Varianten:
Setup-Anzahl der verschiedenen Typen von diese - Methode, und geben geben für jedes Element - und Sie können convertView.
Erstellen "vollen" Punkt der Liste anzeigen und festlegen der Sichtbarkeit für die Elemente, die Sie nicht wollen, um zu sehen, in bestimmte Element.
Code für #2:
ItemViewType
sieht vor, dass die Methoden für die Erstellung der anzeigen (im Fall convertView istnull
) und binden von Daten an die view. Implementierende Klassen deklarieren Ihre spezifischenViewHolder
als innere Klasse. Sie könnten erweitern die Schnittstelle mit einem accpets Methode zu helfen, Sie in Ihrem AdaptersgetItemViewType
Einen benutzerdefinierten adapter würde Ihr problem lösen. Dies ist, weil Sie ändern können die Ansichten Hinzugefügt, um jede Zeile in der Listview, da können Sie den Inhalt über die Logik, die Sie implementieren, in der benutzerdefinierte adapter.
Wenn die getView () - Methode gibt eine Ansicht, die nicht null ist, bedeutet dies für die betreffende Zeile gibt es eine Aussicht das war es schon. Als solche, wenn dies der Fall ist, können Sie oder können nicht wollen, ändern Sie Inhalte in diesem bestimmten Blick. Oder Sie könnte Aufbau einer Marke neue Ansicht mit dynamischen Inhalten für die jeweilige Zeile.
Eine Sache zu beachten ist, dass getView() wird aufgerufen, so oft, wie es Elemente in Ihrem adapter.
Hier ist eine Idee, die wahrscheinlich ermöglichen Sie sich vorstellen, wie viele Element-Typen, wie Sie ohne änderung der adapter jedes mal, wenn Sie tun:
... und dann verlängern AbstractItem und hinzufügen von Instanzen der adapter, keine Notwendigkeit, hinzufügen, wenn die Klauseln zu getView() nicht mehr.