我有一个listview
,每行有一个textview
和一个edit text
。如果我在一个编辑文本字段中设置一个值然后向下滚动,我将在其他一些编辑文本字段中获得该输入字段值的重复值。我该如何解决这个问题?
我的适配器类如下所示:
public class CustomAdapter extends ArrayAdapter<String> {
private Context context;
private String[] names;
ViewHolder holder;
static class ViewHolder {
public TextView text;
public EditText editText;
}
public CustomAdapter(Context context, int textViewResourceId, String[] names) {
super(context, textViewResourceId, names);
this.context = context;
this.names = names;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_design, parent, false);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.textView1);
holder.editText = (EditText) convertView.findViewById(R.id.editText1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
String s = names[position];
holder.text.setText(s);
return convertView;
}
}
我已经提到了这个链接: Listview duplicate action,Android listview duplicates the item on scroll
答案 0 :(得分:5)
首先这个问题的原因是Listview在滚动时重用它的视图, 所以我们应该在get视图中有一个逻辑来管理
if(convertview == null)
{
//code here
}else {
//code here
}
, 但如果您不想重复使用,那么您可以使用以下内容:
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return 500;
}
答案 1 :(得分:0)
请尝试以下代码:
public class CustomAdapter extends ArrayAdapter<String> {
private Context context;
private String[] names;
static class ViewHolder {
public TextView text;
public EditText editText;
}
public CustomAdapter(Context context, int textViewResourceId, String[] names) {
super(context, textViewResourceId, names);
this.context = context;
this.names = names;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.row_design, parent, null);
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.textView1);
viewHolder.editText = (EditText) rowView.findViewById(R.id.editText1);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder)rowView.getTag();
String s = names[position];
holder.text.setText(s);
return rowView;
}
}
有关详细信息,请参阅This link.
希望它会对你有所帮助。
答案 2 :(得分:0)
这是我能够想到的最好的。但试试这个作为解决方法。我同意这个问题可以有一个更好/更清洁的解决方案。
您面临的问题是ListView
回收视图以获得更好的效果。
首先,您可以将数据更改为List
而不是数组,并进行如下更改。
List<String> names;
List<String> edit;
// In Constructor()
this.names = names;
// Create a list with empty data for the editTexts
int listSize = names.size();
String emptyString = new String("");
List<String> emptyList = new ArrayList<String>(listSize);
for(int i = 0; i < listSize; i ++){
emptyList.add(emptyString);
}
this.edit = emptyList;
// In getView()
// add watcher to editText and when it is changed, update the value in 'edit'
// Simply set the corresponding values to this row to the editText
holder.text.setText(names.get(position));
holder.editText.setText(edit.get(position));
你能看出这是否能在短期内解决你的问题。
您可以看到如何使用此答案https://stackoverflow.com/a/11181721/592025
中观看的内容答案 3 :(得分:0)
<强>更新强>
我的原始解决方案适用于此用例,但更好的解决方案是HailNaRoz所涉及的ViewHolder
模式。虽然HailNaRoz没有解释为什么他的解决方案有效,但该解决方案使用ViewHolder
来帮助View
重用,并且是Google和Android Dev社区采用的首选方法。 ViewHolder
保留对Views
(EditText
,TextView
,ImageView
等)的引用,并允许您将它们添加回正确的列表行它变得可见。
它还值得研究RecyclerView
,这是为了解决其中一些问题而引入的,这些问题迫使这种方法论出现。 RecyclerView
可用作支持库,可以在gradle中添加
请参阅View Holder in List View和Creating Lists and Cards (Recycler View)
<强>原始强>
您的问题是您的EditText
正在被回收。您将保留TextView
文字的副本,并在每次加载时重置该文本,但不会为EditText
重置。
因此,您需要一种方法将文本存储在EditText
字段中,并在getView()
方法中重置该文本。
要执行此操作,您需要在TextWatcher
中的if / else语句后设置getView()
:
holder.editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start,
int before, int count) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void afterTextChanged(Editable s) {
editTextList.put(position,s.toString());
}
});
这将值存储在单独维护的HashMap
中。 position
取自getView()
方法中的int参数。你需要做到最后。
HashMap
:
private HashMap<Integer,String> editTextList =new HashMap<Integer,String>();
然后,当您设置TextView
文字时,您还要设置EditText
值:
holder.text.setText(s);
holder.editText.setText(editTextList.get(position));
这应该将当前位置editText
保留在正确的EditText
框中。