Fragment to Activity Communications

谁说我不能喝 提交于 2019-12-11 06:17:38

问题


I will come clean immediately by admitting that I don't understand Interfaces. I believe that I followed the process laid out in https://developer.android.com/training/basics/fragments/communicating.html. In section Define an Interface, I declare and define the required interface NewDate:

public class DatePickerFragment extends DialogFragment {
    NewDate mCallback;
    private static final String TAG = "DatePickerFragment";
    public Date date;

    private DatePicker mDatePicker;

    //interface implemented by DatePicker Activity
    public interface NewDate{
        public void UpdateDate(Date date);
    }

I implement it in the calling Activity as discussed in section Implement the Interface:

public class DatePickerActivity extends SingleFragmentActivity implements DatePickerFragment.NewDate {
    private final String TAG = "DatePickerActivity";
    private static final int REQUEST_DATE = 0;

    @Override
    protected Fragment createFragment() {
        Log.d(TAG, "Entered createFragment");
        Intent intent = getIntent();
        Date date = (Date) intent.getSerializableExtra(EXTRA_DATE);
        Log.d(TAG,"date = " + date);
        UUID id = (UUID) intent.getSerializableExtra(EXTRA_ID);
        Log.d(TAG, "crime ID is " + id);
        return DatePickerFragment.newInstance(date);
    }

    public void UpdateDate(Date date) {
        Log.d(TAG, "Entered UpdateDate");
        Log.d(TAG, "Date is " + date);
        Toast.makeText(getApplicationContext(),"Clicked OK to update date!", Toast.LENGTH_SHORT).show();
        return;
    }
}

Ignore the fact that returning date might be wrong, the problem is that the code never makes it here.

As shown the following method in DatePickerFragment is called when the user clicks the OK button to deliver the event to the parent DatePickerActivity and the onAttach method is performed when the DatePickerFragment attaches to DatePickerActivity:

    public class DatePickerFragment extends DialogFragment {

   ...

    private void sendResult(int resultCode, Date date){
        Log.d(TAG, "Entered sendResult");
        Log.d(TAG, "resultCode is " + resultCode);
        Log.d(TAG, "Date passed in to sendResult is " + date);

        if (getTargetFragment() == null) {
            if (mCallback != null){
            mCallback.UpdateDate(date);
            return;
            } else {
                Log.d(TAG, "mCallback is null");
                return;
            }

    ...

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        Log.d(TAG, "Entered onAttach");
        try {
            Log.d(TAG, "Trying to create new mCallback");
            mCallback = (NewDate) date;
            Log.d(TAG, "mCallback is " + mCallback);
        } catch (ClassCastException e){
            throw new ClassCastException(date.toString() + " must implement NewDate");
        }

The following is the LogCat output as a result of the code running after I run the code:

DatePickerActivity: Entered createFragment
DatePickerActivity: date = Mon Oct 23 15:24:38 CDT 2017
DatePickerActivity: crime ID is a205fce6-9a38-4c40-9dce-ba651c281752
DatePickerFragment: Entered newInstance
DatePickerFragment: Date is Mon Oct 23 15:24:38 CDT 2017
DatePickerFragment: id is 16842960
DatePickerFragment: Entered onAttach
DatePickerFragment: Trying to create new mCallback
DatePickerFragment: mCallback is null
DatePickerFragment: Entered onCreateView
DatePickerFragment: Date passed to DatePickerFragment is: Mon Oct 23 15:24:38 CDT 2017
DatePickerFragment: Set date in calendar
DatePickerFragment: year is 2017
DatePickerFragment: month is 9
DatePickerFragment: day is 23
DatePickerFragment: Entered onActivityCreated
DatePickerFragment: Entered onStart
DatePickerFragment: Entered onResume
DatePickerFragment: You clicked OK!
DatePickerFragment: onClick: year is 2017
DatePickerFragment: onClick: month is 9
DatePickerFragment: onClick: day is 31
DatePickerFragment: Dialog date is Tue Oct 31 00:00:00 CDT 2017
DatePickerFragment: Entered sendResult
DatePickerFragment: resultCode is -1
DatePickerFragment: Date passed in to sendResult is Tue Oct 31 00:00:00 CDT 2017
DatePickerFragment: mCallback is null

If you align the code's Log.d messages, you'll note that UpdateDate in DatePickerActivity is never accessed because mCallback is null. I thought that mCallback would not be null after onAttach, but it is still null. I've read other web pages, such as http://simpledeveloper.com/how-to-communicate-between-fragments-and-activities/ and http://techblogon.com/communication-between-activity-and-fragment-example/, that make me think that I've fulfilled the Interface requirements. However, I obviously haven't.

So, can anyone explain either what I missed on those web pages or provide a link to one that explains what I'm missing?


回答1:


You need to assign mCallback to the activity that hosts your fragment and implements the DatePickerFragment.NewDate interface:

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Log.d(TAG, "Entered onAttach");
    try {
        Log.d(TAG, "Trying to create new mCallback");
        //modified:
        if (context instanceof DatePickerActivity){
            mCallback = (DatePickerActivity) context; 
        }
        Log.d(TAG, "mCallback is " + mCallback);
    } catch (ClassCastException e){
        throw new ClassCastException(date.toString() + " must implement NewDate");
    }
}


来源:https://stackoverflow.com/questions/46900069/fragment-to-activity-communications

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!