EditText inside Listview and its reclycling issue in android - android

"Don't use edittext inside a listview" this is what most of the people say.. now I am thinking should have listened to them. I had a problem earlier when I added an EditText inside a ListView and encountered a problem related to click and I also posted a question regarding this(EditText and ListView are not working together) and also found a solution for that in(Focus on EditText in ListView when block descendants (Android)). After having so many obstacles I have been able to implement this,
But now I am having a recycle issue problem, I have an addTextChangedListener for the EditText in the ListView. Most of the people are suggesting to use setOnFocusChangeListener, but that is not an option for me as i have to change the EditText value of one row depending the value entered in the EditText of the other row.
The problem currently I am facing is when I enter the value in the last row of the EditText, the same thing is reflecting in the first row. Can anybody help me to solve this issue.
Here is the code snippet (Sorry for bad english)
public class MyBaseAdapter extends BaseAdapter {
ArrayList < ListData > myList = new ArrayList < > ();
LayoutInflater inflater;
Activity activity;
ListView lvDetail;
TextView total_amount;
TextView spendAmount;
Button proceed;
HashMap < Integer, ListData > selectedRow = new HashMap < > ();
public MyBaseAdapter(Activity activity, ArrayList < ListData > myList, ListView lvDetail) {
this.myList = myList;
this.activity = activity;
this.lvDetail = lvDetail;
inflater = LayoutInflater.from(this.activity);
total_amount = (TextView) activity.findViewById(R.id.total_amount);
spendAmount = (TextView) activity.findViewById(R.id.spendAmount);
proceed = (Button) activity.findViewById(R.id.proceed);
}
#Override
public int getCount() {
return myList.size();
}
#Override
public Object getItem(int position) {
return myList.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
public void setItem(int position, ListData data) {
myList.set(position, data);
}#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final MyViewHolder mViewHolder;
final ListData currentListData = (ListData) getItem(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_list_item, parent, false);
mViewHolder = new MyViewHolder(convertView);
convertView.setTag(mViewHolder);
} else {
mViewHolder = (MyViewHolder) convertView.getTag();
mViewHolder.enterAmount.setText("");
mViewHolder.enterAmount.setVisibility(View.INVISIBLE);
mViewHolder.tvDesc.setText("");
mViewHolder.tvTitle.setText("");
mViewHolder.ivIcon.setImageResource(R.drawable.ic_launcher_1);
}
if (selectedRow.containsKey(position)) {
mViewHolder.enterAmount.setVisibility(View.VISIBLE);
mViewHolder.enterAmount.setText(currentListData.getEditTextValue());
mViewHolder.ivIcon.setImageResource(R.drawable.ic_check_orange);
} else if (currentListData.getEditTextValue().toString().length() == 0) {
mViewHolder.enterAmount.setVisibility(View.INVISIBLE);
mViewHolder.enterAmount.setText(currentListData.getEditTextValue());
mViewHolder.ivIcon.setImageResource(currentListData.getImgResId());
}
mViewHolder.tvTitle.setText(currentListData.getTitle());
mViewHolder.tvDesc.setText(currentListData.getDescription());
mViewHolder.enterAmount.addTextChangedListener(new TextWatcher() {
String enterAmount, enterDescption;#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
enterAmount = s.toString();
enterDescption = mViewHolder.tvDesc.getText().toString().trim();
if ((count == 1 && start == 0) && (before == 1)) {
mViewHolder.enterAmount.setText("");
currentListData.setEditTextValue("");
setItem(position, currentListData);
}
}
#Override
public void afterTextChanged(Editable s) {
String[] separated;
int totalBal = 0;
if ((enterAmount.length() != 0 && enterDescption.length() != 0)) {
separated = enterDescption.split(":");
totalBal = Integer.parseInt(separated[1]);
if ((Integer.parseInt(enterAmount) > totalBal)) {
mViewHolder.enterAmount.setText("");
currentListData.setEditTextValue("");
setItem(position, currentListData);
new AlertDialog.Builder(activity)
.setTitle("Alert")
.setMessage("You do not have sufficient balance")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.setIcon(android.R.drawable.ic_dialog_alert)
.setCancelable(false)
.show();
} else if (Integer.parseInt(enterAmount) >= 0) {
System.out.println(position + "positioninside else if enterAmount:" + Integer.parseInt(enterAmount));
currentListData.setEditTextValue(enterAmount);
setItem(position, currentListData);
}
}
}
});
convertView.setOnClickListener(new View.OnClickListener() {#Override
public void onClick(View view) {
int i = selectedRow.size();
if (selectedRow.containsKey(position)) {
selectedRow.remove(position);
mViewHolder.enterAmount.setVisibility(View.INVISIBLE);
mViewHolder.enterAmount.setText("");
mViewHolder.ivIcon.setImageResource(R.drawable.ic_launcher1);
} else if (i < 2) {
ListData currentListData = (ListData) getItem(position);
selectedRow.put(position, currentListData);
mViewHolder.enterAmount.setVisibility(View.VISIBLE);
mViewHolder.ivIcon.setImageResource(R.drawable.ic_check_orange);
} else if (i >= 2) {
Toast.makeText(activity, "Select only two cards", Toast.LENGTH_SHORT).show();
}
}
}
);
return convertView;
}
private static class MyViewHolder {
TextView tvTitle, tvDesc;
ImageView ivIcon;
EditText enterAmount;
public MyViewHolder(View item) {
tvTitle = (TextView) item.findViewById(R.id.tvTitle);
tvDesc = (TextView) item.findViewById(R.id.tvDesc);
ivIcon = (ImageView) item.findViewById(R.id.ivIcon);
enterAmount = (EditText) item.findViewById(R.id.edittext);
}
}
}

