我正在尝试从ListView中的EditText获取数据。我看到了很多类似的问题和得到solution。但它在我的实施中抛出了一个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的值存储在Array中。但滚动列表视图时。值将更改为初始值。
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
滚动后重新输入值
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
答案 0 :(得分:3)
我首先尝试的方法是在holder.marks中添加TextChangedListener,或者添加一个按钮来保存输入EditText的新值。
当文本发生变化时,我会更改列表中的值。如果没有这个,当列表滚动为此行时,您将丢失数据用户:
holder.marks.setText(list.get(position).get("STUDENT_MARK"), TextView.BufferType.EDITABLE);
将重写最初列在该列表中的studend标记。
编辑:我将链接中找到的适配器代码放在链接中,以防将来无法使用。
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()] );
}
});
答案 1 :(得分:1)
在设置文本之前,您需要从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);
答案 2 :(得分:1)
您获得NPE的原因可能是因为您的getItem返回null。
@Override
public Object getItem(int arg0) {
return null;
}
您需要返回Collection(Arraylist)中的特定位置
@Override
public Object getItem(int arg0) {
return list.get(arg0);
}
答案 3 :(得分:-1)
替换它:
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());
}
答案 4 :(得分:-1)
您正在使用的方法:
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);
}
};
}
请注意,通常不需要为每个项创建新的OnClickListener实例,这会导致一些开销。您可以使用单个OnClickListener和标记来区分项目。
或者,您可以在侦听器中使用ListView的构建:
https://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html
答案 5 :(得分:-1)
Listview的getChildAt(i)
仅返回设备上可见项目的值,而不是适用于适配器中所有项目的值,因此您将获得设备屏幕上可见项目的所有视图,否则 null 。因此,尝试仅获取可见项目视图并处理NullPointerException
您可以进行检查:
View v = mListView.getChildAt(i);
if(v!=null){
// your code
}
答案 6 :(得分:-1)
尝试这个
@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);
}