Как создать диалоговое окно при нажатии на элемент recyclerview?

#java #android

Вопрос:

Я пытаюсь создать функцию, которая, как только пользователь нажмет на представление переработчика, появится диалоговое окно, но я застрял на ошибке, как указано ниже. Когда я пытаюсь инициализировать AlertDialog.build и указать this в качестве параметра, он показывает ошибку. Я попытался использовать несколько других параметров, таких как контекст, getActivity. Но ошибка все та же.

введите описание изображения здесь

Приведенный ниже код-это мой полный код

 package com.example.tuitioncentre;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.Observable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.firestore.DocumentSnapshot;

public class myadapter_tutorlist extends FirebaseRecyclerAdapter<User,myadapter_tutorlist.myviewholder> {

    AlertDialog.Builder builder;


    public myadapter_tutorlist(@NonNull FirebaseRecyclerOptions<User> options) {
        super(options);
    }

    @Override
    protected void onBindViewHolder(@NonNull final myviewholder holder, int position, @NonNull final User model) {

        holder.name.setText("Tutor's Name:"   model.getUsername());
        holder.phone.setText("Phone No:"   model.getPhone());
        holder.email.setText("Email:"   model.getEmail());
        holder.status.setText("Status: "   model.getActive().toString());
        builder = new AlertDialog.Builder(this);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(final View v) {
                //Toast.makeText(v.getContext(),model.getUsername(),Toast.LENGTH_SHORT).show();

                builder.setMessage(R.string.dialog_message) .setTitle(R.string.dialog_title);
                builder.setMessage("Do you want to activate tutor account ?")
                        .setCancelable(false)
                        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                Toast.makeText(v.getContext(),"you choose yes action for alertbox", Toast.LENGTH_SHORT).show();
                            }
                        })
                        .setNegativeButton("No", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                //  Action for 'NO' Button
                                dialog.cancel();
                                Toast.makeText(v.getContext(),"you choose no action for alertbox", Toast.LENGTH_SHORT).show();
                            }
                        });
                //Creating dialog box
                AlertDialog alert = builder.create();
                //Setting the title manually
                alert.setTitle("AlertDialogExample");
                alert.show();
            }
        });
    }
    @NonNull
    @Override
    public myviewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //put singlerow xml into view holder
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.singlerow,parent,false);
        return new myviewholder(view);
    }


    class myviewholder extends RecyclerView.ViewHolder{
        TextView name,phone,email,status;
        public myviewholder(@NonNull View itemView) {
            super(itemView);
            name=(TextView)itemView.findViewById(R.id.nametext);
            phone=(TextView)itemView.findViewById(R.id.phonetext);
            email=(TextView)itemView.findViewById(R.id.emailtext);
            status=(TextView)itemView.findViewById(R.id.statustext);
        }
        
    }
}
 

Комментарии:

1. я не знаю, почему вы столкнулись с этой ошибкой, но я запустил ваш код диалогового окна предупреждения в своем коде представления переработчика шаблонов и успешно выполнил его. это лучше, если вы определяете класс прослушивателя щелчка отдельно и определяете диалоговое окно предупреждения в классе MainActivity как обратный вызов

2. Спасибо, это действительно успешно работает, когда я определяю класс прослушивателя щелчков в MainActivity.

3. Ваше приветствие, вам лучше определить интерфейс прослушивателя щелчков отдельно и реализовать методы интерфейса в основной активности в качестве обратного вызова. это продвинутый подход

4. я написал это для вас, как показано ниже. вы можете сохранить его для своих будущих проектов.

Ответ №1:

Передача «этого» AlertDialog.Builder(this); не будет работать, так как вы пытаетесь передать ссылку на свой адаптер.

Есть два правильных способа добиться этого:

Добавьте переменную для ссылки на вашу активность, как Activity mActivity; в вашем классе адаптера. Затем в классе действий, в котором вы инициализируете адаптер, вы можете передать контекст действия как «это». Вы можете добиться этого либо с помощью конструктора в классе адаптера, либо в своем классе действий, используя свой adapter экземпляр после его инициализации для доступа к mActivity переменной и ее установки.

В качестве альтернативы вы можете использовать интерфейс представления и реализовать его в своей деятельности, переопределив метод, чтобы отобразить журнал уведомлений в своей деятельности. Затем добавьте ссылочную переменную этого интерфейса в свой адаптер, например SomeInterface mInfterface; , и инициализируйте ее в своем классе активности тем же способом, о котором говорилось выше. Затем вы можете просто вызвать этот метод, чтобы отобразить журнал уведомлений, и передать данные этому методу с адаптера, чтобы отобразить всю информацию, например —

 mInterface.showAlertDialog(model);
 

Комментарии:

1. Спасибо за ваше предложение, но мне кажется, что это не сработает.

Ответ №2:

сначала создайте этот класс:

 class RecyclerItemClickListener extends RecyclerView.SimpleOnItemTouchListener {
interface OnRecyclerClickListener{
    void onItemClick(View view, int position);
}

private final OnRecyclerClickListener mListener;
private final GestureDetectorCompat mGestureDetector;


public RecyclerItemClickListener(Context context, final RecyclerView recyclerView,
                                 OnRecyclerClickListener listener) {
    mListener = listener;

    mGestureDetector = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener(){
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
          View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
            if (childView != null amp;amp; mListener != null){
                Log.d(TAG, "onSingleTapUp: calling listener.onItemClick");
                mListener.onItemClick(childView, recyclerView.getChildAdapterPosition(childView));
            }
            return true;
        }
});
}

@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
    if (mGestureDetector != null){
        boolean result = mGestureDetector.onTouchEvent(e);
        return resu<
    } else {
        return false;
    }
}
}
 

и в основной деятельности:

в методе onCreate: сначала определите переменную RecyclerView с помощью findviewbyid (), затем:

         recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, recyclerView, this));
 

затем реализуйте метод onItemClick (). вы можете определить диалоговое окно предупреждения здесь:

 @Override
public void onItemClick(View view, int position) {
    Toast.makeText(this, "normal tap on position "   position, Toast.LENGTH_SHORT).show();

}
 

Ответ №3:

Сначала передайте context из действия или фрагмента:

Для деятельности:

 myadapter_tutorlist(options, this);
 

Для Фрагмента:

 myadapter_tutorlist(options, getActivity());
 

Затем создайте контекстную переменную в стороне класса адаптера:

 public class myadapter_tutorlist extends FirebaseRecyclerAdapter<User,myadapter_tutorlist.myviewholder> {

    AlertDialog.Builder builder;
    Context context;


    public myadapter_tutorlist(@NonNull FirebaseRecyclerOptions<User> options) {
        super(options);
        this.context = context;
    }
 

Теперь вы можете передать этот контекст в свой AlertDialog

 builder = new AlertDialog.Builder(context);