Android-列表视图中的相邻按钮会自动单击

时间:2015-07-01 18:38:27

标签: android listview

我正在开发一个填充购物车的模块。我使用ListView和扩展BaseAdapter来填充购物车项目。 对于ListView中的每个项目,我嵌入了两个按钮(inc和dec)来增加和减少购物车中的商品数量。

ListView已正确更新,但快速点击/点按时的递增/递减按钮会显示突然行为。

每当我快速点击inc或dec按钮时,会自动点击ListView中当前项目旁边项目的相应inc或dec按钮(以及当前项目btn)。

换句话说,每当我快速点击ListView中第i个项目的inc btn时,ListView中i + 1项的inc btn会自动点击(连同第i项的inc btn)。

@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;
}

回调接口

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

尝试调试,无法弄清楚这种奇怪的行为。

5 个答案:

答案 0 :(得分:9)

你没有在CartModel内选择正确的onClick,如果你想在onclick内获得正确的对象,那么你必须将位置标记为按钮

holder.qntInc.setTag(position);
onClick上的

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

qntDec进行相同操作。

答案 1 :(得分:3)

如果您想保留当前的实施,请执行此操作。

@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);


...

但是,如果没有看到其余的代码,我想您可能想重新考虑如何实现BaseAdapter。传统上,它们与列表视图结合使用以回收视图以提高效率。这意味着当列表滚动视图超出帧时,而不是重绘视图 - 如果(convertView == null) - 它重用它。我认为您遇到的是您在同一个按钮上为两个不同的对象设置了一个点击监听器。

我建议做的更像是这样:

@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;
    }

}

注意:BaseAdapter类必须实现OnClickListener

答案 2 :(得分:1)

将您的观点的位置存储在viewholder中,并在setonclicklistner viewHolder的{​​{1}}所有位置使用它,您将看不到任何荒谬的行为,它将按您的意愿运作< / p>

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

还会检查INCREMENT_QNTDECREACE_QNT

的值

答案 3 :(得分:-1)

代码中存在问题。

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

    // This should be added in the code
    holder.qntSel = (TextView) convertView.findViewById(R.id.sec_txt);

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

答案 4 :(得分:-1)

我怀疑y中的getter方法getmIid()有问题。此方法返回错误的索引,因此您的下一个/上一个按钮正在更新

我建议在回调CartModel第一个参数中使用position整数。因为changeQuantityOfSelectedItemInCart()回调

,所以该位置将始终正确

解决方案:

getView()

holder.qntInc.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (qntSpinnerCb != null) qntSpinnerCb.changeQuantityOfSelectedItemInCart(position+"", INCREASE_QNT); } }); holder.qntDec.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (qntSpinnerCb != null) qntSpinnerCb.changeQuantityOfSelectedItemInCart(position+"", DECREASE_QNT); } }); position类型,您的回调需要int,因此我们应该使用String

希望这对你有用