Related

RecyclerView shows previous values entered in an EditText in new rows

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

How do I delete an item from my cart adapter?

I am using ArrayAdapter When I delete the first item from Listview.Its delete perfectly.But When I do delete the second item from the listview. Its not perfectly delete.
how can i do it?
Adapter coding
import android.widget.ArrayAdapter;
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// final CartBean beans = getItem(position);
View view = convertView;
final ViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_cart_row, parent, false);
viewHolder = new ViewHolder();
viewHolder.row_price = (TextView) view.findViewById(R.id.row_price);
viewHolder.et_quantity = (EditText) view.findViewById(R.id.cart_quantity);
viewHolder.row_item_name = (TextView) view.findViewById(R.id.row_item_name);
viewHolder.deleteButton = (ImageView) view.findViewById(R.id.iv_delete);
// viewHolder.rastaurantoffer = (ImageView) view.findViewById(R.id.rastaurantname2);
view.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
if (viewHolder.textWatcher != null)
viewHolder.et_quantity.removeTextChangedListener(viewHolder.textWatcher);
final CartBean bean = getItem(position);
viewHolder.textWatcher = 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) {
if (charSequence.length()>0) {
viewHolder.row_price.setText(String.valueOf(df.format(Double.parseDouble(bean.getTotal_price()) * Integer.parseInt(charSequence.toString()))));
AppConstants.cartBeanArrayList.get(position).setQuantity(Integer.parseInt(charSequence.toString()));
}
}
#Override
public void afterTextChanged(Editable editable) {
Double totalPrice=0.0;
for (int i=0;i<AppConstants.cartBeanArrayList.size();i++)
{
totalPrice=totalPrice+(Double.parseDouble(AppConstants.cartBeanArrayList.get(i).getTotal_price()) * AppConstants.cartBeanArrayList.get(i).getQuantity());
Log.i("total_price12356",""+total_price);
}
ActivityCart.tv_sub_total.setText("£. "+String.valueOf(df.format(totalPrice)));
}
};
viewHolder.row_price.setText("£."+String.valueOf(df.format(Double.parseDouble(cartBeans.get(position).getTotal_price()) * cartBeans.get(position).getQuantity())));
viewHolder.et_quantity.setText(String.valueOf(cartBeans.get(position).getQuantity()));
viewHolder.row_item_name.setText(cartBeans.get(position).getItem_name());
viewHolder.et_quantity.addTextChangedListener(viewHolder.textWatcher);
if(isDeleteRequired){
viewHolder.deleteButton.setVisibility(View.VISIBLE);
viewHolder.et_quantity.setInputType(InputType.TYPE_CLASS_NUMBER);
viewHolder.et_quantity.setFocusableInTouchMode(true);
viewHolder.et_quantity.setCursorVisible(true);
viewHolder.deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AppConstants.cartBeanArrayList.remove(position);
notifyDataSetChanged();
for (int i = 0; i < AppConstants.cartBeanArrayList.size(); i++) {
// String price = AppConstants.cartBeanArrayList.get(i).getTotal_price().substring(3, AppConstants.cartBeanArrayList.get(i).getTotal_price().length());
// Log.i("total_price123",""+price);
total_price = total_price + ActivityCart.getTotal(i);
Log.i("total_price123",""+total_price);
Log.i("total_price1237",""+AppConstants.cartBeanArrayList.size());
// AppConstants.cartBeanArrayList.clear();
}
Log.i("total_price1234",""+total_price);
ActivityCart.tv_sub_total.setText("£. "+String.valueOf(total_price));
if (AppConstants.cartBeanArrayList.size()==0)
{
ActivityCart.tv_sub_total.setText("£.0.00");
}
// AppConstants.addressBeanArrayList.setText(String.valueOf(total_price));
}
});
}else{
viewHolder.deleteButton.setVisibility(View.GONE);
}
return view;
}
class ViewHolder {
TextView row_item_name;
TextView row_price;
EditText et_quantity;
ImageView deleteButton;
public TextWatcher textWatcher;
}
public void setIsDeleteRequired(boolean isDeleteRequire){
isDeleteRequired = isDeleteRequire;
}
}
And getTotal() method coding is:
public static Double getTotal(int i) {
total =(Double.parseDouble(AppConstants.cartBeanArrayList.get(i).getTotal_price()) * AppConstants.cartBeanArrayList.get(i).getQuantity());
Log.i("totalsunder", "" +total);
return total;
}
Yes I got the answer myself.
Here my code
viewHolder.deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AppConstants.cartBeanArrayList.remove(position);
for (int i = 0; i < AppConstants.cartBeanArrayList.size(); i++) {
total_price = total_price + ActivityCart.getTotal(i);
}
ActivityCart.tv_sub_total.setText("£. "+String.valueOf(total_price));
total_price =0.0;
notifyDataSetChanged();
}
});
delete.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//removing from database
int i =impl_cart.deleteRow(data_cart.get(position).get_id());
//removing from adapter
data_cart.remove(position);
notifyDataSetChanged();
}
});

