Can't get values from Listview's EditText?

与世无争的帅哥 提交于 2019-12-04 00:27:32

问题


I'm trying to get data from EditText which is in my Listview. I saw a lot of similar questions & got a solution. But it throws an NPE in my Implementation.

So please guide me to fix this issue.

Adapter

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

UPDATE using TextWatcher

Now i can store the value of the edittext in a Array. But when the listview is scrolled. The values are changed to the intial values.

 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

Entering Data

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

While Scrolling

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

While Reentering value after Scrolling

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

回答1:


The way I would try first would be to add a TextChangedListener to the holder.marks, or you could add a button to save new value entered into the EditText.

When the text changes, I'd change the values in the list. Without this you will lose the data user when the list is scrolled as this line:

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

will re-write the studend mark that was originally in the list.

Edit: I'm putting the Adapter code I found in the link in case it becomes unavailable in the future.

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


}

New Edit:

Remove your GenericTextWatcher and use this instead. When I used your TextWatcher implementation it didn't work, I changed it like this and this works for me.

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



回答2:


You need to remove TextWatcher from edittext before you set text in it

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



回答3:


The reason you're getting a NPE is probably because your getItem is returning null.

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

You need to return the particular position in your Collection(Arraylist)

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



回答4:


Replace this :

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

With this :

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



回答5:


Method you are using:

v = mListView.getChildAt(i);

belongs to ViewGroup superclass and is going to return only currently visible items in your ListView (because they are recycled and there is no reason to keep all of them in memory). Try to set OnClickListener inside getView() method of adapter:

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

Please note, that creating new instance of OnClickListener for each item is usually not necessary and will cause some overhead. You can use single OnClickListener and tags to distinguish items.

Alternatively, you can use ListView's build in listener:

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




回答6:


Listview's getChildAt(i) only returns value for Visible Items on Device not for all items inflated in Adapter so you will get all the view for items visible on screen of a device otherwise null. so try to fetch only visible items view's and to handle NullPointerException you can make a check :

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



回答7:


try this one

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

}



来源:https://stackoverflow.com/questions/39166669/cant-get-values-from-listviews-edittext

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!