如何调用在 Activity 中扩展 DialogFragment 的 class 的成员函数

How to call member function of a class that extend DialogFragment in an Activity

我编写了自定义 DatePickerDialog,它扩展了 DialogFragment 并实现了 DatePickerDialog.OnDateSetListener.

public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {
    DatePickerDialog dpd = new DatePickerDialog(getActivity(),
                R.style.MyDialogTheme, this, year, month, day);
    return dpd;
  }

  public void onDateSet(DatePicker view, int year, int month, int day) {

  }

  // own  methods
  String getFormattedDate() {
  }
}

我在我的 MainActivity 中调用这个片段。

public class Booking_activity extends AppCompatActivity implements View.OnClickListener {

  public void onClick(View view) {
    if (view == imgView_from) {
      // Initialize a new date picker dialog fragment
      DialogFragment dFragment = new DatePickerFragment();
      // Show the date picker dialog fragment
      dFragment.show(getFragmentManager(), "Date Picker");

      // error 
      dFragment.getFormattedDate();
    } 
  } 
}

您需要初始化一个新的日期选择器对话框片段:

DatePickerFragment dFragment = new DatePickerFragment();

就像下面的代码:

public class Booking_activity extends AppCompatActivity implements View.OnClickListener {
  public void onClick(View view) {
    if (view == imgView_from) {

      // Initialize a new date picker dialog fragment
      DatePickerFragment dFragment = new DatePickerFragment(); // Changed this

      // Show the date picker dialog fragment
      dFragment.show(getFragmentManager(), "Date Picker");

      // error 
        dFragment.getFormattedDate();
    } 
  }
}

您可以通过简单地转换对象来调用成员函数,如下所示

((DatePickerDialog)dFragment).getFormattedDate();

将您的函数 getFormattedDate 访问模式设为 public,如下所示

  public String getFormattedDate() {
        }

将解决您的问题。

错误发生是因为您试图从 DialogFragment 访问一个无效的方法。您需要使用以下内容创建 DatePickerFragment:

DatePickerFragment dFragment = new DatePickerFragment();

或铸造它:

DialogFragment dFragment = new DatePickerFragment();
((DatePickerDialog)dFragment).getFormattedDate();

但是主要缺陷是,您尝试在 dFragment 对象之前访问 getFormattedDate() method完成实例化。请记住 show() 是一个异步调用。

所以当 dFragment 完成实例化时,您需要通知 Booking_activity activity。您可以为它使用一个接口。类似于以下内容:

  1. 在你的 DatePickerFragment 中,添加接口:

    public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
    
      private DatePickerListener mListener;
    
      public interface DatePickerListener {
        void onDialogFinishInitialized();
      }
    
      @Override
      public Dialog onCreateDialog(Bundle savedInstanceState) {
        DatePickerDialog dpd = new DatePickerDialog(getActivity(),
                R.style.MyDialogTheme, this, year, month, day);
    
        // you need to inform the activity when Dialog has finish
        // initialized.
        mListener.onDialogFinishInitialized();
    
        return dpd;
      }
    
      ...
    
      // Need to add the activity as the listener.
      @Override 
      public void onAttach(Activity activity) {
        super.onAttach(activity);
        // This makes sure that the container activity has implemented
        // the listener interface. If not, it throws an exception
        try {
          mListener = (DatePickerListener) activity;
        } catch (ClassCastException e) {
          throw new ClassCastException(activity.toString() + " must implement DatePickerListener");
        }
      }
    
      ...
    
    }
    
  2. 在您的 Activity 中实现接口并调用 getFormattedDate() 方法:

    public class Booking_activity extends AppCompatActivity
    implements View.OnClickListener, DatePickerFragment.DatePickerListener {
      ...
      private DatePickerFragment dFragment;
      ...
      @Override
      public void onDialogFinishInitialized() {
        // You can call the method here now
        dFragment.getFormattedDate();
      }
      ...
    }
    

所选解决方案运行良好,但我想指出 onAttach() 函数已被弃用。我在这里找到了一些解决方案:

我认为最受欢迎的答案是:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    activity = getActivity();
}

他们正在将 onAttach(Activity activity) 更改为 onAttach(Context context)。