【问题标题】:Attaching a ClickListener to a list item button click in a custom adapter将 ClickListener 附加到列表项按钮单击自定义适配器
【发布时间】:2018-12-03 13:31:13
【问题描述】:

我有这个自定义适配器

public class ProductAdapter extends ArrayAdapter<Product> {

Context mContext;

public ProductAdapter(Activity context, ArrayList<Product> products) {
    super(context, 0, products);
}

@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View listItemView = convertView;
    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.list_item, parent, false);
    }

    Product currentProduct = getItem(position);

    TextView nameTextView = (TextView) listItemView.findViewById(R.id.product_name);

    nameTextView.setText(currentProduct.getProductName());

    TextView numberTextView = (TextView) listItemView.findViewById(R.id.product_price);

    numberTextView.setText("$"+currentProduct.getProductPrice());

    ImageView iconView = (ImageView) listItemView.findViewById(R.id.list_item_icon);

    iconView.setImageResource(currentProduct.getProductImage());

    Button buyNow = (Button) listItemView.findViewById(R.id.buy_now);

    buyNow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(mContext,"test", Toast.LENGTH_SHORT).show();
        }
    });

    return listItemView;
  }
}

list_item 中的这个按钮

<Button
        android:id="@+id/buy_now"
        android:text="Buy Now"
        style="@style/listBtn" />

如您所见,我已将 mContext 定义为 Context 以在适配器内部使用它。

单击按钮会使应用程序关闭并且它不起作用。如何在自定义适配器中正确创建onClickListener?

【问题讨论】:

  • 尝试 Toast.makeText(v.getContext(),"test", Toast.LENGTH_SHORT).show();或者您可以在应用崩溃时发布异常

标签: android onclicklistener custom-adapter


【解决方案1】:

看起来您的 mContext 为空(我猜),因为您似乎没有在任何地方实例化它。

试试这个代码(你可以复制/粘贴)

public class ProductAdapter extends ArrayAdapter<Product> {

// Use getContext() instead of this property
//Context mContext;

public ProductAdapter(Activity context, ArrayList<Product> products) {
    super(context, 0, products);
}

@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {

    View listItemView = convertView;
    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.list_item, parent, false);
    }

    Product currentProduct = getItem(position);

    TextView nameTextView = (TextView) listItemView.findViewById(R.id.product_name);

    nameTextView.setText(currentProduct.getProductName());

    TextView numberTextView = (TextView) listItemView.findViewById(R.id.product_price);

    numberTextView.setText("$"+currentProduct.getProductPrice());

    ImageView iconView = (ImageView) listItemView.findViewById(R.id.list_item_icon);

    iconView.setImageResource(currentProduct.getProductImage());

    Button buyNow = (Button) listItemView.findViewById(R.id.buy_now);

    buyNow.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Toast.makeText(getContext(),"test", Toast.LENGTH_SHORT).show();
        }
    });

    return listItemView;
  }
}

我刚刚删除了您的 mContext 属性,因为您可以在适配器内的任何位置使用 getContext()

【讨论】:

    【解决方案2】:

    当你在listview或recyclerview中执行点击事件时,像这样在适配器类中创建接口..

        onItemClickListner onItemClickListner;
    
    public void setOnItemClickListner(CommentsAdapter.onItemClickListner onItemClickListner) {
        this.onItemClickListner = onItemClickListner;
    }
    
    public interface onItemClickListner {
        void onClick(int position);//pass your object types.
    }
    

    在那之后 getView() in..

            buyNow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onItemClickListner.onClick(position); // pass your data.
            }
        });
    

    然后在调用点击事件之后创建适配器对象并绑定到列表视图..确保您的适配器不为空

            adapter.setOnItemClickListner(new CommentsAdapter.onItemClickListner() {
            @Override
            public void onClick(int position) {
                // here show your toast or data
                adapter.notifyDataSetChanged();
            }
        });
    

    【讨论】:

      【解决方案3】:

      您的 mContext 未初始化。

      您可以像这样从视图中获取上下文:

      public void onClick(View v) {
              Toast.makeText(v.getContext(),"test", 
      Toast.LENGTH_SHORT).show();
          }
      

      【讨论】:

        【解决方案4】:

        您可以通过以下三种不同的方式执行此操作。

        方法1:在构造函数中初始化你的上下文,你可以创建如下:

        Context mContext;
        List<Product> products
        
        public ProductAdapter(Context mContext, List<Product> products) {
            super(context, 0, products);
        
            this.mContext = mContext;
            this.products = products;
        }
        

        然后是您在代码中使用的上下文。

        方法 - 2:在适配器中创建自定义侦听器并按如下方式使用:

        //你在Adapter中的接口

        private onItemViewClickListener itemViewClickListener;
        

        //你的客户界面定义

        public interface onItemViewClickListener{
               void onClick(View view, int position, Object object)
        }
        

        //你的接口的Setter方法

        public void setItemViewClickListener(onItemViewClickListener itemViewClickListener) {
                this.itemViewClickListener = itemViewClickListener;
        }
        

        //您的视图点击事件,您必须设置如下值:

        convertView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (itemViewClickListener != null){
                            itemViewClickListener.onClick(v, position, object);
                        }
                    }
                });
        

        在您的适配器中编写上面的代码,在您使用适配器的活动或片段中编写下面的代码,例如,如果您在活动中使用此适配器,您可以通过以下两种方式使用它。

        TestAdapter adapter = new TestAdapter();
        adapter.setItemViewClickListener(new TestAdapter.onItemViewClickListener() {
            @Override
            public void onClick(View view, int position, Object object) {
                        //Here your logic
            }
        });
        

        或者,如果您在活动类中实现适配器接口,则必须使用以下代码,并且在您可以编写逻辑的类中实现后,您的 click 方法将被覆盖:

        TestAdapter adapter = new TestAdapter();
        adapter.setItemViewClickListener(this);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-15
          • 2018-09-19
          • 2011-12-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多