将ClickListener附加到列表项按钮上,然后单击自定义适配器

时间:2018-12-03 13:31:14

标签: android onclicklistener 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?

4 个答案:

答案 0 :(得分: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()

答案 1 :(得分:0)

当您在listview或recyclerview中执行click事件时,将以这种方式将接口创建到适配器类。

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

在创建适配器对象之后,在调用click事件之后绑定到列表视图中。确保您的适配器不为空

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

答案 2 :(得分:0)

您的mContext未初始化。

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

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

答案 3 :(得分:0)

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

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

Context mContext;
List<Product> products

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

    this.mContext = mContext;
    this.products = products;
}

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

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

//您在适配器中的界面

private onItemViewClickListener itemViewClickListener;

//您的用户界面定义

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

//界面的设置方法

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