【问题标题】:Custom Alert Dialog With RecyclerView带有 RecyclerView 的自定义警报对话框
【发布时间】:2016-02-07 05:10:15
【问题描述】:

我正在使用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是否写正确
  • 是的,它显示空指针并指出这是问题:final Dialog dialog = new Dialog(context);
  • 你的context初始化在哪里?
  • 发生这种情况是因为您使用了上下文,但您从未为其分配任何值。

标签: android android-alertdialog android-recyclerview


【解决方案1】:

没关系,我忘了初始化我的上下文

上下文 = itemView.getContext();

【讨论】:

    【解决方案2】:

    这不是您查询的答案,而是处理这种情况的更好方法。

    使用回调方法。

    在您的活动中:

    这将实现我们在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();
        }
    }
    

    礼貌: Call Activity method from adapter

    【讨论】:

      【解决方案3】:
      final Dialog dialog = new Dialog(your_activity_context);
      

      【讨论】:

        【解决方案4】:

        您正在使用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;
                ....
           }
        

        【讨论】:

          【解决方案5】:

          与问题没有直接关系,尽管我求你:不要在适配器内部设置 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
                  **/
              }
          }
          

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

          【讨论】:

          • 如果您对不在适配器内部设置 onClickListeners 这么具体,您介意告诉我们这是为什么,以便我们都可以从您的知识中学习吗?另外,我们如何让两个按钮做不同的事情?
          【解决方案6】:

          写下这段代码:

           final Dialog dialog = new Dialog(CBAdapter.this);
          

          而不是

          final Dialog dialog = new Dialog(context);
          

          (或)

          context = CBAdapter.this; // Initialize context
          

          希望这会有所帮助。

          快乐编码:)

          【讨论】:

          • 这没有提供问题的答案,并且适配器类不能有可用的上下文,除了活动
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多