【问题标题】:Android- Adjacent buttons in list view automatically clickedAndroid-自动点击列表视图中的相邻按钮
【发布时间】:2015-07-01 18:38:27
【问题描述】:

我正在开发一个填充购物车的模块。我使用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);
}

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

【问题讨论】:

  • 您强调“快速点击”一词。那么,当您缓慢点击按钮时,还是仅在未点击相邻项目时?
  • “baseItem”是否有固定宽度?在 changeQuantityOfSelectedItemInCart() 之后,Inc/Dec 按钮的位置可能会发生变化,这会导致突然的行为。我猜。 (或在更改布局时点击)
  • 添加qntSpinnerCb 的代码以及它所涉及的任何内容。 OnClickListener() 实例似乎是合理的。
  • 你能显示你的xml代码吗?
  • 什么是 mCart?如果可能,我要求您发布完整的适配器类。

标签: android listview


【解决方案1】:

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

holder.qntInc.setTag(position);

在点击中:

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

qntDec 也是如此。

【讨论】:

    【解决方案2】:

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

    @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。传统上,它们与列表视图结合使用以回收视图以提高效率。这意味着当列表将视图滚动出框架时,而不是重绘视图 - if(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

    【讨论】:

      【解决方案3】:

      将视图的位置存储在您的viewholder 中,并在viewHoldersetonclicklistner 中的每个位置使用它,您不会看到任何荒谬的行为,它将按照您的意愿工作

      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 的值

      【讨论】:

      【解决方案4】:

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

      我建议在你的回调changeQuantityOfSelectedItemInCart() 第一个参数中使用position 整数。因为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);
              }
          });
      

      positionint 类型,你的回调需要String 所以我们应该使用position+""

      希望这对你有用

      【讨论】:

      • 拒绝投票的原因是什么?应添加至少评论以进一步修改答案..不必要地对这个问题的每个答案都投了反对票..
      【解决方案5】:

      代码有问题。

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

      【讨论】:

      • 投反对票的原因是什么?响应基于提供的输入。如果事情应该在没有正当理由的情况下被假设/理解,那么每个人都应该是(过度)这里的专业人士并且不需要帮助。伤心..
      猜你喜欢
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多