从Fragment调用时可以使AlertDialog工作吗?

问题描述 投票:0回答:1

我有一个AlertDialogActivites工作正常,但由于AlertDialog.Builder(getActivity)它不适用于Fragments。在这种情况下,父Activity包含一个使用Fragment显示记录的子RecyclerView。当用户滑动记录时,会显示AlertDialog以确认删除。但是,这不起作用,因为AlertDialog引用了父Activity。我已经在下面的AlertFragment代码中包含了AlertDialog的代码和LogCat输出。

我在子Fragment中实例化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的Delete时,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确实返回到调用Fragment Confirm DialogFragment.ConfirmDialog Listener Interface方法,它转到父Activity的。

这是因为AlertDialog.BuildergetActivity()实例化,它获得了父Activity的引用,而不是调用Fragment的引用。从LogCat输出中可以看出,尝试使用getContext也引用了父Activity。所有关于使用AlertDialog的问题都表明使用getActivity,因为它们似乎是关于使用DialogFragment,而不是关于片段调用它。

AlertDialog是否打算从片段中使用?是否有一个Fragment等同于Activity的引用,可以传递给AlertDialog的构造函数,如下所示?

DialogFragment confirmDialog =  new ConfirmDialogFragment(CallingFragmentReferenceSimilarToAnActivity);
confirmDialog.show(getFragmentManager(), "ConfirmDialogFragment");

在这种情况下,我应该能够重载AlertDialog的构造函数,我相信。

android android-alertdialog android-dialogfragment
1个回答
1
投票

这是因为AlertDialog.Builder是用getActivity()实例化的,它获取父Activity的引用,而不是调用Fragment的引用。

问题不在于AlertDialog,而在于你的听众是如何设置的。由于FragmentgetContext()方法返回父亲Activity的上下文。

mListener = (ConfirmDialogListener) context;

此行将您的侦听器设置为调用Activity的父Fragment。不必将mListener设置为父活动,而是必须将其设置为调用片段。

首先,您必须在实例化时为DialogFragment设置目标片段。

DialogFragment confirmDialog =  new ConfirmDialogFragment();
confirmDialog.setTargetFragment(this, "CONFIRM_DIALOG_TAG");
if (getFragmentManager() != null) {
  confirmDialog.show(getFragmentManager(), "ConfirmDialogFragment");
}

现在,在对话框片段的onCreate中,您可以将回调设置为您的片段。

try {
  mListener = (ConfirmDialogListener) getTargetFragment();
} catch (ClassCastException e) {
  throw new ClassCastException(context.toString()
                + " must implement ConfirmDialogListener");
}

并从onAttach方法中删除代码。

© www.soinside.com 2019 - 2024. All rights reserved.