使用RecyclerView创建自定义警告对话框

10

我正在使用RecyclerView列出一些文本,现在我想使当用户点击文字时弹出一个自定义的警告对话框。

迄今为止,我尝试了这个方法,但出现了NullPointerException;可能有什么问题吗?

public class CBAdapter extends RecyclerView.Adapter<CBAdapter.ViewHolder> {

List<AdapterData> mItems;

public CBAdapter() {
    super();
    mItems = new ArrayList<>();
    AdapterData data = new AdapterData();
    data.setTextOne("Many Bows");
    mItems.add(data);

    data = new AdapterData();
    data.setTextOne("Pardon");
    mItems.add(data);

    data = new AdapterData();
    data.setTextOne("Fall To Knees & Beg");
    mItems.add(data);

    data = new AdapterData();
    data.setTextOne("Backflips");
    mItems.add(data);



}

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext())
            .inflate(R.layout.test3, viewGroup, false);
    return new ViewHolder(v);
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
    AdapterData data = mItems.get(i);
    viewHolder.textOne.setText(data.getTextOne());

}


@Override
public int getItemCount() {

    return mItems.size();
}

class ViewHolder extends RecyclerView.ViewHolder{

    public TextView textOne;
    private Context context;





    public ViewHolder(View itemView) {
        super(itemView);
        textOne = (TextView)itemView.findViewById(R.id.textView1);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                final Dialog dialog = new Dialog(context);
                dialog.setContentView(R.layout.custom_dialog);
                dialog.setTitle("Title");

                TextView text = (TextView) dialog.findViewById(R.id.text);
                text.setText("hello world");

                ImageView image = (ImageView) dialog.findViewById(R.id.image);
                image.setImageResource(R.drawable.ic_launcher);

                Button dialogButton = (Button) dialog.findViewById(R.id.dialogButtonOK);

                dialogButton.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dialog.dismiss();
                    }
                });

                dialog.show();
            }
        });


    }
}
}

请检查ID custom_dialogtextimagedialogButtonOK是否正确编写。 - Benjamin Scharbau
是的,它显示了空指针,并将问题指向了这个:final Dialog dialog = new Dialog(context); - Jacques Krause
1
你的 context 初始化在哪里? - Emil
这是因为您使用了上下文,但从未给它赋值。 - Rajen Raiyarela
6个回答

6

不要紧,我忘记初始化上下文了。

context = itemView.getContext();


3

这并不是你问题的答案,但是处理这种情况的更好方法是使用回调方法。

使用回调方法。

在你的 Activity 中:

这将实现我们在 Adapter 中拥有的接口。在本例中,它将在用户点击 RecyclerView 中的项目时被调用。

  public class MyActivity extends Activity implements AdapterCallback {

    private MyAdapter mMyAdapter;

    @Override
    public void onMethodCallback() {
       // Show your alert
    }

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.mMyAdapter = new MyAdapter(this);
    }
}

在你的适配器中:

在Activity中,我们初始化了我们的Adapter并将其作为参数传递给构造函数。这将初始化我们回调方法的接口。您可以看到我们使用回调方法处理用户单击事件。

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private AdapterCallback mAdapterCallback;

    public MyAdapter(Context context) {
        try {
            this.mAdapterCallback = ((AdapterCallback) context);
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement AdapterCallback.");
        }
    }

    @Override
    public void onBindViewHolder(final MyAdapter.ViewHolder viewHolder, final int i) {
        // simple example, call interface here
        // not complete
        viewHolder.itemView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    mAdapterCallback.onMethodCallback();
                } catch (ClassCastException exception) {
                   // do something
                }
            }
        });
    }

    public static interface AdapterCallback {
        void onMethodCallback();
    }
}

来源 : 从适配器中调用活动方法


2
final Dialog dialog = new Dialog(your_activity_context);

0

虽然与问题不直接相关,但我恳求您:请勿在适配器内设置onClickListener-s!

以下是正确的做法:

private class ItemDataHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener{

    private final String TAG = ItemDataHolder.class.getSimpleName();

    /**
     * Define view's elements
     */

    /**
     *  Define object instance
     */
    private Item mData;

    // Constructor
    public MessageDataHolder(View itemView) {
        super(itemView);
        /**
         * Init elements
         */
        itemView.setOnLongClickListener(this);
    }

    /**
     * Method to handle long click on the item
     * @param v View to handle click on
     * @return
     */
    @Override
    public boolean onLongClick(View v) {
        Log.v(TAG, "Long click fired!");
        return false;
    }

    /**
     * Function to update view's elements
     * @param message Good data to be updated to
     */
    public void bindData(Item message) {
        mData = message;
        /**
        * Set values of views here
        **/
    }
}

希望我的回答能帮助某人写出更好的代码 :)

1
如果您非常注重不在适配器内设置onClickListeners,那么能否告诉我们为什么这样做,以便我们都能从您的知识中学习?另外,我们如何拥有两个执行不同操作的按钮? - Timmiej93

0

你正在使用 context,但它是null,所以请在ViewHolder构造函数和CBAdapter构造函数中传递context,如下所示:

public class CBAdapter extends RecyclerView.Adapter<CBAdapter.ViewHolder> {

List<AdapterData> mItems;
Context context;

public CBAdapter(Context context) {
    super();
    this.context = context;
    .....
  }

在 ViewHolder 类中

class ViewHolder extends RecyclerView.ViewHolder{

    public TextView textOne;
    private Context mcontext;


    public ViewHolder(View itemView, Context mcontext) {
        super(itemView);
        this.mcontext = mcontext;
        ....
   }

-2
编写这段代码:
 final Dialog dialog = new Dialog(CBAdapter.this);

而不是

final Dialog dialog = new Dialog(context);

(或者)

context = CBAdapter.this; // Initialize context

希望这可以帮到你。 愉快编程 :)

这并没有回答问题,适配器类除了活动之外无法使用上下文。 - Umar Ata

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接