无法从Listview的EditText获取值?

我试图从我的ListView中的EditText获取数据。 我看到了很多类似的问题,并得到了一个解决scheme 。 但是它在我的实现中抛出了一个NPE。

所以请指导我解决这个问题。

适配器

public class Coscho_adapter extends BaseAdapter { Context con; ArrayList<HashMap<String, String>> list; LayoutInflater mInflater; EditText marks; TextView studname, acname; public Coscho_adapter(Context co, ArrayList<HashMap<String, String>> list1) { list = list1; con = co; mInflater = (LayoutInflater) con.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int arg0) { return null; } @Override public long getItemId(int arg0) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null){ holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.sc_item,null,false); holder.marks = (EditText) convertView.findViewById(R.id.marks); holder.studname = (TextView) convertView.findViewById(R.id.stu_name); holder.acname = (TextView) convertView.findViewById(R.id.act_name); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } int sno = position + 1; holder.studname.setText(sno + ". " + list.get(position).get("DESCRIPTOR")); holder.acname.setVisibility(View.GONE); holder.marks.setText(list.get(position).get("STUDENT_MARK"), TextView.BufferType.EDITABLE); int maxLength = 1; holder.marks.setFilters(new InputFilter[] {new InputFilter.LengthFilter(maxLength), new InputFilterMinMax("0", "5")}); desc_ids.add(list.get(position).get("DESCRIPTOR_ID")); return convertView; } class ViewHolder { EditText marks; TextView studname, acname; } } 

ONCLICK

 @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId()==R.id.add) { View v; ArrayList<String> scho = new ArrayList<String>(); EditText et; if (co_adapter.getCount() != 0) { for (int i = 0; i < co_adapter.getCount(); i++) { v = mListView.getChildAt(i); et = (EditText) v.findViewById(R.id.marks); if (et != null) { scho.add(et.getText().toString()); Log.e("SCH", et.getText().toString()); } } } } return super.onOptionsItemSelected(item); } 

屏幕

更新使用TextWatcher

现在我可以将edittext的值存储在数组中。 但是,当列表视图滚动。 这些值被更改为初始值。

  public class Coscho_adapter extends BaseAdapter { Context con; LayoutInflater mInflater; public Scholastic_adapter(Context context, ArrayList<HashMap<String, String>> list1) { sadap_list = list1; con = context; mInflater = LayoutInflater.from(context); } @Override public int getCount() { return sadap_list.size(); } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null){ holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.sc_item,null,false); holder.marks = (EditText) convertView.findViewById(R.id.marks); holder.studname = (TextView) convertView.findViewById(R.id.stu_name); holder.acname = (TextView) convertView.findViewById(R.id.act_name); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } for (int i = 0; i < arrScMarks.length; i++) { Log.e("Array > ", i +"> "+ arrScMarks[i]); } int sno = position + 1; holder.ref = position; holder.studname.setText(sno + ". " + sadap_list.get(holder.ref).get("FIRST_NAME")); holder.acname.setText(sadap_list.get(holder.ref).get("ACTIVITY_NAME")); holder.marks.setText(arrScMarks[holder.ref]); holder.marks.addTextChangedListener(new GenericTextWatcher(holder.ref)); return convertView; } class ViewHolder { EditText marks; TextView studname, acname; int ref; } } 

TextWatcher

 private class GenericTextWatcher implements TextWatcher{ int position; private GenericTextWatcher(int pos) { this.position = pos; } public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} public void afterTextChanged(Editable editable) { String text = editable.toString(); arrScMarks[position] = text; Log.e("Watcher > ", position +"> "+ arrScMarks[position] ); } } 

logcat的

input数据

 09-01 05:37:59.658 2466-2466/app E/Watcher >: 1> 09-01 05:38:00.638 2466-2466/app E/Watcher >: 1> 1 09-01 05:38:02.518 2466-2466/app E/Watcher >: 2> 09-01 05:38:02.798 2466-2466/app E/Watcher >: 2> 2 09-01 05:38:04.478 2466-2466/app E/Watcher >: 3> 09-01 05:38:05.318 2466-2466/app E/Watcher >: 3> 3 09-01 05:38:06.878 2466-2466/app E/Watcher >: 4> 09-01 05:38:07.758 2466-2466/app E/Watcher >: 4> 4 09-01 05:38:09.928 2466-2466/app E/Watcher >: 5> 09-01 05:38:10.278 2466-2466/app E/Watcher >: 5> 5 

