Android RecyclerView在新行中显示以前在EditText中输入的值
我正在创建一个android应用程序,其中我正在使用Android RecyclerView在新行中显示以前在EditText中输入的值,android,android-recyclerview,addtextchangedlistener,Android,Android Recyclerview,Addtextchangedlistener,我正在创建一个android应用程序,其中我正在使用recyclerView,recyclerView的行具有editText 这是我的ReadingAdapter课程 public class ReadingAdapter extends RecyclerView.Adapter<ReadingAdapter.ViewHolder> implements AdapterView.OnItemSelectedListener { Context context;
recyclerView
,recyclerView的行具有editText
这是我的ReadingAdapter
课程
public class ReadingAdapter extends RecyclerView.Adapter<ReadingAdapter.ViewHolder> implements AdapterView.OnItemSelectedListener {
Context context;
String valOpenReading, valClosReading, valConsumption;
private List<ReadingData> readingList;
static String[] arrValOpenRead, arrValClosRead, arrValConsumption;
public ReadingAdapter(Context context, List<ReadingData> readingList) {
this.context = context;
this.readingList = readingList;
arrValOpenRead = new String[readingList.size()];
arrValClosRead = new String[readingList.size()];
arrValConsumption = new String[readingList.size()];
}
@Override
public ReadingAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.reading_sheet_layout, parent, false);
return new ReadingAdapter.ViewHolder(view);
}
@Override
public void onBindViewHolder(final ReadingAdapter.ViewHolder holder, final int position) {
ReadingData tempData = readingList.get(position);
holder.pdtName.setText(tempData.pdtName);
holder.keyId.setText("Key "+tempData.keyId);
holder.etClosRead.addTextChangedListener(new TextWatcher() {
boolean ignore = false;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (ignore)
return;
ignore = true;
valOpenReading = holder.etOpenRead.getText().toString();
arrValOpenRead[position] = valOpenReading;
valClosReading = s.toString().equals("") ? "0": s.toString();
arrValClosRead[position] = valClosReading;
if (!valOpenReading.equals("")) {
if (Integer.parseInt(valClosReading) < Integer.parseInt(valOpenReading)) {
Toast.makeText(context, "Check once! closing reading should be more than opening reading!", Toast.LENGTH_LONG).show();
valConsumption = "0";
holder.consumption.setText("");
} else {
valConsumption = (Integer.parseInt(valClosReading) - Integer.parseInt(valOpenReading))+"";
arrValConsumption[position] = valConsumption;
holder.consumption.setText(valConsumption);
}
} else
Toast.makeText(context, "Please fill the opening reading!", Toast.LENGTH_SHORT).show();
ignore = false;
}
});
}
@Override
public int getItemCount() {
return readingList.size();
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView pdtName, keyId, consumption;
EditText etOpenRead, etClosRead;
public ViewHolder(View view) {
super(view);
pdtName = (TextView)view.findViewById(R.id.txt_list_pdt_supp);
keyId = (TextView)view.findViewById(R.id.key_set);
etOpenRead = (EditText)view.findViewById(R.id.open_val_set);
etClosRead = (EditText)view.findViewById(R.id.clos_val_set);
consumption = (TextView)view.findViewById(R.id.consumption_val);
}
}
}
在这里,如果我在recyclerView
的起始项中输入值,那么当我向上滚动到列表底部时,最后一项将具有该值
请忽略图像质量,因为我们无法上传超过2MiB的快照
在这里,当列表滚动时,视图被循环使用。如何防止将值复制到列表中的其他项
而且,这个Toast
也重复了好几次。如何阻止这一切
更新:
通过SO问题
的建议,我得到了ListView
实际如何处理视图循环的逻辑
但我不确定recyclerView
是否也能正常工作
但在我的例子中,我如何实现这个过程。请有人在这里帮助我。您的活动代码:
ListView listview = (ListView) findViewById(R.id.list_view);
listview.setItemsCanFocus(true);
Adapter adapter = new Adapter (YourActivity.this, YourArrayList);
listview .setAdapter(adapter);
适配器类
public class Adapter extends BaseAdapter {
// Declare Variables \\
Context mContext;
LayoutInflater inflater;
Activity act;
String[] temp;
public Adapter(Context context, ArrayList<String> list) {
mContext = context;
inflater = LayoutInflater.from(mContext);
act = (Activity) context;
//-------Temp String Array-------\\
temp = new String[this.count];
for (int i = 0; i < this.count; i++) {
temp[i] = list.get(i);
}
//---------------------------\\
}
public class ViewHolder {
TextView optionTitle;
EditText optionText;
int ref;
}
@Override
public int getCount() {
return list.size;
}
@Override
public Object getItem(int position) {
return temp[position];
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.lv_items_add_ques_options_mcq, null);
holder.optionTitle = (TextView) view.findViewById(R.id.add_ques_opts_count_mcq_tv);
holder.optionText = (EditText) view.findViewById(R.id.add_ques_opts_title_mcq_et);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.ref = position;
holder.optionTitle.setText(getCharForNumber(position) + ":");
holder.optionText.setText(temp[position]);
holder.optionText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
temp[holder.ref] = arg0.toString().trim();
}
});
return view;
}
public void getList() {
StaticValues.arrayListOptions = new ArrayList<String>(Arrays.asList(temp));
StaticValues.arrayListOptionsCount = new ArrayList<String>();
for (int i = 0; i < count; i++) {
StaticValues.arrayListOptionsCount.add(String.valueOf(i+1));
Log.e("err_al", StaticValues.arrayListOptions.get(i));
Log.e("err_al", StaticValues.arrayListOptionsCount.get(i));
}
}
private String getCharForNumber(int i) {
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
if (i > 25) {
return null;
}
return Character.toString(alphabet[i]);
}}
公共类适配器扩展了BaseAdapter{
//声明变量\\
语境;
充气机;
活动法;
字符串[]温度;
公共适配器(上下文、ArrayList列表){
mContext=上下文;
充气器=从(mContext)开始的充气器;
act=(活动)上下文;
//-------临时字符串数组-------\\
temp=新字符串[this.count];
for(int i=0;i25){
返回null;
}
返回字符.toString(字母[i]);
}}
RecyclerView
重用视图,实际上它只生成屏幕上可见的多达个视图。因此,如果您可以看到为其他行设置的值,则会出现这种情况
解决方案是将要更改为默认值的视图的所有属性或数据集中该行应显示的任何属性设置为默认值
因此,将
addTextChangedListener
放入deViewHolder
构造函数中(您可以通过调用getAdapterPosition()
获得位置)为了获得更好的性能,请在数据集中的onBindViewHolder
方法中设置editText
值ListView
重用屏幕上不可见的项目视图。你应该看看这个答案以了解:。要解决您的问题,您应该将用户留下的数据保存在ReadingData
中。每次调用getView
方法时,您都会将这些数据设置回EditText
(s),感谢您的链接。现在我了解了listView
的工作原理。但是在我的案例中我应该使用什么呢?我如何在不重复使用视图的情况下实现这一点?我应该在这里使用recyclerView
吗?如果您想在不循环的情况下使用ListView
,那么您可以删除代码中的If(convertView==null)
。但是,如果列表中有很多项,则可以从MemoryException中获取OutOfMemoryException
。因此,我强烈建议您在ListView
中使用回收。您可以在我的第一条注释中尝试我的解决方案。ReadingData
是为绑定变量而创建的。很抱歉,我不明白解决办法。您可以使用TextWatcher
查看用户使用EditText.addTextChangedListener(TextWatcher)
()输入的任何内容。然后,将新变量添加到ReadingData
(或创建一个新对象->由您决定)以保留这些输入数据。只要调用getView
方法,您就可以将这些输入数据设置回编辑文本。谢谢您的回答。是从适配器返回的视图,不是被回收的?我们把编辑文本数据保存到一个用来保存数据的临时数组中,这样即使它被回收了,你的数据也是完整的。
public class Adapter extends BaseAdapter {
// Declare Variables \\
Context mContext;
LayoutInflater inflater;
Activity act;
String[] temp;
public Adapter(Context context, ArrayList<String> list) {
mContext = context;
inflater = LayoutInflater.from(mContext);
act = (Activity) context;
//-------Temp String Array-------\\
temp = new String[this.count];
for (int i = 0; i < this.count; i++) {
temp[i] = list.get(i);
}
//---------------------------\\
}
public class ViewHolder {
TextView optionTitle;
EditText optionText;
int ref;
}
@Override
public int getCount() {
return list.size;
}
@Override
public Object getItem(int position) {
return temp[position];
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.lv_items_add_ques_options_mcq, null);
holder.optionTitle = (TextView) view.findViewById(R.id.add_ques_opts_count_mcq_tv);
holder.optionText = (EditText) view.findViewById(R.id.add_ques_opts_title_mcq_et);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.ref = position;
holder.optionTitle.setText(getCharForNumber(position) + ":");
holder.optionText.setText(temp[position]);
holder.optionText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
temp[holder.ref] = arg0.toString().trim();
}
});
return view;
}
public void getList() {
StaticValues.arrayListOptions = new ArrayList<String>(Arrays.asList(temp));
StaticValues.arrayListOptionsCount = new ArrayList<String>();
for (int i = 0; i < count; i++) {
StaticValues.arrayListOptionsCount.add(String.valueOf(i+1));
Log.e("err_al", StaticValues.arrayListOptions.get(i));
Log.e("err_al", StaticValues.arrayListOptionsCount.get(i));
}
}
private String getCharForNumber(int i) {
char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
if (i > 25) {
return null;
}
return Character.toString(alphabet[i]);
}}