将 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);
我有这个自定义适配器
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);