Can't get values from Listview's EditText?

混江龙づ霸主 提交于 2019-12-01 03:37:17

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

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

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

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

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

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
     }

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

}

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