滚动

 09-01 05:48:49.188 16362-16362/app E/Watcher >: 0> 0 09-01 05:48:49.538 16362-16362/app E/Watcher >: 1> 0 09-01 05:48:49.708 16362-16362/app E/Watcher >: 2> 0 09-01 05:48:49.888 16362-16362/app E/Watcher >: 3> 0 09-01 05:48:50.268 16362-16362/app E/Watcher >: 4> 0 09-01 05:48:50.538 16362-16362/app E/Watcher >: 5> 0 09-01 05:48:50.558 16362-16362/app E/Watcher >: 6> 0 09-01 05:48:50.868 16362-16362/app E/Watcher >: 8> 0 09-01 05:48:52.708 16362-16362/app E/Watcher >: 9> 0 09-01 05:48:52.768 16362-16362/app E/Watcher >: 0> 0 09-01 05:48:52.768 16362-16362/app E/Watcher >: 10> 0 09-01 05:49:20.648 16362-16362/app E/Watcher >: 9> 0 09-01 05:49:20.648 16362-16362/app E/Watcher >: 18> 0 09-01 05:49:20.738 16362-16362/app E/Watcher >: 8> 0 09-01 05:49:20.738 16362-16362/app E/Watcher >: 17> 0 09-01 05:49:20.818 16362-16362/app E/Watcher >: 7> 0 09-01 05:49:20.888 16362-16362/app E/Watcher >: 5> 0 09-01 05:49:20.888 16362-16362/app E/Watcher >: 15> 0 09-01 05:49:20.898 16362-16362/app E/Watcher >: 4> 0 09-01 05:49:20.898 16362-16362/app E/Watcher >: 14> 0 09-01 05:49:20.968 16362-16362/app E/Watcher >: 3> 0 09-01 05:49:20.968 16362-16362/app E/Watcher >: 13> 0 09-01 05:49:21.068 16362-16362/app E/Watcher >: 6> 0 09-01 05:49:21.068 16362-16362/app E/Watcher >: 16> 0 09-01 05:49:22.008 16362-16362/app E/Watcher >: 1> 0 09-01 05:49:22.008 16362-16362/app E/Watcher >: 11> 0 09-01 05:49:22.058 16362-16362/app E/Watcher >: 0> 0 09-01 05:49:22.058 16362-16362/app E/Watcher >: 10> 0 09-01 05:49:22.058 16362-16362/app E/Watcher >: 10> 0 09-01 05:49:22.098 16362-16362/app E/Watcher >: 9> 0 09-01 05:49:22.098 16362-16362/app E/Watcher >: 18> 0 09-01 05:49:22.108 16362-16362/app E/Watcher >: 9> 0 

滚动后重新input值

 09-01 05:56:32.288 16362-16362/app E/Watcher >: 1> 09-01 05:56:32.288 16362-16362/app E/Watcher >: 10> 09-01 05:56:32.288 16362-16362/app E/Watcher >: 10> 09-01 05:56:32.288 16362-16362/app E/Watcher >: 1> 09-01 05:56:33.438 16362-16362/app E/Watcher >: 1> 1 09-01 05:56:33.438 16362-16362/app E/Watcher >: 10> 1 09-01 05:56:33.438 16362-16362/app E/Watcher >: 10> 1 09-01 05:56:33.438 16362-16362/app E/Watcher >: 1> 1 09-01 05:56:34.918 16362-16362/app E/Watcher >: 11> 09-01 05:56:34.918 16362-16362/app E/Watcher >: 2> 09-01 05:56:36.248 16362-16362/app E/Watcher >: 11> 2 09-01 05:56:36.248 16362-16362/app E/Watcher >: 2> 2 09-01 05:56:37.918 16362-16362/app E/Watcher >: 3> 09-01 05:56:37.918 16362-16362/app E/Watcher >: 12> 09-01 05:56:37.918 16362-16362/app E/Watcher >: 3> 09-01 05:56:39.008 16362-16362/app E/Watcher >: 3> 3 09-01 05:56:39.008 16362-16362/app E/Watcher >: 12> 3 09-01 05:56:39.008 16362-16362/app E/Watcher >: 3> 3 

Solutions Collecting From Web of "无法从Listview的EditText获取值?"

我会先尝试的方法是将一个TextChangedListener添加到holder.marks中,或者您可以添加一个button来保存input到EditText中的新值。

