Android:EditText失去滚动ListView中的内容?

我有EditText列表项目,我不知道会有多less项目。 当我在EditTextinput一些文本时出现问题,然后向下滚动ListView ,再次向上滚动后,我的第一个EditText没有文本,或者ListView其他EditText有一些文本。

我已经尝试了TextWatcher ,并将数据保存到数组,但问题是在ListView中返回的视图位置并不总是正确的,所以我从数组中丢失了一些数据。

请帮忙。

这是我的代码:

 public class EfficientAdapter extends BaseAdapter { private LayoutInflater mInflater; public String[] Current; ArrayList<String> MeterName, PreviousReading, Current_Reading; JSONArray getArray_Meter_Reading; public EfficientAdapter(Context context, JSONArray getArray_Meter_Reading) { mInflater = LayoutInflater.from(context); this.getArray_Meter_Reading = getArray_Meter_Reading; MeterName = new ArrayList<String>(); PreviousReading = new ArrayList<String>(); for (int i = 0; i < getArray_Meter_Reading.length(); i++) { try { String Meter_Name = getArray_Meter_Reading.getJSONObject(i) .getString("MeterName").toString(); String previous_Meter_Reading = getArray_Meter_Reading .getJSONObject(i).getString("PrevMeterReading") .toString(); MeterName.add(Meter_Name); PreviousReading.add(previous_Meter_Reading); // Meter[i]=MeterName.get(i); // Previous[i]=PreviousReading.get(i); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public int getCount() { return getArray_Meter_Reading.length(); } public Object getItem(int position) { // TODO Auto-generated method stub return position; } public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.meter_reading_list, null); holder = new ViewHolder(); holder.adp_MeterName = (TextView) convertView .findViewById(R.id.txt_Meter_Name); holder.adp_Previous = (TextView) convertView .findViewById(R.id.txt_Previous); holder.adp_Current = (EditText) convertView .findViewById(R.id.ed_Current); holder.adp_Current.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) { // TODO Auto-generated method stub } public void afterTextChanged(Editable s) { Current[holder.ref] = s.toString(); } }); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.ref = position; holder.adp_MeterName.setText(MeterName.get(position)); holder.adp_Previous.setText(PreviousReading.get(position)); // holder.adp_Current.setHint(MeterName.get(position)); // holder.adp_Current.setText(PreviousReading.get(position)); return convertView; } class ViewHolder { TextView adp_MeterName, adp_Previous; EditText adp_Current; int ref; } } 

尝试这个:

 public class EfficientAdapter extends BaseAdapter { private LayoutInflater mInflater; public String[] Current; ArrayList<String> MeterName, PreviousReading, Current_Reading; JSONArray getArray_Meter_Reading; public static HashMap<Integer,String> myList=new HashMap<Integer,String>(); public EfficientAdapter(Context context, JSONArray getArray_Meter_Reading) { mInflater = LayoutInflater.from(context); this.getArray_Meter_Reading = getArray_Meter_Reading; MeterName = new ArrayList<String>(); PreviousReading = new ArrayList<String>(); for (int i = 0; i < getArray_Meter_Reading.length(); i++) { try { String Meter_Name = getArray_Meter_Reading.getJSONObject(i) .getString("MeterName").toString(); String previous_Meter_Reading = getArray_Meter_Reading .getJSONObject(i).getString("PrevMeterReading") .toString(); MeterName.add(Meter_Name); PreviousReading.add(previous_Meter_Reading); // Meter[i]=MeterName.get(i); // Previous[i]=PreviousReading.get(i); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // initialize myList for(int i=0;i<JSON_ARRAY_LENGTH;i++) { myList.put(i,""); } } public int getCount() { return getArray_Meter_Reading.length(); } public Object getItem(int position) { // TODO Auto-generated method stub return position; } public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder holder; final int pos=position; if (convertView == null) { convertView = mInflater.inflate(R.layout.meter_reading_list, null); holder = new ViewHolder(); holder.adp_MeterName = (TextView) convertView .findViewById(R.id.txt_Meter_Name); holder.adp_Previous = (TextView) convertView .findViewById(R.id.txt_Previous); holder.adp_Current = (EditText) convertView .findViewById(R.id.ed_Current); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.adp_Current.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) { // TODO Auto-generated method stub } public void afterTextChanged(Editable s) { Current[holder.ref] = s.toString(); myList.put(pos,s.toString.trim()); } }); holder.ref = position; holder.adp_MeterName.setText(MeterName.get(position)); holder.adp_Previous.setText(PreviousReading.get(position)); // holder.adp_Current.setHint(MeterName.get(position)); // holder.adp_Current.setText(PreviousReading.get(position)); holder.adp_Current.setText(myList.get(position)); return convertView; } class ViewHolder { TextView adp_MeterName, adp_Previous; EditText adp_Current; int ref; } } 

在这里,我已经包含了一个HashMap对象,如果EditText包含值或不包含值,那么这个HashMap对象将会被关注。当你滚动列表视图时,它将通过调用其getView方法以及与每个edittext相关的文本再次被渲染。

在这个代码中,当你第一次加载列表视图时,所有的编辑文本都将没有文本。一旦你input了一些文本,它会在myList中注明。所以当你再次渲染列表时,你的文本将被阻止。

还有一件事,你应该在外面实现textwatcher if(convertView == null).. else .. block.That是一个更好的做法!

我正在处理与我正在进行的项目完全相同的问题。 我发现的所有解决scheme都使用textChangeListener ,但是由于列表的性质以及每个行视图中的EditText ,这是非常低效的。 我采用了EditText.setOnFocusChangeListener()

我将其附加到getView方法中的每个EditText。 这个效果如此之好的原因是,当用户切换到不同的编辑文本或滚动,所以当前行离开屏幕导致EditText失去焦点时调用它。

在监听器的onFocusChange(View v,boolean hasFocus)中,我简单地说:

 if (!hasFocus) { EditText et = (EditText) v.findViewById(R.id.groupAmount); data.get(position).put("dueAmount", et.getText().toString().trim()); } 

在我的示例中,我将input的值存储到用于填充每个getView调用的视图的数据中,但是这仍然会显示如何访问用户input的数据。 只要确保你试图把这个存储的数据,并尝试在相应的位置填充editText。

希望这可以帮助。

在这里发布我的完整适配器以供参考

 public class memberlistadapter extends BaseAdapter { private LayoutInflater mInflater; public ArrayList<Hashtable<String, String>> data; ViewHolder viewHolder; public static HashMap<Integer,String> myList=new HashMap<Integer,String>(); public memberlistadapter(Context context) { mInflater = LayoutInflater.from(context); } public memberlistadapter(Activity activity, ArrayList<Hashtable<String, String>> objects) { super(); mInflater = activity.getLayoutInflater(); //this.activity = activity; this.data = objects; Log.d("data", data.toString()); } public void clear() { this.data.clear(); viewHolder = null; } public void setData(ArrayList<Hashtable<String, String>> data) { this.data = data; } public int getCount() { return data.size(); } public Object getItem(int item) { return data.get(item); } public long getItemId(int position) { return position; } public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = mInflater.inflate(R.layout.member_amount_child, null); viewHolder = new ViewHolder(); viewHolder.nameText = (TextView) convertView.findViewById(R.id.grp_amt_child); viewHolder.amountText = (EditText) convertView.findViewById(R.id.groupAmount); viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.memberCheckNotif); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } //Log.d("data at "+position, data.get(position).toString()); String amt = data.get(position).get("dueAmount"); String name = data.get(position).get("name"); String check = data.get(position).get("reminder"); viewHolder.nameText.setText(name); try { if (amt.length() > 0 && !amt.equalsIgnoreCase("0")) { viewHolder.amountText.setText(amt); } else { viewHolder.amountText.setText(""); } } catch (Exception e) { viewHolder.amountText.setText(""); } viewHolder.amountText.setOnFocusChangeListener(new View.OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { if (!hasFocus) { EditText et = (EditText) v.findViewById(R.id.groupAmount); data.get(position).put("dueAmount", et.getText().toString().trim()); } } }); try { if (check.equalsIgnoreCase("true")) { viewHolder.checkBox.setChecked(true); } else { viewHolder.checkBox.setChecked(false); } } catch (Exception e) { viewHolder.checkBox.setChecked(false); } viewHolder.checkBox.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (((CheckBox) v).isChecked()) { data.get(position).put("reminder", "True"); } else { data.get(position).put("reminder", "False"); } } }); if (position == 0) { viewHolder.checkBox.setVisibility(View.GONE); viewHolder.amountText.setVisibility(View.GONE); viewHolder.nameText.setVisibility(View.GONE); } else { viewHolder.checkBox.setVisibility(View.VISIBLE); viewHolder.amountText.setVisibility(View.VISIBLE); viewHolder.nameText.setVisibility(View.VISIBLE); } return convertView; } static class ViewHolder { TextView nameText; EditText amountText; CheckBox checkBox; } } 

也许你可以试试这个或在右边的相关post部分看到

EditText在ListView中滚动时丢失内容