问题
I'm creating an android app, in which I'm using recyclerView
and the row of recyclerView is having editText
.
This is my ReadingAdapter
class
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);
}
}
}
This is my ReadingData.java
public class ReadingData {
String pdtName, keyId, openReading, closReading, consumption;
public ReadingData(String pdtName, String keyId) {
this.pdtName = pdtName;
this.keyId = keyId;
}
}
Here, if I enter value in the starting items of the recyclerView
then as I scroll up the items to the bottom of the list, the last item will have that value.
Please ignore the quality of image as we can't upload above of 2MiB of snap.
Here the views are recycled as the list is scrolled. How to prevent the copying values to the other item in the list.
And that Toast
is also repeated several times. How to stop this.
update:
By the suggetion of LQ Gioan through the SO question
How ListView's recycling mechanism works , I got the logic how ListView
actually works with recycling of views.
But I'm not sure whether the recyclerView
also works same.
But here in my case, how can I implement this process. pls someone help me here.
回答1:
RecyclerView
reuse views, in fact it only generate the as many as views that is visible on the screen. so it's expected if you can see a value you set for other rows
The solution would be set all attributes of the view that you are changing to default or whatever the row should present from your data set
So put addTextChangedListener
insode ViewHolder
constructor(you can get position by calling getAdapterPosition()
) for better performance and set the editText
value inside onBindViewHolder
method from your data set
回答2:
Your Activity Code:
ListView listview = (ListView) findViewById(R.id.list_view);
listview.setItemsCanFocus(true);
Adapter adapter = new Adapter (YourActivity.this, YourArrayList);
listview .setAdapter(adapter);
Adapter class
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]);
}}
来源:https://stackoverflow.com/questions/47897770/recyclerview-shows-previous-values-entered-in-an-edittext-in-new-rows