当文字改变时,我会改变列表中的值。 没有这个,当列表滚动为这一行时,你将失去数据用户:

  holder.marks.setText(list.get(position).get("STUDENT_MARK"), TextView.BufferType.EDITABLE); 

将重新编写列表中最初的学生标记。

编辑:我把我在链接中find的适配器代码,以防将来变得不可用。

 private class MyListAdapter extends BaseAdapter{ @Override public int getCount() { // TODO Auto-generated method stub if(arrText != null && arrText.length != 0){ return arrText.length; } return 0; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return arrText[position]; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { //ViewHolder holder = null; final ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); LayoutInflater inflater = ListviewActivity.this.getLayoutInflater(); convertView = inflater.inflate(R.layout.lyt_listview_list, null); holder.textView1 = (TextView) convertView.findViewById(R.id.textView1); holder.editText1 = (EditText) convertView.findViewById(R.id.editText1); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.ref = position; holder.textView1.setText(arrText[position]); holder.editText1.setText(arrTemp[position]); holder.editText1.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable arg0) { // TODO Auto-generated method stub arrTemp[holder.ref] = arg0.toString(); } }); return convertView; } private class ViewHolder { TextView textView1; EditText editText1; int ref; } } 

新build编辑:

删除你的GenericTextWatcher,并用它来代替。 当我用你的TextWatcher实现它没有工作,我改变了这样,这对我的作品。

 holder.getEditText().addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { String text = editable.toString(); ARR[holder.getPosition()] = text; Log.e("Watcher > ", holder.getPosition()+"> "+ ARR[holder.getPosition()] ); } }); 

您需要从edittext中删除TextWatcher,然后在其中设置文本

 if (holder.marks.getTag() != null) { GenericTextWatcher oldWatcher = (GenericTextWatcher) holder.marks.getTag(); holder.marks.removeTextChangedListener(oldWatcher); holder.marks.setText(arrScMarks[holder.ref]); } //then set new textwatcher to edittext with current position GenericTextWatcher watcher; watcher = new GenericTextWatcher(position); holder.marks.addTextChangedListener(watcher); holder.marks.setTag(watcher); 

你得到一个NPE的原因可能是因为你的getItem返回null。

 @Override public Object getItem(int arg0) { return null; } 

您需要返回您的collections(Arraylist)中的特定位置

  @Override public Object getItem(int arg0) { return list.get(arg0); } 

replace这个:

  if (et != null) { // here you check if et,which is a textview if its null scho.add(et.getText().toString()); Log.e("SCH", et.getText().toString()); } 

有了这个 :

  if (et.getText().toString()) { // check if the text is null scho.add(et.getText().toString()); Log.e("SCH", et.getText().toString()); } 

您正在使用的方法:

 v = mListView.getChildAt(i); 

属于ViewGroup超类,并且将仅返回ListView中当前可见的项目(因为它们被回收并且没有理由将其全部保留在内存中)。 尝试在适配器的getView()方法中设置OnClickListener:

 public View getView(final int position, View convertView, ViewGroup parent) { ... convertView.setOnClickListener(new OnClickListener() { public void onClick(View v) { ... et = (EditText) v.findViewById(R.id.marks); } }; } 

请注意,为每个项目创buildOnClickListener的新实例通常是没有必要的,并会导致一些开销。 您可以使用单个OnClickListener和标签来区分项目。

或者,您可以在侦听器中使用ListView的构build:

https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html

ListView的getChildAt(i)只返回适配器上Visible Items的值,不适用于适配器中所有充气的项目,因此您将获得设备屏幕上可见的项目的所有视图,否则为null 。 所以尝试只提取可见项目视图和处理NullPointerExceptionexception,你可以检查:

  View v = mListView.getChildAt(i); if(v!=null){ // your code } 

试试这个

 @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId()==R.id.add) { ArrayList<String> scho = new ArrayList<String>(); EditText et; if (mListView.getChildCount() > 0) { for (int i = 0; i < mListView.getChildCount(); i++) { // if your view statrts with relative layout then RelativeLayout rl=(RelativeLayout)mListView.getChildAt(i); // else yourlayout lay =(yourlayout)mListView.getChildAt(i); EditText et=(EditText)lay.getChildAt(your edit text positin in lay) // main thing is we have to follow chain logic to find out the EditText position System.out.println(et.getText().toString()); } } } return super.onOptionsItemSelected(item); 

}