List view not getting refreshed

I have displayed all the contacts within the phone along with a check box in a list view. Now when the user checks say A and B and clicks on "ok" button, then what I want is to display the list again when making all the check box checked value to false. For that, I have created a method but when I call this method the value of the selected contacts is set to unchecked only when the list is scrolled, else it remains unchecked.
Whats the problem with my code???
Code
public void getContactSync(Context context, ArrayList<ContactModel> data) {
setListAdapter(null);
contactListAdapter = new ContactListAdapter(context, data);
setListAdapter(contactListAdapter);
// contactListAdapter.notifyDataSetChanged();
}
On OK button click
Arrays.fill(ContactListAdapter.contacts, 0);
contactListFragment.getContactSync(getActivity(), dbHandler.getAlGetContacts());
Custom Adapter
public class ContactListAdapter extends BaseAdapter {
private Context context;
private ArrayList<ContactModel> data;
DbHandler dbHandler;
public static int[] contacts;
static ArrayList<String> contactsSepetrated;
public static ArrayList<String> contactsId;
public ContactListAdapter(Context context, ArrayList<ContactModel> data) {
this.context = context;
this.data = data;
contacts = new int[data.size()];
contactsSepetrated = new ArrayList<String>();
contactsId = new ArrayList<String>();
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(final int i, View view, ViewGroup viewGroup) {
final ViewHolder holder;
dbHandler = new DbHandler(context);
if (view == null) {
holder = new ViewHolder();
view = LayoutInflater.from(context).inflate(R.layout.contact_custom_list, viewGroup, false);
holder.tvContact = (TextView) view.findViewById(R.id.tv_contact_name);
holder.checkBox = (CheckBox) view.findViewById(R.id.cb_contact_checkbox);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (compoundButton == holder.checkBox) {
if (b) {
contacts[i] = 1;
//dbHandler.updateContactList(data.get(i).getUserID(), 1);
//
} else {
contacts[i] = 0;
}
}
}
}
);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (contacts[i] == 1) {
contactsSepetrated.add(data.get(i).getContactName());
Log.e("Contact values", contactsSepetrated.toString());
contactsId.add(data.get(i).getUserID());
Log.e("Position", "" + i);
} else if (contacts[i] == 0) {
contactsSepetrated.remove(data.get(i).getContactName());
contactsId.remove(data.get(i).getUserID());
Log.e("Contact values", contactsSepetrated.toString());
Log.e("Position", "" + i);
}
ShareWithinpocketDocs.etContactsList.setText(contactsSepetrated.toString().subSequence(1, contactsSepetrated.toString().length() - 1));
}
});
if (contacts[i] == 0) {
holder.checkBox.setChecked(false);
// emailSeperated.remove(data.get(i).getEmail());
// Log.e("Email values", emailSeperated.toString());
// ShareWithinpocketDocs.etEmailLists.setText(emailSeperated.toString());
} else {
holder.checkBox.setChecked(true);
// emailSeperated.add(data.get(i).getEmail());
// Log.e("Email values", emailSeperated.toString());
}
holder.tvContact.setText(data.get(i).getContactName());
return view;
}
private class ViewHolder {
TextView tvContact;
CheckBox checkBox;
}
}
on click of checkbox inside adapter just call notifydatasetchanged() it will solve your problem
holder.checkBox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton,
boolean b) {
if (compoundButton == holder.checkBox) {
if (b) {
contacts[i] = 1;
// dbHandler.updateContactList(data.get(i).getUserID(),
// 1);
//
notifyDataSetChanged();
} else {
contacts[i] = 0;
notifyDataSetChanged();
}
}
}
}
);
if you want to refresh adapter on ok button click add this to ok button click
adapter.notifydatasetchagned()
Try to call setListAdapter(contactListAdapter); again inside your onClick()

