Не удается получить значения из EditText Listview?

Я пытаюсь получить данные из EditText, который находится в моем Listview. Я видел много похожих вопросов и получил решение . Но это бросает 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; } } 

По щелчку

 @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 в массиве. Но когда прокручивается список. Значения изменяются на значения intial.

  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

Ввод данных

 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 

Значение Reentering после прокрутки

 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 "Не удается получить значения из EditText Listview?"

Сначала я попытался бы добавить TextChangedListener в файл holder.marks, или вы могли бы добавить кнопку для сохранения нового значения, введенного в EditText.

Когда текст изменится, я изменил бы значения в списке. Без этого вы потеряете пользователя данных, когда список прокручивается по этой строке:

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

Будет перезаписывать знак, который был первоначально включен в список.

Изменить: я помещаю код адаптера, который я нашел в ссылке, в случае, если он станет недоступным в будущем.

 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; } } 

Новое редактирование:

Удалите свой 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()] ); } }); 

Вам нужно удалить TextWatcher из edittext перед тем, как вы установите в нем текст

 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; } 

Вы должны вернуть определенную позицию в своей коллекции (Arraylist)

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

Замените это:

  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 (потому что они переработаны, и нет никаких оснований хранить их все в памяти). Попробуйте установить OnClickListener внутри метода getView () адаптера:

 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); } }; } 

Обратите внимание, что создание нового экземпляра OnClickListener для каждого элемента обычно не является необходимым и вызовет некоторые накладные расходы. Вы можете использовать один OnClickListener и теги для различения элементов.

Кроме того, вы можете использовать сборку ListView в слушателе:

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

Функция getChildAt(i) Listview возвращает значение для видимых элементов на устройстве не для всех элементов, раздутых в адаптере, поэтому вы получите все представление для элементов, видимых на экране устройства, в противном случае – null . Поэтому попробуйте получить только видимые элементы view и обработать NullPointerException вы можете сделать чек:

  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); 

}