У меня есть AlertDialog
, который отлично работает с Activites
, но не работает с фрагментами из-за AlertDialog.Builder(getActivity)
. В этом случае родительский Activity содержит дочерний элемент Fragment
, который использует RecyclerView
для отображения записей. Когда пользователь проводит запись, отображается AlertDialog
, чтобы подтвердить удаление. Однако это не работает, так как AlertDialog
ссылается на родительское действие. Я включил код AlertDialog и вывод LogCat из кода AlertFragment ниже.
Я создаю экземпляр ConfirmDialogFragment в дочернем фрагменте следующим образом:
DialogFragment confirmDialog = new ConfirmDialogFragment();
confirmDialog.show(getFragmentManager(), "ConfirmDialogFragment");
Код фрагмента AlertDialog показан ниже:
package com.example.jbiss.petminder.dialogs;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import androidx.fragment.app.DialogFragment;
import com.example.jbiss.petminder.R;
import java.util.Set;
public class ConfirmDialogFragment extends DialogFragment {
private static final String TAG = "ConfirmDialogFragment";
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Log.d(TAG, "Entered onCreateDialog");
if(savedInstanceState ==null){
Log.d(TAG, "savedInstanceState is null");
}else{
Set<String> s = savedInstanceState.keySet();
Log.d(TAG, "savedInstanceState is: " + s);
}
Log.d(TAG, "getParentFragment is: " + getParentFragment());
Log.d(TAG, "getContext is: " + getContext());
Log.d(TAG, "getActivity is: " + getActivity());
Log.d(TAG, "this is: " + this);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.delete_confirm)
.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Log.d(TAG, "Delete clicked");
Log.d(TAG, "getContext is: " + getContext());
Log.d(TAG, "this is: " + this);
mListener.onDialogPositiveClick(ConfirmDialogFragment.this);
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
Log.d(TAG, "Cancel clicked");
mListener.onDialogNegativeClick(ConfirmDialogFragment.this);
}
});
return builder.create();
}
public interface ConfirmDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
// Use this instance of the interface to deliver action events
ConfirmDialogListener mListener;
// Override the Fragment.onAttach() method to instantiate the ConfirmDialogListener
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.d(TAG, "Entered onAttach");
// Verify that the host activity implements the callback interface
try {
// Instantiate the NoticeDialogListener so we can send events to the host
mListener = (ConfirmDialogListener) context;
Log.d(TAG, "activity is: " + context);
Log.d(TAG, "mListener is: " + mListener);
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(context.toString()
+ " must implement NoticeDialogListener");
}
}
}
Вывод LogCat, показанный в коде, показан ниже.
MedicalInformationFragment: swiped to the 4!
MedicalInformationFragment: position swiped is: 0
ConfirmDialogFragment: Entered onAttach
ConfirmDialogFragment: activity is: com.example.jbiss.petminder.activities.PetInformationActivity@8963dda
ConfirmDialogFragment: mListener is: com.example.jbiss.petminder.activities.PetInformationActivity@8963dda
ConfirmDialogFragment: Entered onCreateDialog
ConfirmDialogFragment: savedInstanceState is null
ConfirmDialogFragment: getParentFragment is: null
ConfirmDialogFragment: getContext is: com.example.jbiss.petminder.activities.PetInformationActivity@8963dda
ConfirmDialogFragment: getActivity is: com.example.jbiss.petminder.activities.PetInformationActivity@8963dda
ConfirmDialogFragment: this is: ConfirmDialogFragment{a4e01a0 #2 ConfirmDialogFragment}
Когда нажата кнопка «Удалить» в ConfirmDialogFragment, LogCat отображает следующее:
ConfirmDialogFragment: Delete clicked
ConfirmDialogFragment: getContext is: com.example.jbiss.petminder.activities.PetInformationActivity@8963dda
ConfirmDialogFragment: this is: com.example.jbiss.petminder.dialogs.ConfirmDialogFragment$2@c3512d0
PetInformationActivity: Entered onDialogPositiveClick
PetInformationViewModel: Entered: deletePetName
Как можно видеть из выходных данных LogCat, ConfirmDialogFragment возвращается к методам интерфейса ConfirmDialogFragment.ConfirmDialogListener вызывающего фрагмента, он переходит к родительской операции Activity.
Это связано с тем, что AlertDialog.Builder
создается с getActivity()
, который получает ссылку на родительскую активность, а не на вызывающий фрагмент. Как видно из вывода LogCat, попытка использовать getContext также ссылается на родительскую активность. Все вопросы об использовании AlertDialog
утверждают, что getActivity следует использовать так, как они, похоже, касаются использования DialogFragment
, а не фрагмента, вызывающего его.
AlertDialog предназначен для использования с фрагмента? Есть ли фрагмент, эквивалентный ссылке на Activity, который можно передать конструктору AlertDialog, как показано ниже?
DialogFragment confirmDialog = new ConfirmDialogFragment(CallingFragmentReferenceSimilarToAnActivity);
confirmDialog.show(getFragmentManager(), "ConfirmDialogFragment");
Я должен быть в состоянии перегрузить конструктор AlertDialog в этом случае, я считаю.