Android CustomListView 更新的字段在向下滚动时重复
Android CustomListView updated fields are repeating when scrolled down
我在 customlist view
中遇到问题。
我有两个 buttons
和一个 textVie
w 。添加和减去按钮。
单击 Add
按钮时,计数器应分别为 +1 和 -1。
我使用了一个虚拟字符串来检查它是否真的在更新 textView
。但问题是当我 scroll down
一些项目具有相同的价值时。
例如
第一项 TextView
设置为 "HIII"
然后如果我向下滚动第 11 个,第 21 个 ... 也设置为 "HIII"
注意:显示可以包含的最大数量是 10 个项目,所以当我向下滚动到第 11 个时,它被设置为 "HII".
public class CustomAdapter extends ArrayAdapter {
Context context;
LayoutInflater inflater;
int resource;
//ArrayList<Integer> count = new ArrayList<>();
public CustomAdapter(Context context, int resource) {
super(context, resource);
this.context = context;
this.resource = resource;
}
@Override
public int getCount() {
return 100;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mainHolder = null;
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
final ViewHolder holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
convertView.setTag(holder);
} else {
mainHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
}
class ViewHolder {
Button add, sub;
TextView textView;
}
请帮助我。我想知道如何设置一个与另一个的 tag
(我的意思是你怎么知道你需要用另一个对象或视图设置标签)
谢谢
在 else 条件之后编写您的 onclick 侦听器。
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
ListView 回收视图。它创建的视图将在向下滚动时重新使用。
因此,您必须在每次调用 getView()
时调用 setText()
和 setOnClickListener()
,而不仅仅是单击按钮时。
要实现您想要的效果,您必须将设置的文本数据存储在模型中,例如 SparseArray
将位置映射到数据。
public class CustomAdapter extends ArrayAdapter {
Context context;
LayoutInflater inflater;
int resource;
//ArrayList<Integer> count = new ArrayList<>();
// Your data map by position
SparseArray<String> data = new SparseArray<>();
public CustomAdapter(Context context, int resource) {
super(context, resource);
this.context = context;
this.resource = resource;
}
@Override
public int getCount() {
return 100;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(data.get(position));
holder.add.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
final String text = "HIII";
data.put(position, text);
holder.textView.setText(text);
notifyDataSetChanged();
}
});
return convertView;
}
}
class ViewHolder {
Button add, sub;
TextView textView;
}
看看你的 getView 函数:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mainHolder = null;
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
final ViewHolder holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
convertView.setTag(holder);
} else {
mainHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
只有在创建新的 Viewholder 时,您才能编辑持有人 textView
和 add
按钮的内容。
列表视图第一次显示其项目时,总会为所有可见单元格创建一个新视图(以及一个新的 Viewholder)。
一旦您向下滚动,适配器将获取一个现在不可见的单元格(可能是第一个单元格)并回收它以显示一个现在可见的单元格。在这种情况下,getView 中的 convertView
将不再为 null,因为视图已被回收。
因此,您应该在 if
语句之外处理所有文本更改和监听器等,以管理这两种情况(回收的和新的)。
例如:
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
final ViewHolder holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
convertView.setTag(holder);
} else {
mainHolder = (ViewHolder) convertView.getTag();
}
holder.textView.setText("");
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
编辑
将数据保存在像 Yaroslav Mytkalyk 这样的稀疏数组中是一种更好的方法。
无论如何,你必须处理回收的视图。
我在 customlist view
中遇到问题。
我有两个 buttons
和一个 textVie
w 。添加和减去按钮。
单击 Add
按钮时,计数器应分别为 +1 和 -1。
我使用了一个虚拟字符串来检查它是否真的在更新 textView
。但问题是当我 scroll down
一些项目具有相同的价值时。
例如
第一项 TextView
设置为 "HIII"
然后如果我向下滚动第 11 个,第 21 个 ... 也设置为 "HIII"
注意:显示可以包含的最大数量是 10 个项目,所以当我向下滚动到第 11 个时,它被设置为 "HII".
public class CustomAdapter extends ArrayAdapter {
Context context;
LayoutInflater inflater;
int resource;
//ArrayList<Integer> count = new ArrayList<>();
public CustomAdapter(Context context, int resource) {
super(context, resource);
this.context = context;
this.resource = resource;
}
@Override
public int getCount() {
return 100;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mainHolder = null;
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
final ViewHolder holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
convertView.setTag(holder);
} else {
mainHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
}
class ViewHolder {
Button add, sub;
TextView textView;
}
请帮助我。我想知道如何设置一个与另一个的 tag
(我的意思是你怎么知道你需要用另一个对象或视图设置标签)
谢谢
在 else 条件之后编写您的 onclick 侦听器。
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
ListView 回收视图。它创建的视图将在向下滚动时重新使用。
因此,您必须在每次调用 getView()
时调用 setText()
和 setOnClickListener()
,而不仅仅是单击按钮时。
要实现您想要的效果,您必须将设置的文本数据存储在模型中,例如 SparseArray
将位置映射到数据。
public class CustomAdapter extends ArrayAdapter {
Context context;
LayoutInflater inflater;
int resource;
//ArrayList<Integer> count = new ArrayList<>();
// Your data map by position
SparseArray<String> data = new SparseArray<>();
public CustomAdapter(Context context, int resource) {
super(context, resource);
this.context = context;
this.resource = resource;
}
@Override
public int getCount() {
return 100;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.textView.setText(data.get(position));
holder.add.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
final String text = "HIII";
data.put(position, text);
holder.textView.setText(text);
notifyDataSetChanged();
}
});
return convertView;
}
}
class ViewHolder {
Button add, sub;
TextView textView;
}
看看你的 getView 函数:
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mainHolder = null;
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
final ViewHolder holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
convertView.setTag(holder);
} else {
mainHolder = (ViewHolder) convertView.getTag();
}
return convertView;
}
只有在创建新的 Viewholder 时,您才能编辑持有人 textView
和 add
按钮的内容。
列表视图第一次显示其项目时,总会为所有可见单元格创建一个新视图(以及一个新的 Viewholder)。
一旦您向下滚动,适配器将获取一个现在不可见的单元格(可能是第一个单元格)并回收它以显示一个现在可见的单元格。在这种情况下,getView 中的 convertView
将不再为 null,因为视图已被回收。
因此,您应该在 if
语句之外处理所有文本更改和监听器等,以管理这两种情况(回收的和新的)。
例如:
if (convertView == null) {
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(resource, parent, false);
Log.e("GET-VIEW", " Creating Views");
final ViewHolder holder = new ViewHolder();
holder.add = (Button) convertView.findViewById(R.id.add);
holder.sub = (Button) convertView.findViewById(R.id.sub);
holder.textView = (TextView) convertView.findViewById(R.id.numberTV);
convertView.setTag(holder);
} else {
mainHolder = (ViewHolder) convertView.getTag();
}
holder.textView.setText("");
holder.add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
holder.textView.setText("HIII");
}
});
编辑 将数据保存在像 Yaroslav Mytkalyk 这样的稀疏数组中是一种更好的方法。 无论如何,你必须处理回收的视图。