将 ClickListener 附加到自定义适配器中的列表项按钮单击

Attaching a ClickListener to a list item button click in a custom adapter

我有这个自定义适配器

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?

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

试试这个代码(你可以copy/paste)

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

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

    onItemClickListner onItemClickListner;

public void setOnItemClickListner(CommentsAdapter.onItemClickListner onItemClickListner) {
    this.onItemClickListner = onItemClickListner;
}

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

在 getView() 之后..

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

您的 mContext 未初始化。

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

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

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

方法 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);
                }
            }
        });

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

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

或者,如果您在 activity class 中实现适配器接口,那么您必须使用以下代码,并且在 class 中实现后您的点击方法将被覆盖,您可以写下你的逻辑:

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