片段到活动通信

时间:2017-10-23 23:44:11

标签: java android android-fragments android-activity interface

我承认自己并不了解界面,我会马上来。我相信我遵循https://developer.android.com/training/basics/fragments/communicating.html中规定的流程。在Define a 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);
    }

我在调用Activity中实现它,如实现接口:

部分所述
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;
    }
}

忽略返回日期可能有误的事实,问题是代码永远不会在这里。

如图所示,当用户单击“确定”按钮将事件传递给父DatePickerActivity并且DatePickerFragment附加到DatePickerActivity时执行onAttach方法时,将调用DatePickerFragment中的以下方法:

    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");
        }

以下是运行代码后代码运行的LogCat输出:

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

如果您对齐代码的Log.d消息,您将注意到从未访问DatePickerActivity中的UpdateDate,因为mCallback为null。我认为在onAttach之后mCallback不会为null,但它仍然是null。我已经阅读了其他网页,例如http://simpledeveloper.com/how-to-communicate-between-fragments-and-activities/http://techblogon.com/communication-between-activity-and-fragment-example/,这让我觉得我已经满足了界面要求。但是,我显然没有。

那么,任何人都可以解释我在这些网页上遗漏的内容,或者提供一个解释我错过的内容的链接吗?

1 个答案:

答案 0 :(得分:0)

您需要将mCallback分配给托管您的片段的活动,并实现DatePickerFragment.NewDate界面:

@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");
    }
}