Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android- Adjacent buttons in list view automatically clicked

I am working on a module that populates cart. I used ListView and extended BaseAdapter to populate the cart items. With each of the item in ListView, I embedded two button(inc and dec) to increment and decrement quantity of item in cart.

ListView is correctly updated, but increment/decrement button on quick click/tapping shows abrupt behaviour.

Whenever I quickly tap any of inc or dec button, the corresponding inc or dec button of an item next to current item in ListView is automatically clicked(along with current item btn).

In other words, whenever I quickly tap inc btn of ith item in ListView, inc btn of i+1 th item in ListView is automatically clicked( along with inc btn of ith item).

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item_cart, parent, false);
        holder = new ViewHolder();
        holder.baseItem = (TextView) convertView.findViewById(R.id.qnt_tv);
        holder.qntInc = (TextView) convertView.findViewById(R.id.inc_btn);
        holder.qntDec = (TextView) convertView.findViewById(R.id.dec_btn);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    final CartModel cm = mCart.get(position);
    holder.baseItem.setText(cm.getmTitle());
    holder.qntSel.setText(String.valueOf(cm.getmQnt()));
    holder.qntInc.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (qntSpinnerCb != null)
                qntSpinnerCb.changeQuantityOfSelectedItemInCart(cm.getmIid(), INCREASE_QNT);
        }
    });
    holder.qntDec.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if (qntSpinnerCb != null) {
                qntSpinnerCb.changeQuantityOfSelectedItemInCart(cm.getmIid(), DECREASE_QNT);
            }
        }
    });

    return convertView;
}

Interface for callback

public interface CartQntSpinnerListenerCallBack {
    void changeQuantityOfSelectedItemInCart(String iId, char changeType);
}

Tried debugging, unable to figure out this weird behavior.

like image 772
Ritesh Kumar Gupta Avatar asked Jul 01 '15 18:07

Ritesh Kumar Gupta


3 Answers

You are not selecting correct CartModel inside onClick, if you want to get correct object inside onclick then you have to tag position to button

holder.qntInc.setTag(position);

in onClick:

@Override
public void onClick(View view) {
    if (qntSpinnerCb != null) {
        CartModel cm= mCart.get((Integer)view.getTag);
        qntSpinnerCb.changeQuantityOfSelectedItemInCart(cm.getmIid(), INCREASE_QNT);
    }
}

Follow the same for qntDec.

like image 61
Jaiprakash Soni Avatar answered Nov 03 '22 20:11

Jaiprakash Soni


If you want to keep your current implementation, do this.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
    convertView = mInflater.inflate(R.layout.list_item_cart, parent, false);
}

ViewHolder holder = new ViewHolder();

holder.baseItem = (TextView) convertView.findViewById(R.id.qnt_tv);
holder.qntInc = (TextView) convertView.findViewById(R.id.inc_btn);
holder.qntDec = (TextView) convertView.findViewById(R.id.dec_btn);


...

Without seeing the rest of your code, however, I think you may want to reconsider how you are implementing BaseAdapter. Traditionally, they are used in conjunction with a list view to recycle views for efficiency. This means when a list scrolls a view out of frame, instead of redrawing the view - if(convertView == null) - it reuses it. What I think you are experiencing is that you are putting a click listener for two different objects on the same button.

What I would recommend doing is something more like this:

@Override
public int getCount() {
    return objects.size();
}

@Override
public CartModel getItem(int position) {
    // mCart sounds like a single item but is a list? I advise you to rename
    return objects.get(position);
}

@Override
public long getItemId(int position) {
    // Implement with id. Copied the id call from your code..
    return getItem(position).getmIid();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item_cart, parent, false);
    }

    CartModel cm = getItem(position);

    TextView baseItem = (TextView) convertView.findViewById(R.id.qnt_tv);
    baseItem.setText(cm.getmTitle());

    // Organize like items together for readability
    TextView qntInc = (TextView) convertView.findViewById(R.id.inc_btn);
    qntInc.setTag(mCartKey, cm);
    qntInc.setOnClickListener(this);

    // readability
    TextView qntDec = (TextView) convertView.findViewById(R.id.dec_btn);
    qntDec.setTag(mCartKey, cm);
    qntDec.setOnClickListener(this);


    // Defined in convert view?
    qntSel.setText(String.valueOf(cm.getmQnt()));


    return convertView;
}

@Override
public void onClick(View v) {

    switch(v.getId()){
        case R.id.R.id.inc_btn:
            CartModel cm = (CartModel)v.getTag(mCartKey);
            // What is this?
            if (qntSpinnerCb != null)
                qntSpinnerCb.changeQuantityOfSelectedItemInCart(cm.getmIid(), INCREASE_QNT);

            break;


        case R.id.dec_btn:

            CartModel cm = (CartModel)v.getTag(mCartKey);
            if (qntSpinnerCb != null) {
                qntSpinnerCb.changeQuantityOfSelectedItemInCart(cm.getmIid(), DECREASE_QNT);
            }
            break;
    }

}

NOTE: BaseAdapter class must implement OnClickListener

like image 33
PSchuette Avatar answered Nov 03 '22 19:11

PSchuette


store the position of your view in your viewholder and use it every where in the setonclicklistner from viewHolder that position you will not see any absurd behaviour it will work as you want

static class ViewHolder {
    TextView baseItem, qntInc, qntDec;
    ....../* your code goes here */
    int position
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.list_item_cart, parent, false);
        holder = new ViewHolder();
        holder.baseItem = (TextView) convertView.findViewById(R.id.qnt_tv);
        holder.qntInc = (TextView) convertView.findViewById(R.id.inc_btn);
        holder.qntDec = (TextView) convertView.findViewById(R.id.dec_btn);
        holder.position=position
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
        holder.position=position;
    }
    CartModel cm = mCart.get(holder.position);
    holder.baseItem.setText(cm.getmTitle());
    holder.qntSel.setText(String.valueOf(cm.getmQnt()));
    holder.qntInc.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) { 

            CartModel cm = mCart.get(holder.position);
            qntSpinnerCb.changeQuantityOfSelectedItemInCart(cm.getmIid(), INCREASE_QNT);
        }  
    });

    holder.qntDec.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            CartModel cm = mCart.get(holder.position); 
            qntSpinnerCb.changeQuantityOfSelectedItemInCart(cm.getmIid(), DECREASE_QNT);

        }
    });

    return convertView;
}

also check the value of INCREMENT_QNT and DECREACE_QNT

like image 1
Naval Kishor Jha Avatar answered Nov 03 '22 19:11

Naval Kishor Jha