gpt4 book ai didi

android - 如何在运行时向 ListView 项添加动态 View ?

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:01:27 25 4
gpt4 key购买 nike

我的问题是我不知道是应该使用多 ListView 还是可以动态增长的自定义 ListView 项适配器。例如,对于特定用户,他们可以有多个 Activity :
- 拍照
- 说点什么
- 签到
- ...

显然,随着用户进行更多 Activity ,此列表会增长。大多数时候,我经常创建一个自定义项适配器,它从 BaseAdapter 扩展并使用 ItemHolder 模式,如下所示:

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

使用这种方法,GUI 小部件的数量是固定的,这意味着我不能使我的 ListView 项看起来像下图。

    public static class ItemViewHolder {
TextView nameTextView;
TextView typesTextView;
TextView ratingTextView;
ImageView mapIconImageView;
}

我最初的方法是创建一个嵌套在适配器项中的动态 View ,但是它会产生重复的 View 。为了避免重复 View ,我将 convertView 设置为 null,这意味着每次加载时,它都会创建一个新的 ItemViewHolder,最终会耗尽我的所有内存。 :( 那么我该如何处理这种情况?非常感谢一个最小的工作示例。

重复 View

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

大量内存使用

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

enter image description here

enter image description here

最佳答案

如果您有少量可能的变体(在您的屏幕截图上我可以看到 2 个不同的列表项)您有两种可能的变体:

  1. 设置不同类型的数量 this方法,并提供type对于每个项目 - 您可以使用 convertView。

  2. 创建“完整”列表项 View 并设置您不想在特定项中看到的元素的可见性。

#2 的一些代码:

public class ListTestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

List<Element> list = new ArrayList<Element>();
list.add(new Element(0));
list.add(new Element(0));
list.add(new Element(1));
list.add(new Element(0));
list.add(new Element(1));
list.add(new Element(1));
list.add(new Element(0));
list.add(new Element(0));
list.add(new Element(1));
list.add(new Element(1));
list.add(new Element(1));
list.add(new Element(0));
list.add(new Element(0));
list.add(new Element(1));
list.add(new Element(0));
list.add(new Element(0));
((ListView) findViewById(android.R.id.list)).setAdapter(new SampleAdapter(this, list));
}

private class SampleAdapter extends BaseAdapter {

private List<Element> list;
private Context context;

public SampleAdapter(Context context, List<Element> list) {
this.list = list;
this.context = context;
}

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

@Override
public Element getItem(int position) {
return list.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null)
switch (getItemViewType(position)) {
case 0:
convertView = new CheckBox(context);
break;
default:
convertView = new Button(context);
break;
}
// Output here shows that you can lay on getItemViewType(position) as indicator of convertView type or structure
Log.e("test", getItemViewType(position) + ": " + convertView.getClass().getSimpleName());
return convertView;
}

@Override
public int getItemViewType(int position) {
return getItem(position).type;
}

@Override
public int getViewTypeCount() {
return 2;
}

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

private class Element {
public int type;

public Element(int type) {
this.type = type;
}
}
}

关于android - 如何在运行时向 ListView 项添加动态 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8649705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com