I have the following custom base adapter. I have a listview with a edittext on each item. I want to save that data as soon as the user leaves the edittext, but what happens now is that each time the user types in 1 char, the setOnFocusChangeListener triggers. I really don't know why this is happening.
My custom base adapter class
public class ChecklistBaseAdapter extends BaseAdapter {
private static ArrayList<Checklist> searchArrayList;
Context currentcontext;
DatabaseHandler db;
private LayoutInflater mInflater;
public ChecklistBaseAdapter(Context context, ArrayList<Checklist> results) {
searchArrayList = results;
mInflater = LayoutInflater.from(context);
currentcontext = context;
db = new DatabaseHandler(currentcontext);
}
public int getCount() {
return searchArrayList.size();
}
public void remove(int position) {
searchArrayList.remove(position);
notifyDataSetChanged();
}
public void removeAll() {
searchArrayList.clear();
notifyDataSetChanged();
}
public void add(Checklist checklist) {
searchArrayList.add(checklist);
notifyDataSetChanged();
}
public void notifyChange() {
notifyDataSetChanged();
}
public Object getItem(int position) {
return searchArrayList.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.checklistitem, null);
holder = new ViewHolder();
holder.cbStatus = (CheckBox) convertView
.findViewById(R.id.checkbox);
holder.etName = (EditText) convertView.findViewById(R.id.editname);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Checklist checklist = (Checklist) getItem(position);
holder.etName.setText(checklist.getName());
holder.etName.setId(position);
if (searchArrayList.get(position).getStatus().equals("F")) {
holder.cbStatus.setChecked(false);
} else {
holder.cbStatus.setChecked(true);
}
holder.etName.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
int myint = v.getId();
searchArrayList.get(myint)._name = v.getText().toString();
return true;
}
return false;
}
});
holder.etName
.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
String input;
EditText editText;
if (!hasFocus) {
Log.e("test", "test123");
int myint = v.getId();
editText = (EditText) v;
input = editText.getText().toString();
searchArrayList.get(myint)._name = input;
}
}
});
holder.cbStatus
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
String name = holder.etName.getText().toString().trim();
if (isChecked) {
for (int x = 0; x < searchArrayList.size(); x++) {
Checklist checklist = new Checklist();
checklist = searchArrayList.get(x);
if (name.equals(checklist.getName())) {
checklist.setStatus("T");
db.updateCheckList(checklist);
searchArrayList.set(x, checklist);
}
}
} else {
for (int x = 0; x < searchArrayList.size(); x++) {
Checklist checklist = new Checklist();
checklist = searchArrayList.get(x);
if (name.equals(checklist.getName())) {
checklist.setStatus("F");
searchArrayList.set(x, checklist);
db.updateCheckList(checklist);
}
}
}
}
});
return convertView;
}
static class ViewHolder {
CheckBox cbStatus;
EditText etName;
}
}
Try using the addTextChangedListener() method
holder.etName.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) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
String input;
EditText editText;
Log.e("test", "test123");
int myint = v.getId();
editText = (EditText)v;
input = editText.getText().toString();
searchArrayList.get(myint)._name = input;
});
Hope It will Help you.
Related
Background:
I have created a ListView with three columns sNo, product and price. First column is defined as TextView (whose value is auto generated) and the next two columns are EditText (whose value is filled up by the user).
What I want:
I want to add a new row to the ListView whenever:
User hit enter key on any EditText
There is no empty EditText (meaning all the EditText defined so far have some value in them).
Basically I want display a new orders list where users can add orders.
My code so far:
ListView Model:
public class NewTableModel {
private String sNo, product, price;
public NewTableModel(String sNo, String product, String price){
this.sNo = sNo;
this.product = product;
this.price = price;
}
public String getProduct(){ return product; }
public String getPrice(){ return price; }
public String getsNo() { return sNo; }
}
ListView adapter:
public class NewTableAdapter extends BaseAdapter {
private ArrayList<NewTableModel> productList;
private Activity activity;
public NewTableAdapter(Activity activity, ArrayList<NewTableModel> productList) {
super();
this.activity = activity;
this.productList = productList;
}
#Override
public int getCount() { return productList.size(); }
#Override
public Object getItem(int position) { return productList.get(position); }
#Override
public long getItemId(int position) { return position; }
public class ViewHolder {
TextView mSno;
EditText mProduct;
EditText mPrice;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
LayoutInflater inflater = activity.getLayoutInflater();
if (convertView == null) {
convertView = inflater.inflate(R.layout.new_table_row, null);
holder = new ViewHolder();
holder.mSno = (TextView) convertView.findViewById(R.id.sno);
holder.mProduct = (EditText) convertView.findViewById(R.id.product);
holder.mPrice = (EditText) convertView.findViewById(R.id.price);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
NewTableModel item = productList.get(position);
holder.mSno.setText(item.getsNo());
holder.mProduct.setText(item.getProduct());
holder.mPrice.setText(String.valueOf(item.getPrice()));
return convertView;
}
}
MainActivity:
public class MainActivity extends AppCompatActivity {
private ArrayList<NewTableModel> productList;
private ListView orderView;
private NewTableAdapter orderAdapter;
private void insertNewRow(){ insertNewRow("",""); }
private void insertNewRow(String productVal, String priceVal){
String serialNoVal = String.valueOf(orderView.getCount() + 1);
NewTableModel item = new NewTableModel(serialNoVal, productVal, priceVal);
productList.add(item);
}
private void setupAdapter(){
productList = new ArrayList<NewTableModel>();
orderView = (ListView) findViewById(R.id.newTableContent);
orderAdapter = new NewTableAdapter(this, productList);
orderView.setAdapter(orderAdapter);
orderAdapter.notifyDataSetChanged();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
setupAdapter();
insertNewRow();
}
}
My Listener:
setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER
&& noEmptyColumn())
insertNewRow();
return false;
}
});
Where should I place that listener ? and how would I check if any column is empty or not (define noEmptyColumn()) ?
You should place the listener where any of EditText values are changed. I would add a Button to any row, and set the listener at there. So in your ViewHolder:
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
boolean hasEmpty = false;
for (NewTableModel item: productList) {
if (item.getDesiredField().isEmpty()) {
hasEmpty = true;
break;
}
}
if (!hasEmpty) {
insertNewRow();
notifyDataSetChanged();
}
}
});
Another option could be setting a TextWatcher on EditText :
ed.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) {
boolean hasEmpty = false;
for (NewTableModel item: productList) {
if (item.getDesiredField().isEmpty()) {
hasEmpty = true;
break;
}
}
if (!hasEmpty) {
insertNewRow();
notifyDataSetChanged();
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
Just move both methods to your Adapter class. And note that the second solution is not efficient when there are too many rows.
I'm not expert in android listview and Edittext. However, I am stuck with some annoying problem regarding this issue. I am fetching values in listview without any problem but when I input something in Edittext and scroll down the value of EditText changes it's position. Here is my code.
//product class
public class products {
public String prod_sl;
public String prod_code;
public String product_name;
public String product_desc;
public String prod_qnty;
public String prod_uom;
public String prod_price;
boolean ShowName;
public products(String psl, String pcode,String Name, String Desc, String UOM) {
this.prod_sl = psl;
prod_code = pcode;
prod_qnty="";
prod_price ="";
product_name=Name;
product_desc=Desc;
prod_uom =UOM;
}
/* public boolean isShowName() {
return ShowName;
}
public void setShowName(boolean showName) {
ShowName = showName;
}*/
//sl
public String getSl() { return prod_sl; }
public void setSl(String psl) { this.prod_sl = psl; }
//product code
public String getCode() { return prod_code; }
public void setCode(String pcode) { this.prod_code = pcode; }
//product Name
public String getName() { return product_name; }
public void setName(String product_name) { this.product_name = product_name; }
//product desc
public String getDesc() { return product_desc; }
public void setDesc(String product_desc) { this.product_desc = product_desc; }
//product UOM
public String getUom() { return prod_uom; }
public void setUom(String prod_uom) { this.prod_uom = prod_uom; }
// product quantity
public String getQnty() {
return prod_qnty; }
public void setQnty(String prod_qnty) {
this.prod_qnty = prod_qnty; }
//product price
public String getPrice() {
return prod_price; }
public void setPrice(String prod_price) {
this.prod_price = prod_price; }
}
And here is the adapter class
public class ListViewAdapter extends ArrayAdapter<products> {
Context mContext;
View v;
private String[] arrTemp;
LayoutInflater inflater;
ArrayList<products> arrayproducts;
public String[] scoresToUpdate=new String[1000];
//public String Array scoresToUpdate =scoresToUpdate[];
public static EditText edit_qnty,prod_price;
public static HashMap<Integer,String> myList=new HashMap<Integer,String>();
public ListViewAdapter(Context context, int resource, ArrayList<products> arrayproducts) {
super(context, resource);
this.mContext = context;
this.arrayproducts = arrayproducts;
this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
try {
final int pos=position;
final ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_adapter_view, null);
holder = new ViewHolder();
holder.prod_sl = (TextView) convertView.findViewById(R.id.prod_sl);
holder.prod_code = (TextView) convertView.findViewById(R.id.prod_code);
holder.txtTitle = (TextView) convertView.findViewById(R.id.adapter_text_title);
holder.txtDescription = (TextView) convertView.findViewById(R.id.adapter_text_description);
holder.prod_uom = (TextView) convertView.findViewById(R.id.prod_uom);
holder.prod_qnty = (EditText) convertView.findViewById(R.id.prod_qnty);
holder.prod_price = (EditText) convertView.findViewById(R.id.prod_price);
// edit_qnty = (EditText) convertView.findViewById(R.id.prod_qnty);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
// holder.prod_qnty.setText(scoresToUpdate[pos]);
}
holder.ref = position;
products prod = arrayproducts.get(position);
holder.prod_sl.setText("" + position);
holder.prod_code.setText(prod.getCode());
holder.txtTitle.setText(prod.getName());
holder.txtDescription.setText(prod.getDesc());
holder.prod_uom.setText(prod.getUom());
Log.e("row values",""+position+"\t-"+prod.getCode()+""+prod.getName()+""+prod.getDesc()+""+prod.getUom());
// holder.prod_qnty.setText(arrTemp[position]);
holder.prod_qnty.setText(scoresToUpdate[position]);
holder.prod_qnty.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
arrayproducts.get(pos).setQnty(holder.prod_qnty.getText().toString().trim());
myList.put(pos,arg0.toString().trim());
if (!arg0.equals("0")){
scoresToUpdate[pos] = arg0.toString();
Log.e("On text Change","Pos"+pos+"\tqnty:"+holder.prod_qnty.getText().toString().trim()+"\t Args: "+arg0.toString());
}
}
#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
Log.e("After Text change","Pos"+holder.ref+"\tqnty:"+holder.prod_qnty.getText().toString().trim());
// arrTemp[holder.ref] = arg0.toString();
}
});
//holder.prod_qnty.setText(myList.get(position));
holder.prod_qnty.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
Log.e("Current Qnty",edit_qnty.getText().toString().trim());
if(holder.prod_qnty.getText().toString().trim().equals("0")){
holder.prod_qnty.setText("");
}
String inttext = (""+holder.prod_qnty.getText().toString().trim());
if (!inttext.equals("0")){
holder.prod_price.setText("");
}
return false;
//return true;
}
});
//Using setOnclickListener not setOnCheckedChangeListener
//we need to update adapter once we finish with editing
/* holder.prod_qnty.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
final int pos = v.getId();
final EditText Qnty = (EditText) v;
Log.e("Qnty For the positon","POS: "+pos+"\tQnty: "+Qnty.getText().toString().trim());
arrayproducts.get(pos).setQnty(Qnty.getText().toString().trim());
//holder.prod_qnty.setText(Caption.getText().toString().trim());
}
}
});*/
/* holder.prod_price.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
final int position = v.getId();
final EditText Caption = (EditText) v;
arrayproducts.get(position).setPrice(Caption.getText().toString().trim());
}
}
});
*/
return convertView;
}
catch(Exception e){
Toast.makeText(mContext, "!!!", Toast.LENGTH_SHORT).show();
e.printStackTrace();
Log.e("Exception:",""+e.toString());
}
return convertView;
}
/* #Override
public int getCount() {
return arrayproducts.size();
}*/
#Override
public int getCount() {
// TODO Auto-generated method stub
if(arrayproducts != null && arrayproducts.size() != 0){
return arrayproducts.size();
}
return 0;
}
/*#Override
public Objects getItem(int position) {
// TODO Auto-generated method stub
return arrayproducts[position];
}*/
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public void getQnty(){
if(edit_qnty.getText().toString().trim().equals("0"))
edit_qnty.setText("");
}
static class ViewHolder {
TextView prod_sl;
TextView prod_code;
TextView txtTitle;
TextView txtDescription;
TextView prod_uom;
EditText prod_qnty,prod_price;
TextWatcher qtyWatcher;
TextWatcher priceWatcher;
int ref;
}
}
Please help me, With regards
This works for me !
if (holder.qtyWatcher != null) {
holder.txtFourth.removeTextChangedListener(holder.qtyWatcher);
}
// Create the TextWatcher corresponding to this row
holder.qtyWatcher = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
if(s.toString().equals("")||s.toString().equals("0")){
arrayproducts.get(position).setQnty("0");
}
else{
arrayproducts.get(position).setQnty(s.toString());
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
};
not sure that listview and recycleview can be used like this as they involve a recycling mechanism to reuse created views and rebind data from arrays or cursors as users scroll down/up to see more data. in other words, the row views created are with limited number to only fill the screen (with few extra from both sides) and they are recycled and reused to show data, if you insert a price or quantity for one product line, how the recycling process will rebind to show same data you inserted or show it on same position, I doubt this is possible.
I suggest that you restructure your application on parent/child base. show on list parent data, for example fixed product data, when users click one product line another screen opens so users insert new data, for example the price for that particular product line, the layout of your child screen will contains the edittext and any other data input views, in such case you need to integrate SQLite database so that you persist the new data provided by users.
hope this may provide you with some useful ideas to help you achieve your target.
hello to every one i have a custom list view with a search and animation all works cool but in search i have a little problem . I would like to, for example, I search for a word in a sentence.
But the way I used to enter the letters i have to put them in sequence.
here is my code:
public class MainActivity extends Activity {
ListView list;
ListViewAdapter adapter;
EditText editsearch;
String[] country;
Typeface tf;
ArrayList<WorldPopulation> arraylist = new ArrayList<WorldPopulation>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_main);
editsearch = (EditText) findViewById(R.id.search);
list = (ListView) findViewById(R.id.listview);
tf = Typeface.createFromAsset(getAssets(), "fonts/BKOODB.TTF");
country = new String[54];
for (int x = 1; x < 54 + 1; x = x + 1) {
String this_subject = "mo_" + String.valueOf(x);
int resID = getResources().getIdentifier(this_subject, "string", getPackageName());
country[x - 1] = getResources().getString(resID);
}
for (int i = 0; i < 54; i++) {
WorldPopulation wp = new WorldPopulation(country[i]);
// Binds all strings into an array
arraylist.add(wp);
}
adapter = new ListViewAdapter(this, arraylist);
list.setAdapter(adapter);
editsearch.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = editsearch.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
#Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
});
list.setOnScrollListener(new OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
hideKeyboard();
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
new CountDownTimer(500, 500) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
hideKeyboard();
}
}.start();
}
public class WorldPopulation {
private String country;
public WorldPopulation(String country) {
this.country = country;
}
public String getCountry() {
return this.country;
}
}
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context mContext;
LayoutInflater inflater;
private List<WorldPopulation> worldpopulationlist = null;
private ArrayList<WorldPopulation> arraylist;
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_in_right);
public ListViewAdapter(Context context, List<WorldPopulation> worldpopulationlist) {
mContext = context;
this.worldpopulationlist = worldpopulationlist;
inflater = LayoutInflater.from(mContext);
this.arraylist = new ArrayList<WorldPopulation>();
this.arraylist.addAll(worldpopulationlist);
}
public class ViewHolder {
TextView country;
}
#Override
public int getCount() {
return worldpopulationlist.size();
}
#Override
public WorldPopulation getItem(int position) {
return worldpopulationlist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
LayoutInflater inflater = getLayoutInflater();
View row;
row = inflater.inflate(R.layout.listview_item, parent, false);
TextView textview = (TextView) row.findViewById(R.id.country);
ImageView im = (ImageView) row.findViewById(R.id.imageitem);
im.setImageResource(R.drawable.hair);
textview.setText(worldpopulationlist.get(position).getCountry());
textview.setTypeface(tf);
Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_in_right);
row.startAnimation(animation);
row.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// *********************************************************
// in here it does not send right number to secend activity*
// *********************************************************
int orgPos = 0;
if (country.length != worldpopulationlist.size()) {
notifyDataSetChanged();
// The list on which we clicked is sorted!
String clickedText = worldpopulationlist.get(position).toString();
int i1 = 0;
boolean found = false;
while (i1 < country.length && found == false) {
if (clickedText == country[i1]) {
orgPos = i1;
found = true;
} else {
i1++;
}
}
Intent i2 = new Intent(mContext, SingleItemView.class);
String Subject_number = String.valueOf(orgPos + 1);
i2.putExtra("subject_number", Subject_number);
startActivity(i2);
} else {
Intent i = new Intent(mContext, SingleItemView.class);
String Subject_number = String.valueOf(position + 1);
i.putExtra("subject_number", Subject_number);
startActivity(i);
}
}
});
return row;
}
// Filter Class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
worldpopulationlist.clear();
if (charText.length() == 0) {
worldpopulationlist.addAll(arraylist);
} else {
for (final WorldPopulation wp : arraylist) {
if (wp.getCountry().toLowerCase(Locale.getDefault()).contains(charText)) {
worldpopulationlist.add(wp);
}
}
}
notifyDataSetChanged();
}
}
private void hideKeyboard() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
try doing it in afterTextChanged Method because this allows you to enter all the text. and follow this link
public void afterTextChanged(Editable s) {
}
Try with custom adapter.
this will help you.Link
How to store and retrieve editText from a listview that have 2 editText on each row?
With this code, when I write something to one editText, it copy the value to all others.
public class CheckoutAdapter extends BaseAdapter{
private Context mContext;
private List<JsonObject> mObjs;
private ViewHolder holder;
private SessionManager session;
private float Value = 0;
private int tax = 0;
private float Total = 0;
private int viewID = 0;
private EnhancedListView listview;
private ImageLoader imageLoader = ImageLoader.getInstance();
static DisplayImageOptions options;
private ArrayList<String> arrayFirstName = new ArrayList<String>();
private ArrayList<String> arrayLastName = new ArrayList<String>();
public CheckoutAdapter(Context context, List<JsonObject> objs, EnhancedListView mListView) {
// TODO Auto-generated constructor stub
this.mContext = context;
this.mObjs = objs;
this.listview = mListView;
for (int i = 0; i < mObjs.size(); i++) {
arrayFirstName.add("");
arrayLastName.add("");
}
}
//Classe ViewHolder
public final class ViewHolder {
public TextView ticketValue;
public TextView ticketItem;
public TextView ticketOpcao;
public TextView ticketTax;
public TextView ticketTitle;
public TextView ticketDate;
public TextView ticketFullName;
public EditText ticketFirstName;
public EditText ticketLastName;
public ImageView ticketImageThumb;
int position;
}
public void remove(int position) {
mObjs.remove(position);
}
public void insert(int position, JsonObject item) {
mObjs.add(position, item);
}
#Override
//Contar a quntidade de linhas.
public int getCount() {
// TODO Auto-generated method stub
return mObjs.size();
}
#Override
//Pegar o item conforme a posição.
public Object getItem(int position) {
// TODO Auto-generated method stub
return mObjs.get(position);
}
#Override
//ID do item (refere-se a posição em que ele se encontra).
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View vi=convertView;
//Se não houver nenhuma View, uma nova view é criada.
if(convertView==null)
{
vi = LayoutInflater.from(mContext).inflate(R.layout.row_checkout, null);
Typeface font = Typeface.createFromAsset(mContext.getAssets(), "fonts/Oswald-Bold.otf");
final View origView = vi;
vi.findViewById(R.id.action_delete).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listview.delete(((ViewHolder)origView.getTag()).position);
}
});
holder = new ViewHolder();
holder.ticketItem = (TextView)vi.findViewById(R.id.tvItem);
holder.ticketOpcao = (TextView)vi.findViewById(R.id.tvOpcao);
holder.ticketTax = (TextView)vi.findViewById(R.id.tvTaxa);
holder.ticketValue = (TextView)vi.findViewById(R.id.tvValue);
holder.ticketValue.setTypeface(font);
holder.ticketTitle = (TextView)vi.findViewById(R.id.tvTitle);
holder.ticketTitle.setTypeface(font);
holder.ticketDate = (TextView)vi.findViewById(R.id.tvDate);
holder.ticketDate.setTypeface(font);
holder.ticketFullName = (TextView)vi.findViewById(R.id.tvFullName);
holder.ticketFullName.setTypeface(font);
holder.ticketFirstName = (EditText)vi.findViewById(R.id.etFirstName);
holder.ticketLastName = (EditText)vi.findViewById(R.id.etLastName);
holder.ticketImageThumb = (ImageView)vi.findViewById(R.id.imgFlyerSub);
holder.position = position;
holder.ticketFirstName.addTextChangedListener(FirstNameChangedListener(position));
holder.ticketLastName.addTextChangedListener(LastNameChangedListener(position));
holder.ticketFirstName.setOnFocusChangeListener(FirstNameFocusChangeListener(position));
holder.ticketLastName.setOnFocusChangeListener(LastNameFocusChangeListener(position));
vi.setTag(holder);
//Caso já exista uma view o objeto holder recebe o getTag da View vi.
} else {
holder = (ViewHolder)vi.getTag();
}
holder.ticketItem.setText(mObjs.get(position).getAsJsonObject().get(Constants.JSON.JSON_ITEM).getAsString());
holder.ticketOpcao.setText(mObjs.get(position).getAsJsonObject().get(Constants.JSON.JSON_OPCAO).getAsString());
holder.ticketTax.setText("Taxa de serviço:" + mObjs.get(position).getAsJsonObject().get(Constants.JSON.JSON_TAX).getAsString() + "%");
holder.ticketValue.setText("R$" + String.valueOf(mObjs.get(position).getAsJsonObject().get(Constants.JSON.JSON_VALUE).getAsInt()) + ",00");
holder.ticketDate.setText(mObjs.get(position).getAsJsonObject().get(Constants.KEY.KEY_EVENTDATE).getAsString());
holder.ticketTitle.setText(mObjs.get(position).getAsJsonObject().get(Constants.JSON.JSON_EVENTTITLE).getAsString());
holder.ticketFirstName.setText(arrayFirstName.get(holder.position));
holder.ticketLastName.setText(arrayLastName.get(holder.position));
options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ico_load_imagem)
.cacheInMemory().cacheOnDisc()
.displayer(new RoundedBitmapDisplayer(5))
.build();
imageLoader.displayImage(mObjs.get(position).getAsJsonObject().get("thumbPrincipal").getAsString(), holder.ticketImageThumb, options);
return vi;
}
private View.OnFocusChangeListener LastNameFocusChangeListener(final int position) {
return new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus){
viewID = holder.position;
}
}
};
}
private View.OnFocusChangeListener FirstNameFocusChangeListener(final int position) {
return new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus){
viewID = holder.position;
}
}
};
}
private TextWatcher FirstNameChangedListener(final int position) {
return 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) {
}
#Override
public void afterTextChanged(Editable s) {
String itemName = s.toString();
arrayFirstName.add(viewID, itemName);
}
};
}
private TextWatcher LastNameChangedListener(final int position) {
return 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) {
}
#Override
public void afterTextChanged(Editable s) {
String itemName = s.toString();
arrayLastName.add(viewID, itemName);
}
};
}
}
EDIT: Removed setId and JSON.
Your holder is a member of your class, it's wrong.
Remove it from this place. Every line of your listview has its own holder.
This holder is "sticked" to the view by the setTag method.
In listeners that used holder, you have to get the holder from the view that send the event.
For this, the following code should work:
private View.OnFocusChangeListener FirstNameFocusChangeListener(final int position) {
return new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus){
ViewHolder holder = (ViewHolder ) v.getTag();
viewID = holder.position;
}
}
};
}
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"