Bart Sumps
Bart Sumps

Reputation: 47

How to open AlertDialog by clicking on RecyclerView item?

I have a little problem. I cant open AlertDialog by clicking on RecyclerView item.. Here is my AlertDialog code:

public class LoginDialog extends AppCompatDialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        LayoutInflater inflater = getActivity().getLayoutInflater();
        View view = inflater.inflate(R.layout.dialog_fragment, null);
        builder.setView(view)
                .setTitle("Login")
                .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
        return builder.create();
    }
}

Now I want to display it by clicking on RecyclerView item. Here is the Adapter code:

public class UserAdapter extends  RecyclerView.Adapter<UserAdapter.UserViewHolder> {
    private List<UserModel> list;
    Context context;

    public UserAdapter(List<UserModel>list, Context context){
        this.context = context;
        this.list = list;
    }

    @Override
    public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new UserViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false));
    }

    @Override
    public void onBindViewHolder(final UserViewHolder holder, int position) {
        UserModel user = list.get(position);
        holder.textName.setText(user.name + " " + user.surname);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
               LoginDialog loginDialog = new LoginDialog();
               loginDialog.show()
            }
        });
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    public class UserViewHolder extends RecyclerView.ViewHolder{

        TextView textName;

        public UserViewHolder(View itemView) {
            super(itemView);
            textName = itemView.findViewById(R.id.textName);
        }
    } 
}

Sadly, I cannot do nothing with loginDialog.show(). I can't resolve getSupportFragmentManager or getFragmentManager. The only option is to create new function called show in LoginDialog class. But then I get NPE all the time..

Upvotes: 2

Views: 2790

Answers (3)

Reaz Murshed
Reaz Murshed

Reputation: 24211

I would suggest you modify your LoginDialog like the following.

public class LoginDialog extends AppCompatDialogFragment {

    private Context context;

    public LoginDialog(Context context) {
        this.context = context;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        LayoutInflater inflater = ((AppCompatActivity)context)).getLayoutInflater();
        View view = inflater.inflate(R.layout.dialog_fragment, null);
        builder.setView(view)
                .setTitle("Login")
                .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {

                    }
                });
        return builder.create();
    }
}

The idea is to create a constructor and pass the context to your LoginDialog each time you are creating it from your adapter. Then while creating the Dialog you need to pass the context every time.

holder.itemView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
       LoginDialog loginDialog = new LoginDialog(context);
       loginDialog.show()
    }
});

Hope that helps.

Upvotes: 0

SpiritCrusher
SpiritCrusher

Reputation: 21053

You already have Context in Adapter . So you can directly use it .

LoginDialog dialogFragment = new LoginDialog ();
 dialogFragment.show(((AppCompatActivity)context).getSupportFragmentManager(), "Fragment");

Upvotes: 2

Viktor Yakunin
Viktor Yakunin

Reputation: 3296

If you want to make things better you need to understand responsibility of Adapter and Activity. Adapter should bind data to views and that's it. If you want to show Dialog on item click it's better to do it like:

public UserAdapter(List<UserModel>list, Context context, View.OnClickListener itemClickListener){
        this.list = list;
        this.context = context;
        this.itemClickListener = itemClickListener;
}

......
@Override
public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    return new UserViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false), itemClickListener);
}
......
public class UserViewHolder extends RecyclerView.ViewHolder{
    TextView textName;

    public UserViewHolder(View itemView, View.OnClickListener itemClickListener) {
        super(itemView);
        textName = itemView.findViewById(R.id.textName);
        itemView.setOnClickListener(itemClickListener);
    }
} 
....

In Your fragment/activity:

adapter = new UserAdapter(List<UserModel>list, Context context, new View.OnClickListener(){
   new LoginDialog().show(supportFragmentManager, LoginDialog.TAG)
})

Upvotes: 0

Related Questions