Android DataAdapter混合数据值
我正在为ListView使用自定义数据适配器,它列出了我应用程序中的一些类别。当我添加一个新类别或滚动列表查看每个项目时,不知何故,它并没有为新添加的数据创建一个新项目。这是我的自定义适配器的代码Android DataAdapter混合数据值,android,listview,android-listview,baseadapter,Android,Listview,Android Listview,Baseadapter,我正在为ListView使用自定义数据适配器,它列出了我应用程序中的一些类别。当我添加一个新类别或滚动列表查看每个项目时,不知何故,它并没有为新添加的数据创建一个新项目。这是我的自定义适配器的代码 public class CategoryAdapter extends BaseAdapter { List<Category> mList; Context mContext; public CategoryAdapter(Context context, List<Cate
public class CategoryAdapter extends BaseAdapter {
List<Category> mList;
Context mContext;
public CategoryAdapter(Context context, List<Category> data) {
mList = data;
mContext = context;
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
if (position < 0 || position >= mList.size())
return null;
return mList.get(position);
}
@Override
public long getItemId(int position) {
if (position < 0 || position >= mList.size())
return -1;
return mList.get(position).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
CategoryDelegate del;
if (convertView == null) {
System.out.println("CV Null pos: " + position);
del = new CategoryDelegate(mContext, mList.get(position));
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 67, parent.getResources().getDisplayMetrics());
del.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT, height));
} else {
System.out.println("CV EXIST pos: " + position + " / " + mList.get(position).getTitle() + " =? " + ((CategoryDelegate) convertView).getCategory().getTitle());
del = (CategoryDelegate) convertView;
}
return del;
}
public void setData(List<Category> data) {
mList = data;
notifyDataSetChanged();
}
public class CategoryDelegate extends LinearLayout {
private TextView mTitle;
private TextView mCount;
private Category mCategory;
public CategoryDelegate(Context context, Category category) {
super(context);
mCategory = category;
Resources res = getResources();
//leftMargin = 11dp; textAlignVCenter; fontSize = 20dp(sp!); color = Color.rgb(149, 155, 171);
mTitle = new TextView(context);
mTitle.setTextColor(Color.rgb(149, 155, 171));
mTitle.setGravity(Gravity.CENTER_VERTICAL);
mTitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
mTitle.setText(category.getTitle());
LayoutParams titleParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
titleParams.leftMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 11, res.getDisplayMetrics());
titleParams.weight = 1;
mTitle.setLayoutParams(titleParams);
addView(mTitle);
//rightMargin = 10dp; textAlignVCenter; fontSize = 15dp(sp!); color = Color.rgb(149, 155, 171);
mCount = new TextView(context);
mCount.setTextColor(Color.rgb(149, 155, 171));
mCount.setGravity(Gravity.CENTER_VERTICAL);
mCount.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
mCount.setText(String.valueOf(category.getSize()));
LayoutParams countParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
countParams.gravity = Gravity.RIGHT;
countParams.rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 13, res.getDisplayMetrics());
mCount.setLayoutParams(countParams);
addView(mCount);
}
public Category getCategory() {
return mCategory;
}
}
当我添加一个新的类别或向下滚动到列表时,如果convertView==null{从不工作,我不知道为什么,它会转到现有的convertView,并且在该点之后所有的数据都会混淆。你知道如何使这个适配器工作吗?如果我像这样更改getView函数
@Override
public View getView(int position, View convertView, ViewGroup parent) {
CategoryDelegate del;
if (convertView == null) {
del = new CategoryDelegate(mContext, mList.get(position));
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 67, parent.getResources().getDisplayMetrics());
del.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT, height));
} else {
if (((CategoryDelegate) convertView).getId() != mList.get(position).getId()) {
del = new CategoryDelegate(mContext, mList.get(position));
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 67, parent.getResources().getDisplayMetrics());
del.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT, height));
} else {
del = (CategoryDelegate) convertView;
}
}
return del;
}
public void updateDelegate(Category category) {
mTitle.setText(category.getTitle());
mCount.setText(String.valueOf(category.getSize()));
mCategory = category;
}
ListView工作正常,但我不确定我做的事情是好是坏。是否有人可以向我解释那里发生了什么。是否有可能导致内存泄漏
编辑:由于我担心内存泄漏,上面的代码恰恰导致内存泄漏,所以我发现一篇关于视图持有者模式的好文章值得一读:
然后我改变了我的代码
@Override
public View getView(int position, View convertView, ViewGroup parent) {
CategoryDelegate del;
if (convertView == null) {
del = new CategoryDelegate(mContext, mList.get(position));
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 67, parent.getResources().getDisplayMetrics());
del.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT, height));
} else {
if (((CategoryDelegate) convertView).getId() != mList.get(position).getId()) {
((CategoryDelegate) convertView).updateDelegate(mList.get(position));
}
del = (CategoryDelegate) convertView;
}
return del;
}
最后,分类如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
CategoryDelegate del;
if (convertView == null) {
del = new CategoryDelegate(mContext, mList.get(position));
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 67, parent.getResources().getDisplayMetrics());
del.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT, height));
} else {
if (((CategoryDelegate) convertView).getId() != mList.get(position).getId()) {
del = new CategoryDelegate(mContext, mList.get(position));
int height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 67, parent.getResources().getDisplayMetrics());
del.setLayoutParams(new ListView.LayoutParams(LayoutParams.MATCH_PARENT, height));
} else {
del = (CategoryDelegate) convertView;
}
}
return del;
}
public void updateDelegate(Category category) {
mTitle.setText(category.getTitle());
mCount.setText(String.valueOf(category.getSize()));
mCategory = category;
}
现在一切都像一个符咒一样工作…当convertView!=null时,您需要使用新的mList.getposition值更新del,并更新使用该值的任何视图。适配器将回收视图以避免重新实例化整个新视图。因此,当您收到非null convertView时,您将收到一个回收视图。这意味着您'将需要使用该位置的任何新数据更新该视图。注意,回收的视图并不意味着它使用的是同一位置。它可能来自于在完全不同的位置使用的视图
另外,我应该注意到,创建视图的方式并不是一种干净的或推荐的方式。更好的方法是创建一个单独的独立类CategoryDelegate,然后在XML文件中直接使用该类。在其中定义所有属性并扩展该视图
给你一些进一步的阅读: