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.
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
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]);
}}
Related
I have a RecyclerView in my android project. There I am adding rows from searching from a AutoCompleteTextView. Each row has TextView and one EditText field. As well as adding, I am also removing rows. I have a remove button in a each row.
Everything works fine. Problem is I cannot clear EditText value in removing. For example if I add three rows and remove the second one, the third row should come to second place with its own EditText value. But the problem is, the value from the row removed is not clearing and the third row's EditText value is replaced by it instead. Then if I add another row (to the third place), automatically that EditText field is filled with previous third row's EditText value.
How can I clear EditText value also???
This is my adapter code.
public class SelectItemAdapter extends RecyclerView.Adapter<SelectItemAdapter.ItemHolder> {
private List<String> itemsName, itemsQty, itemsPCode, itemPlant, _retData;
private OnItemClickListener onItemClickListener;
private LayoutInflater layoutInflater;
private String[] mDataset;
public ArrayList myItems = new ArrayList();
private Context context;
private String[] arrayForSaveEditTextValue;
public SelectItemAdapter(Context context, String[] mDataset) {
layoutInflater = LayoutInflater.from(context);
itemsName = new ArrayList<String>();
itemsQty = new ArrayList<String>();
itemsPCode = new ArrayList<String>();
itemPlant = new ArrayList<String>();
_retData = new ArrayList<String>();
this.arrayForSaveEditTextValue = mDataset;
}
#Override
public SelectItemAdapter.ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = layoutInflater.inflate(R.layout.custom_row_selected_item, parent, false);
return new ItemHolder(itemView, this);
}
#Override
public void onBindViewHolder(final SelectItemAdapter.ItemHolder holder, final int position) {
holder.setItemName(itemsName.get(position));
holder.setItemQty(itemsQty.get(position));
holder.setItemPCode(itemsPCode.get(position));
holder.setItemPlant(itemPlant.get(position));
holder.numPicker.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) {
_retData.set(position, arg0.toString());
Log.d("arg0",arg0.toString());
}
});
}
#Override
public int getItemViewType(int position) {
return position;
}
public String retrieveData(int i) {
return _retData.get(i);
}
#Override
public int getItemCount() {
return itemsName.size();
}
public Object getItemName(int position) {
return itemsName.get(position);
}
public Object getItemQty(int position) {
return itemsQty.get(position);
}
public Object getItemPCode(int position) {
return itemsPCode.get(position);
}
public Object getItemPlant(int position) {
return itemPlant.get(position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
onItemClickListener = listener;
}
public OnItemClickListener getOnItemClickListener() {
return onItemClickListener;
}
public interface OnItemClickListener {
public void onItemClick(ItemHolder item, int position);
}
public void add(int location, String iName, String iQty, String iPCode, String iPlant) {
itemsName.add(location, iName);
itemsQty.add(location, iQty);
itemsPCode.add(location, iPCode);
itemPlant.add(location, iPlant);
_retData.add(location,"0");
notifyItemInserted(location);
notifyDataSetChanged();
}
public void remove(int location) {
if (location >= itemsName.size())
return;
itemsName.remove(location);
itemsQty.remove(location);
itemsPCode.remove(location);
itemPlant.remove(location);
_retData.remove(location);
notifyItemRemoved(location);
notifyDataSetChanged();
}
public static class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private SelectItemAdapter parent;
TextView textItemName, txtPCode, txtAvailableQty, txtTempQty, txtPlant;
Button bRemove;
EditText numPicker;
public ItemHolder(View itemView, SelectItemAdapter parent) {
super(itemView);
this.parent = parent;
textItemName = (TextView) itemView.findViewById(R.id.txtProductName);
txtAvailableQty = (TextView) itemView.findViewById(R.id.txtAvailbleQty);
txtPCode = (TextView) itemView.findViewById(R.id.txtPCode);
txtPlant = (TextView) itemView.findViewById(R.id.txtPlant);
bRemove = (Button) itemView.findViewById(R.id.bRemove);
numPicker = (EditText) itemView.findViewById(R.id.numberPicker);
bRemove.setOnClickListener(this);
}
public void setItemName(CharSequence name) {
textItemName.setText(name);
}
public void setItemQty(CharSequence name) {
txtAvailableQty.setText(name);
}
public void setItemPCode(CharSequence name) {
txtPCode.setText(name);
}
public void setItemPlant(CharSequence name) {
txtPlant.setText(name);
}
public CharSequence getItemName() {
return textItemName.getText();
}
#Override
public void onClick(View v) {
final OnItemClickListener listener = parent.getOnItemClickListener();
if (listener != null) {
listener.onItemClick(this, getPosition());
}
}
}
public class RetItem {
public String _itemNumPic;
}
}
And the remove method...
#Override
public void onItemClick(SelectItemAdapter.ItemHolder item, int position) {
Toast.makeText(this,
"Remove " + " : " + item.getItemName(),
Toast.LENGTH_SHORT).show();
myRecyclerViewAdapter.remove(position);
}
First of all use a list of an Object instead of using lots of string arrays!
and then to achieve the behavior you want, you need to remove the item from the main list and call notifyDataSetChanged();
Here is an ex:
List<DayEntity> days = new ArrayList<>();
Here is a list of day items, you set this list to your adapter like this:
MyDayAdapter adapter = new MyDayAdapter(context, days);
So for removing an item in position 'x' you can do this way:
days.remove(x);
adapter.notifyDataSetChanged();
have fun...
1- Create a model class for your data, with all your getters and setters in one list:
public class SelectItemAdapter extends RecyclerView.Adapter<SelectItemAdapter.ItemHolder> {
private final ArrayList<MyData> mDataList = new ArrayList<>();
2- remove at method
//Remove from the list on click
private void removeAt(int position) {
mUserList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mDataList.size());
}
3- Now inside onClick() method you can call removeAt method, and you just pass the position which is the adapter position
removeAt(getAdapterPosition());
You need to keep track of the values entered in the EditText of your RecyclerView. You've an array named arrayForSaveEditTextValue for saving the EditText values I think, but I see no usage of it. Your code is a little bit clumsy too. So I would like to suggest a different approach of implementing this list for you.
Create an object for your list items.
public class ListItem {
public String itemsName;
public String itemsQty;
public String itemsPCode;
public String itemPlant;
public String _retData;
public String editTextValue = ""; // Default EditText Value
}
And your adapter should look like this.
public class SelectItemAdapter extends RecyclerView.Adapter<SelectItemAdapter.ItemHolder> {
private List<ListItem> listItems;
private OnItemClickListener onItemClickListener;
private LayoutInflater layoutInflater;
public SelectItemAdapter(Context context, List<ListItem> listItems) {
layoutInflater = LayoutInflater.from(context);
this.listItems = listItems;
}
#Override
public SelectItemAdapter.ItemHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = layoutInflater.inflate(R.layout.custom_row_selected_item, parent, false);
return new ItemHolder(itemView, this);
}
#Override
public void onBindViewHolder(final SelectItemAdapter.ItemHolder holder, final int position) {
final ListItem tempListItem = listItems.get(position);
holder.textItemName.setText(tempListItem.itemsName);
holder.txtAvailableQty.setText(tempListItem.itemsQty);
holder.txtPCode.setText(tempListItem.itemsPCode);
holder.txtPlant.setText(tempListItem.itemPlant);
holder.numPicker.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) {
// Calculate your _retData and set the TextView
tempListItem._retData = calculateRetData(position, arg0.toString());
tempListItem.editTextValue = arg0.toString();
// Replace the item with the value updated
listItems.add(position, tempListItem);
notifyDataSetChanged();
}
});
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getItemCount() {
return listItems.size();
}
public void setOnItemClickListener(OnItemClickListener listener) {
onItemClickListener = listener;
}
public OnItemClickListener getOnItemClickListener() {
return onItemClickListener;
}
public interface OnItemClickListener {
public void onItemClick(ItemHolder item, int position);
}
public void add(ListItem listItem) {
listItems.add(listItem);
notifyDataSetChanged();
}
public void remove(int location) {
if (location >= listItems.size())
return;
listItems.remove(location);
notifyDataSetChanged();
}
public static class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private SelectItemAdapter parent;
TextView textItemName, txtPCode, txtAvailableQty, txtTempQty, txtPlant;
Button bRemove;
EditText numPicker;
public ItemHolder(View itemView, SelectItemAdapter parent) {
super(itemView);
this.parent = parent;
textItemName = (TextView) itemView.findViewById(R.id.txtProductName);
txtAvailableQty = (TextView) itemView.findViewById(R.id.txtAvailbleQty);
txtPCode = (TextView) itemView.findViewById(R.id.txtPCode);
txtPlant = (TextView) itemView.findViewById(R.id.txtPlant);
bRemove = (Button) itemView.findViewById(R.id.bRemove);
numPicker = (EditText) itemView.findViewById(R.id.numberPicker);
bRemove.setOnClickListener(this);
}
#Override
public void onClick(View v) {
final OnItemClickListener listener = parent.getOnItemClickListener();
if (listener != null) {
listener.onItemClick(this, getPosition());
}
}
}
}
The idea is to save the EditText value in the corresponding object and in case of adding and deleting an item from the RecyclerView, you have to update the list of the items accordingly and then call notifyDataSetChanged().
I haven't tested the code, but I think you get the idea. Please let me know if there's anything else I can help you with.
Recyclerview has 4 items i.e; textView1, textView2, EditText1 and Checkbox1.
Recyclerview has got 24 rows as well. EditText is invisible on initial stage thenit will be visible only when the corresponding checkbox checked by the user. EditText accepts only numbers.
The app is working fine so far this much.
Now I need to get value of all EditTexts and need to display it on another Textview which is not in the part of Recyclerview?
Recyclerview Screenshot- Output Link
Code Samples.
ExamFragment.java
public class ExamFragment extends Fragment {
RecyclerView recyclerView;
ExamFragmentAdapter adapter;
ArrayList<tblChapters> datalistChapters = new ArrayList<>();
TextView txtQcount,txtQCounttotal;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.fragment_exam, container, false);
txtQCounttotal=(TextView) v.findViewById(R.id.txtQCounttotal);
txtQcount=(TextView) v.findViewById(R.id.txtQCount);
recyclerView=(RecyclerView)v.findViewById(R.id.recycler_view);
conn = new ConnectionClass(); //connection initialisation
datalistChapters = conn.getChaptersAndCount(modeid, subjectid);
adapter = new ExamFragmentAdapter(datalistChapters, getActivity());
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
return v;
}
}
ExamFragmentAdapter.java
public class ExamFragmentAdapter extends RecyclerView.Adapter<ExamFragmentAdapter.MyViewHolder> {
private LayoutInflater inflater;
MyViewHolder holder;
Context mContext;
ArrayList<tblChapters> chapterList=new ArrayList<>();
public ExamFragmentAdapter(ArrayList<tblChapters> chapterList, Context context) {
inflater = LayoutInflater.from(context);
this.chapterList = chapterList;
mContext=context;
}
#Override
public ExamFragmentAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.chapter_list_row, parent, false);
holder = new MyViewHolder(view, new MyCustomEditTextListener());
return holder;
}
#Override
public void onBindViewHolder(final ExamFragmentAdapter.MyViewHolder holder, final int position) {
holder.title.setTextColor(Color.BLACK);
holder.slno.setTextColor(Color.BLACK);
holder.noOfQst.setTextColor(Color.BLACK);
holder.noOfQst.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
holder.noOfQst.setGravity(Gravity.CENTER);
holder.title.setText(chapterList.get(position).getTitle()); // Setting Chapter title
holder.slno.setText(String.valueOf(position + 1)+"."); //Setting sl no
holder._myCustomEditTextListener.updatePosition(position);
holder.noOfQst.setText(chapterList.get(position).getNoofQstns()); //Setting no of qstn
if (chapterList.get(position).isVisibled()) {
holder.noOfQst.setVisibility(View.VISIBLE);
} else {
holder.noOfQst.setVisibility(View.INVISIBLE);
}
//in some cases, it will prevent unwanted situations
holder.cbox.setOnCheckedChangeListener(null);
//if true, your checkbox will be selected, else unselected
holder.cbox.setChecked(chapterList.get(position).isSelected());
holder.cbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//set your object's last status
chapterList.get(position).setSelected(isChecked);
chapterList.get(position).setVisibled(isChecked);
//if checkbox checked display EditText(No of qstns), else hide it.
if (holder.cbox.isChecked()) {
holder.noOfQst.setVisibility(View.VISIBLE);
holder.noOfQst.requestFocus();
holder.noOfQst.setText("10");
chapterList.get(position).setNoofQstns(holder.noOfQst.getText().toString());
/* txtQcount.setText("0");
if (txtQcount.getText().toString().equals("")) {
txtQcount.setText("0");
}
txtQcount.setText(Integer.valueOf(txtQcount.getText().toString())+Integer.parseInt(holder.noOfQst.getText().toString()));*/
}
else {
holder.noOfQst.setVisibility(View.INVISIBLE);
holder.noOfQst.setText(""); //remove entered value when uncheck
chapterList.get(position).setNoofQstns("");
}
}
});
}
// we make TextWatcher to be aware of the position it currently works with
// this way, once a new item is attached in onBindViewHolder, it will
// update current position MyCustomEditTextListener, reference to which is kept by ViewHolder
private class MyCustomEditTextListener implements TextWatcher
{
private int position;
private String oldval;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
// no op
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
chapterList.get(position).setNoofQstns(charSequence.toString());
int j = i;
j = i2;
j = i3;
}
#Override
public void afterTextChanged(Editable editable) {
}
}
#Override
public int getItemCount() {
return chapterList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView title;
CheckBox cbox;
TextView slno;
EditText noOfQst;
public MyCustomEditTextListener _myCustomEditTextListener;
public MyViewHolder(View itemView,MyCustomEditTextListener myCustomEditTextListener) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.txtTitle);
cbox = (CheckBox) itemView.findViewById(R.id.cboxChapter);
slno = (TextView) itemView.findViewById(R.id.txtRowSlno);
noOfQst = (EditText) itemView.findViewById(R.id.etNoOfQstns);
this._myCustomEditTextListener = myCustomEditTextListener;
try {
if (noOfQst.getVisibility() == View.VISIBLE) {
holder.noOfQst.setVisibility(View.INVISIBLE);
//adding textchange listener to no of qstn(EditText)
noOfQst.addTextChangedListener(myCustomEditTextListener);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
You can register an AdapterDataObserver for the recycler view adapter.
For each item in the adapter when it's updated (user updates the EditText), the adapter can call notifyItemChanged(int position, Object payload). the observer will receive the payload in its onItemRangeChanged (int positionStart, int itemCount, Object payload) callback, you can pass whatever you want in the payload object so that you accumulate the values of all the EditTexts.
You can also unregister the observer in your Activity/Fragment onStop by calling unregisterAdapterDataObserver
I write a simple test code about shopping. It's like in the picture.add from right to left
It's simple. ListViews show 'Item's. The 'Item' has only name and count. On the right, I change the count and add the item to the cart on the left.
The main point is here, when I change the item's count that I added earlier and add the item again to the cart, all the same items in the cart and in the menu changes to the last count.
After I took the first picture, I changed the same item's count and added it again. So, two items in the cart have same last count. I can't understand the mistake in the code. Second screenshot after added the same item with different count
Thanks in advance.
I found something about the code. All the ArrayLists are acting like they are static. If I change the onClick metot of add button in the menu as:
ImageButton ekle = (ImageButton) view.findViewById(R.id.imageButton2);
ekle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//After changing this row, all the ArrayList's (menu and cart) items
//in this position is changing to the same number 5.
//And I delete the EditText's TextChangeListener, as well.
menu.get(position).setCount(5);
((BaseAdapter) context.list1.getAdapter()).notifyDataSetChanged();
}
});
public class Item {
private String name;
private int count;
public Item(String s, int i) {
name = s;
count = i;
}
public String getName() {return name;}
public int getCount() {return count;}
public void setName(String s) {name = s;}
public void setCount(int i) {count = i;}
}
public class MainActivity extends AppCompatActivity {
ListView list1;
ListView list2;
static ArrayList<Item> menu = new ArrayList<>();
static ArrayList<Item> cart = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
menu.add(new Item("Item1", 1));
menu.add(new Item("Item2", 1));
menu.add(new Item("Item3", 1));
menu.add(new Item("Item4", 1));
menu.add(new Item("Item5", 1));
list1 = (ListView) findViewById(R.id.list1);
list1.setAdapter(new CartAdapter(this, cart));
list2 = (ListView) findViewById(R.id.list2);
list2.setAdapter(new MenuAdapter(this, menu));
}
}
public class CartAdapter extends BaseAdapter {
MainActivity context;
ArrayList<Item> cart;
public CartAdapter(Activity activity, ArrayList<Item> m) {
context = (MainActivity) activity;
cart = m;
}
#Override
public int getCount() {
return cart.size();
}
#Override
public Object getItem(int position) {
return cart.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_list, null);
TextView name = (TextView) view.findViewById(R.id.textView);
name.setText(cart.get(position).getName());
EditText count = (EditText) view.findViewById(R.id.editText);
count.setText("" + cart.get(position).getCount());
return view;
}
}
public class MenuAdapter extends BaseAdapter {
MainActivity context;
ArrayList<Item> menu;
public MenuAdapter(Activity activity, ArrayList<Item> m) {
context = (MainActivity) activity;
menu = m;
}
#Override
public int getCount() {
return menu.size();
}
#Override
public Object getItem(int position) {
return menu.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.item_list2, null);
ImageButton ekle = (ImageButton) view.findViewById(R.id.imageButton2);
ekle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity.cart.add(menu.get(position));
((BaseAdapter) context.list1.getAdapter()).notifyDataSetChanged();
}
});
TextView name = (TextView) view.findViewById(R.id.textView2);
name.setText(menu.get(position).getName());
EditText miktar = (EditText) view.findViewById(R.id.editText2);
miktar.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (count != 0) {
int i = Integer.parseInt(s.toString());
Item item = menu.get(position);
item.setCount(i);
MainActivity.menu.set(position, item);
CharSequence text = menu.get(position).getName() +" : "+ menu.get(position).getCount();
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
return view;
}
#Override
public void notifyDataSetChanged() {
super.notifyDataSetChanged();
}
}
I found the cause of the problem. The both ArrayLists act like static (but they are not!). So I changed the decleration of the Item class, made count final. And that's it, problem is solved.
public class Item
{
private String name;
private final int count;
public Item(String s, int i) {
name = s;
count = i;
}
public String getName() {return name;}
public int getCount() {return count;}
public void setName(String s) {name = s;}
}
Here is my adapter code where on edit field edited am calculating the 2 other fields and displaying through TextWatcher. There are 2 issues here.
1. On scroll the values are changing to default values
2. How can I take the new values updated on click of a button
Please help...thanks.
public class ItemListAdapter extends BaseAdapter {
private ArrayList<Itemlist> mProductList,medicineList;
private LayoutInflater mInflater;
String newEditValu[];
Itemlist curProduct;
Itemlist list;
DataTranrfer df;
public ItemListAdapter(ArrayList<Itemlist> list, LayoutInflater inflater) {
mProductList = list;
mInflater = inflater;
}
#Override
public int getCount() {
return mProductList.size();
}
#Override
public Object getItem(int position) {
return mProductList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewItem item;
final int pos=position;
medicineList=new ArrayList<Itemlist>();
if (convertView == null) {
convertView = mInflater.inflate(R.layout.activity_medicine_list,null);
item = new ViewItem();
item.medicineTitle = (TextView) convertView.findViewById(R.id.tvMedicineName);
item.medcineQuantity =(EditText)convertView.findViewById(R.id.etQuantity);
item.itemDaily=(TextView)convertView.findViewById(R.id.tvDailyText);
item.itemNdays=(TextView)convertView.findViewById(R.id.tvNodays);
item.itemTotal = (TextView)convertView.findViewById(R.id.tvCost);
convertView.setTag(item);
ImageButton b2 = (ImageButton) convertView.findViewById(R.id.thumbnail);
b2.setTag(position);
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
int pos = (int)arg0.getTag();
mProductList.remove(pos);
ItemListAdapter.this.notifyDataSetChanged();
}
});
convertView.setTag(item);
} else {
item = (ViewItem) convertView.getTag();
}
curProduct = mProductList.get(position);
item.ref=position;
item.medicineTitle.setText(curProduct.getmedicineName());
item.itemDaily.setText("Daily: " + curProduct.getMedicineDaily());
item.itemNdays.setText("Days: " + curProduct.medicineNoDays);
item.itemTotal.setText("Rs." + curProduct.getMedicineTotal());
item.medcineQuantity.setText("" + curProduct.getMedicineQuantity());
ItemListAdapter.this.notifyDataSetChanged();
item.medcineQuantity.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//ItemListAdapter.this.notifyDataSetChanged();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
System.out.print("edit response" + s.toString());
Itemlist curProduct = mProductList.get(position);
if (item.medcineQuantity.getText().length() >= 0) {
double dItemcost = Double.parseDouble(curProduct.getMedicineCost());
double dItemDaily = Double.parseDouble(curProduct.getMedicineDaily());
double dItemQuantity = Double.parseDouble(item.medcineQuantity.getText().toString());
//double dItemQuantity = Double.parseDouble(myList.get(pos));
double dItemDays = (dItemQuantity / dItemDaily);
double dItemTotal = (dItemQuantity * dItemcost);
item.medcineQuantity.setText("" +myList.get(pos));
item.itemNdays.setText("Days: " + dItemDays);
item.itemTotal.setText("Rs." + dItemTotal);
list=new Itemlist();
list.setmedicineName(curProduct.getmedicineName());
list.setMedicineDaily(curProduct.getMedicineDaily());
list.setMedicineQuantity(dItemQuantity);
list.setMedicineCost("" + dItemcost);
list.setMedicineTotal(dItemTotal);
medicineList.add(list);
for(int i=0;i<medicineList.size();i++)
{
System.out.println("medicine list"+medicineList.toString());
System.out.println("medicine total at"+i+":"+medicineList.get(i).getMedicineTotal());
}
}
}
});
return convertView;
}
private class ViewItem {
TextView medicineTitle,itemDaily,itemNdays,itemTotal;
EditText medcineQuantity;
int ref;
}
}
I am using a custom list view which contains two Buttons Yes or No. When I clicked on No button, a layout containing an edit text will be displayed. There are more than 15 items in the list view. When I tried to type and save the value in the edittext of the 1st item using TextWatcher(), then the value is save for both 5th and 1st position ie, the same value is saving in both 1st and 5th position.
The code I am using is:
holder.subQuestionAnswer.addTextChangedListener( new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
questionsModel.get(position).getQuestion_subquestion().get(0).setAnswer(holder.subQuestionAnswer.getText()
.toString());
Log.e("value", "no_active<>"+position+"<>"+questionsModel.get(position).getQuestion_subquestion().get(0).getAnswer().toString());
}
});
}
How can i avoid this?
It is because of recycling of view. Please check the following adapter. Use the logic according to your needs.
public class MultiSelectionProductAdapter extends ArrayAdapter<ProductListBean> {
private Context context;
private ArrayList<ProductListBean> productList;
private ArrayList<ProductListBean> mOriginalValues;
private LayoutInflater li;
public MultiSelectionProductAdapter(Context ctx, int simpleListItem1,
ArrayList<ProductListBean> data) {
super(ctx, simpleListItem1, data);
this.context = ctx;
this.productList = data;
li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return productList.size();
}
#Override
public ProductListBean getItem(int position) {
return productList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = li.inflate(R.layout.component_inventory_prod_list, null);
holder = new ViewHolder();
holder.tvProductName = (TextView) convertView.findViewById(R.id.tvProductName);
holder.tvProdShortCode = (TextView) convertView.findViewById(R.id.tvShortName);
holder.tvLastOrderedQty = (TextView) convertView.findViewById(R.id.tvLastOrderedQty);
holder.etQty = (EditText) convertView.findViewById(R.id.etQty);
holder.parentRL = (LinearLayout) convertView.findViewById(R.id.parentRL);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final ProductListBean tempBean = productList.get(position);
holder.etQty.setId(position);
final String productName = tempBean.getProductName();
final String productCode = tempBean.getProductCode();
final String productShortCode = tempBean.getProductShortCode();
if (mSelectedProd != null && mSelectedProd.contains(productCode)) {
final int indexOfProd = mSelectedProd.indexOf(productCode);
holder.etQty.setText(mSelectedProducts.get(indexOfProd).getEnteredQty());
}
holder.tvProductName.setText(productName);
holder.tvProdShortCode.setText(productShortCode);
holder.tvLastOrderedQty.setText(tempBean.getLastOrderedQty());
holder.etQty.setText(tempBean.getEnteredQty());
holder.parentRL.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
holder.etQty.requestFocus();
}
});
holder.etQty.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
final int pos = holder.etQty.getId();
final String qty = holder.etQty.getText().toString();
if (qty.length() > 0) {
if (String.valueOf(qty.charAt(0)).equals("0")) {
holder.etQty.setError("Invalid Quantity");
holder.etQty.setText("");
} else {
productList.get(pos).setEnteredQty(holder.etQty.getText().toString());
}
} else {
productList.get(pos).setEnteredQty("");
}
}
});
return convertView;
}
static class ViewHolder {
TextView tvProductName, tvProdShortCode, tvLastOrderedQty;
EditText etQty;
LinearLayout parentRL;
}