Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to add a dynamic view to a ListView item at runtime?
    primarykey
    data
    text
    <p>My problem is that I don't know whether I should use multiple list view or a custom listview item adapter which can grows dynamically. For example, for a particular user, they can have multiple activities:<br> - Take a picture<br> - Say something<br> - Checking in<br> - ... </p> <p>Apparently, this list can grows as the user has done more activities. Most of the time, I often create a custom item adapter which extends from <code>BaseAdapter</code> and use the <code>ItemHolder</code> pattern as follows:</p> <pre><code>public class PlaceItemAdapter extends BaseAdapter { private Activity context; private List&lt;Place&gt; places; private boolean notifyChanged = false; public PlaceItemAdapter(Activity context, List&lt;Place&gt; 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; } } </code></pre> <p>Using this method, the number GUI widgets is fixed which means I can't make my listview item look like the picture below.</p> <pre><code> public static class ItemViewHolder { TextView nameTextView; TextView typesTextView; TextView ratingTextView; ImageView mapIconImageView; } </code></pre> <p>My initial approach was to create a dynamic view nested inside an adapter item, however it will produce duplicate views. To avoid duplicate view, I have set <code>convertView</code> to null which means each time it loads, it will create a new <code>ItemViewHolder</code> which eventually eats up all my memory. :( So how could I handle this situation? A minimal working example would be greatly appreciated.</p> <p><strong>Duplicate View</strong></p> <pre><code>public class FriendFeedItemAdapter extends BaseAdapter { private List&lt;FriendFeedItem&gt; items; private Activity context; private static LayoutInflater inflater; public ImageLoader imageLoader; private ItemViewHolder viewHolder; public FriendFeedItemAdapter(Activity context, List&lt;FriendFeedItem&gt; 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; } } </code></pre> <p><strong>Extensive Memory Usage</strong></p> <pre><code>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; } </code></pre> <p><img src="https://i.stack.imgur.com/QRa5L.png" alt="enter image description here"></p> <p><img src="https://i.stack.imgur.com/DVwbn.png" alt="enter image description here"></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload