web-dev-qa-db-ja.com

RecyclerViewを使用したカスタムアラートダイアログ

テキストをリストするために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();
            }
        });


    }
}
}
10
Jacques Krause

コンテキストの初期化を忘れた

context = itemView.getContext();

5
Jacques Krause

これはクエリに対する答えではありませんが、このシナリオを処理するためのより良い方法です。

コールバックメソッドを使用します。

アクティビティ内:

これは、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);
    }
}

アダプタ内:

アクティビティでは、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();
    }
}

提供:アダプタからアクティビティメソッドを呼び出す

3
Anoop M
final Dialog dialog = new Dialog(your_activity_context);
2
Nikunj

質問には直接関係ありませんが、お願いします:アダプター内で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
        **/
    }
}

私の答えが誰かがより良いコードを書くのに役立つことを願っています:)

0
egorikem

nullであるcontextを使用しているので、contextViewHolderコンストラクターとCBAdapterコンストラクターに渡します。未満:

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;
        ....
   }
0
Pankaj