ListView Why edittext data lost when scroll listView

I follow some code in few page, but it not working. Here is my code of pageAdapter:
public class ViewHolder {
int ref;
TextView txtTimeToEat;
LinearLayout lnlDishListView, lnlDishToGetpos;
ImageView imgDish;
TextView txtDishName;
TextView txtDishWhen;
TextView txtActiGoal;
TextView txtActiActual;
EditText edtDishAtual;
}
public SelectDishActualAdapter(Context context, List<DishEntity> listDishInTime) {
mContext = context;
Current = new String[listDishInTime.size()];
this.listDishInTime = listDishInTime;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listDishInTime.size();
}
#Override
public Object getItem(int position) {
return listDishInTime.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView( int position, View convertView, ViewGroup parent) {
View vi = convertView;
final int pos = position;
if (vi == null) {
vi = inflater.inflate(R.layout.update_actual_dish_custom, null);
holder = new ViewHolder();
holder.lnlDishListView = (LinearLayout) vi.findViewById(R.id.lnlDishListView);
holder.lnlDishToGetpos = (LinearLayout) vi.findViewById(R.id.lnlDishToGetPos);
holder.txtTimeToEat = (TextView) vi.findViewById(R.id.txtEatTime);
holder.imgDish = (ImageView) vi.findViewById(R.id.imgDishActual);
holder.txtDishName = (TextView) vi.findViewById(R.id.txtDishActualName);
holder.txtActiGoal = (TextView) vi.findViewById(R.id.txtManualGram);
holder.txtActiActual = (TextView) vi.findViewById(R.id.txtActualGram);
holder.edtDishAtual = (EditText) vi.findViewById(R.id.edtActualGram);
holder.edtDishAtual.setId(pos);
vi.setTag(holder);
} else {
holder = (ViewHolder) vi.getTag();
}
///// id = 989898,989897,989896 is to decrale footer,It is mean Breakfast,Lunch and Dinner
if (listDishInTime.get(position).getDishId() == 989898) {
holder.txtTimeToEat.setText(mContext.getResources().getString(R.string.sang));
holder.txtTimeToEat.requestLayout();
holder.txtTimeToEat.getLayoutParams().height = 40;
holder.lnlDishListView.requestLayout();
holder.lnlDishListView.getLayoutParams().height = 0;
} else if (listDishInTime.get(position).getDishId() == 989897) {
holder.txtTimeToEat.setText(mContext.getResources().getString(R.string.trua));
holder.txtTimeToEat.requestLayout();
holder.txtTimeToEat.getLayoutParams().height = 40;
holder.lnlDishListView.requestLayout();
holder.lnlDishListView.getLayoutParams().height = 0;
} else if (listDishInTime.get(position).getDishId() == 989896) {
holder.txtTimeToEat.setText(mContext.getResources().getString(R.string.chieu));
holder.txtTimeToEat.requestLayout();
holder.txtTimeToEat.getLayoutParams().height = 40;
holder.lnlDishListView.requestLayout();
holder.lnlDishListView.getLayoutParams().height = 0;
} else {
// Otherwise fill to listview with custom data
String temp = listDishInTime.get(position).getImageUrl();
final int imgID = mContext.getResources().getIdentifier(temp, "drawable", mContext.getPackageName());
holder.txtDishName.setText(listDishInTime.get(position).getName());
holder.imgDish.setImageResource(imgID);
int size = holder.imgDish.getLayoutParams().width;
holder.txtTimeToEat.requestLayout();
holder.txtTimeToEat.getLayoutParams().height = 0;
holder.lnlDishListView.requestLayout();
holder.lnlDishListView.getLayoutParams().height = size;
holder.edtDishAtual.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) {
holder.ref = pos;
Current[holder.ref] = s.toString(); // String[] Current with size = new size
myList.put(pos, s.toString().trim()); //mylist is hashmap
}
});
holder.edtDishAtual.setText(myList.get(pos));
}
return vi;
}
But when I scroll, editext still lose content data :(. please help me
ListView recycle it's children to optimise use of the memory. When your EditText item is moved out of the screen it gets used by another item from your list.
This short video from Udacity Android course explains nicely how it works. It takes just 1:40min.
If you want your EditText to remain the text you have to store it yourself within item data and then restore it when your item is shown again.

Get the EditText values from ListView

I'm trying to get the values from the EditTexts in a ListView, but its not working. The values set to my array of 'lista' in the afterTextChanged method are apparently lost. I'm new in android programming, someone can help me? (sorry for bad English)
Heres the code for the getView in my adapter:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
final int posicao = position;
if (convertView == null) {
LayoutInflater inflater = contexto.getLayoutInflater();
convertView = inflater.inflate(R.layout.produtos, null);
holder = new ViewHolder();
holder.texto = (TextView) convertView.findViewById(R.id.txtDescricao);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.chkProduto);
holder.edit = (EditText) convertView.findViewById(R.id.txtValor);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.texto.setText(getItem(position).getTexto());
holder.edit.setText("0");
holder.edit.setTag(new LinhaItemTag(getItem(position), position));
//here a get an exception just setting the focus on edit
holder.edit.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
int posicao = v.getId();
EditText e = ((EditText) v);
if (!e.getText().toString().equals("")) {
if (hasFocus) {
if(e.getText().toString().length() != 0)
lista.get(posicao).setValor(Double.parseDouble(e.getText().toString()));
}
}
}
});
holder.edit.addTextChangedListener( new TextWatcher() {
public void afterTextChanged(Editable s)
{
if(s.length() != 0)
{
lista.get(posicao).setValor(Double.parseDouble(s.toString()));
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
});
holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(getItem(position).Selecionado());
holder.checkbox.setTag(new LinhaItemTag(getItem(position), position));
holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
LinhaItemTag elemento = (LinhaItemTag) buttonView.getTag();
elemento.item.setSelecionado(isChecked);
if (isChecked) {
pegos[elemento.position] = true;
} else {
pegos[elemento.position] = false;
}
boolean checados = true;
for (int i = 0; i < lista.size(); i++) {
if (!pegos[i]) {
checados = false;
break;
}
}
if (checados) {
for(int i = 0; i < lista.size(); i++)
{
total += lista.get(i).getValor();
}
Toast.makeText(contexto, "Compra finalizada - Valor Total: " + total, Toast.LENGTH_LONG).show();
}
}
});
return convertView;
}
}
I managed to get values from the EditTexts looking at this post: how to retrieve value from all EditText in ListView
Bu now, i faced with other problem: when i roll my list down, the values from the EditTexts are lost.
This is like my code looks now:
public class MeuAdapter extends ArrayAdapter<LinhaItem> {
private final List<LinhaItem> lista;
private final Activity contexto;
private final boolean[] pegos;
private final double[] valores;
double total;
public MeuAdapter(Activity contexto, List<LinhaItem> lista) {
super(contexto, 0, lista);
this.contexto = contexto;
this.lista = lista;
pegos = new boolean[lista.size()];
valores = new double[lista.size()];
for (int i = 0; i < lista.size(); i++) {
pegos[i] = false;
valores[i] = 0;
}
total = 0;
}
public class ViewHolder
{
protected TextView texto;
protected CheckBox checkbox;
protected EditText edit;
}
public class LinhaItemTag {
LinhaItem item;
int position;
LinhaItemTag(LinhaItem item, int position) {
this.item = item;
this.position = position;
}
}
private class MeuTextWatcher implements TextWatcher {
private View v;
public MeuTextWatcher(View v)
{
this.v = v;
}
#Override
public void afterTextChanged(Editable e) {
String s = e.toString();
LinhaItemTag lTag = (LinhaItemTag) v.getTag();
if(s.length() != 0)
{
valores[lTag.position] = Double.parseDouble(s);
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
}
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater inflater = contexto.getLayoutInflater();
convertView = inflater.inflate(R.layout.produtos, null);
holder = new ViewHolder();
holder.texto = (TextView) convertView.findViewById(R.id.txtDescricao);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.chkProduto);
holder.edit = (EditText) convertView.findViewById(R.id.txtValor);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.texto.setText(getItem(position).getTexto());
holder.edit.setText("");
holder.edit.setTag(new LinhaItemTag(getItem(position), position));
holder.edit.addTextChangedListener(new MeuTextWatcher(holder.edit));
holder.checkbox.setOnCheckedChangeListener(null);
holder.checkbox.setChecked(getItem(position).Selecionado());
holder.checkbox.setTag(new LinhaItemTag(getItem(position), position));
holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
LinhaItemTag elemento = (LinhaItemTag) buttonView.getTag();
elemento.item.setSelecionado(isChecked);
if (isChecked) {
pegos[elemento.position] = true;
} else {
pegos[elemento.position] = false;
}
boolean checados = true;
for (int i = 0; i < lista.size(); i++) {
if (!pegos[i]) {
checados = false;
break;
}
}
String vlrs = "";
if (checados) {
for(int i = 0; i < lista.size(); i++)
{
total += valores[i];
}
Toast.makeText(contexto, "Total da compra: " + total, Toast.LENGTH_LONG).show();
}
}
});
return convertView;
}
}
I change the line:
holder.edit.setText("");
to:
//the valores array is where i store the values in the afterTextChanged method in the TextWatcher class implementation.
holder.edit.setText(**Double.toString(valores[position])**);
But this not working as i expect, for example, if i set a value to the EditText of the first row of the ListView, this value, after i roll down the list, is setted to EditText in the third row of the list...
To get the values from the EditText in your ListView, you could do that in your activity. You must need the values on some view click or something. So whenever that happens, just write the following code
View view=listView.getChildAt(position);
EditText editText=view.findViewById(R.id.editText);
String string=editText.getText().toString();
Here, the above code will give you the text of the EditText that is present in the position position of your ListView. It seems that you need the sum of the of the values of the EditTexts when all are checked right? You can use something like this then
for(int i=0;i<items.size();i++){
View view=listView.getChildAt(i);
EditText editText=view.findViewById(R.id.editText);
String string=editText.getText().toString();
if(!string.equals(""))
total+=Double.parseDouble(string);
}
change in adapter class getView() methods look like.
#Override
public View getView(final int position, View view, ViewGroup parent) {
TextView txt_id, txt_courny_symbol, txt_member_view;
EditText edit_member_amount;
final int posicao = position;
Log.v("ConvertView", String.valueOf(posicao));
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_member_layout, null);
txt_id = (TextView) view.findViewById(R.id.txt_id);
txt_courny_symbol = (TextView) view.findViewById(R.id.txt_courny_symbol);
edit_member_amount = (EditText) view.findViewById(R.id.edit_member_amount);
edit_member_amount.setTag(new LinhaItemTag(getItem(posicao), posicao));
edit_member_amount.addTextChangedListener(new MeuTextWatcher(edit_member_amount));
if (al_contact.size() != 0) {
MemberClass memberClass = al_contact.get(position);
txt_id.setText(memberClass.getName());
txt_courny_symbol.setText(sym);
}
return view;
}
erase the our ViewHolder class
hi you can use the code below to do this, listview cannot save the controllers state on the row, so you need to use settag and gettag of controls.
for source: https://dl.dropbox.com/u/68130108/ListViewEditItem.rar
Losing the values from EditTexts can be annoying as far. I have found this solution while working.
In your android manifest, pick the activity which your list view is in. Then put this code-block there.
android:windowSoftInputMode="adjustPan"
Then go to your ListView, and navigate to the xml layout and put this block there.
android:descendantFocusability="beforeDescendants"

Categories

Resources