在片段内添加日期选择器片段

时间:2017-12-10 15:19:27

标签: android android-fragments

我正在尝试在片段内创建日期选择器对话框。

主要片段:

public class DataFragment extends Fragment implements 
DatePickerDialog.OnDateSetListener
{
private Button addNew;

@Override
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

    String date = String.format("%02d", dayOfMonth) + "/" + String.format("%02d", monthOfYear + 1) + "/" + String.format("%02d", year);
    Log.d("DTAG", "date: "+date);
    }
}

 @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
{
    View RootView = inflater.inflate(R.layout.fragment_data, container, false);
    addNew = RootView.findViewById(R.id.button_add);

    addNew.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            showDatePickerDialog(view);
        }
    });

    return RootView;
}

public void showDatePickerDialog(View v) 
{
    DialogFragment newFragment = new DatePickerFragment();
    newFragment.show(getFragmentManager(), "datePicker");

}

}

DatePickerFragment:

public class DatePickerFragment extends DialogFragment {

private DatePickerDialog.OnDateSetListener mListener;
private Context context;

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    this.context = context;

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

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {

    final Calendar c = Calendar.getInstance();
    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);

    // Create a new instance of DatePickerDialog and return it
   return new DatePickerDialog(context, mListener, year, month, day);
}

}

但我得到一个例外:

FATAL EXCEPTION: main
 Process: michlind.com.workcalendar, PID: 4951
 java.lang.ClassCastException: michlind.com.workcalendar.views.MainActivity@a20fbb7 must implement OnDateSetListener
     at michlind.com.workcalendar.views.DatePickerFragment.onAttach(DatePickerFragment.java:29)
     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1220)
     at android.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2415)
     at android.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2194)
     at android.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2148)
     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2049)
     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:718)
     at android.os.Handler.handleCallback(Handler.java:789)
     at android.os.Handler.dispatchMessage(Handler.java:98)
     at android.os.Looper.loop(Looper.java:164)
     at android.app.ActivityThread.main(ActivityThread.java:6541)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

1 个答案:

答案 0 :(得分:2)

您正尝试通过mListener将数据从一个片段传递到另一个片段,但context代表您的活动

因此第二个片段onAttach中的错误

  

michlind.com.workcalendar.views.MainActivity@a20fbb7必须实施   OnDateSetListener

因为您的MainActivity未实施OnDateSetListener

解决方案:您需要implement callback mechanism其中

DialogFragment - >使用接口回调

将日期发送到MainActivity

MainActivity - >使用参数作为日期

调用它的函数,使用片段的实例将数据发送到片段1

<强> DatePickerFragment

  • 创建界面(将由活动实施)并在onAttach
  • 中初始化界面
  • 通过回调将日期值发送到mainactivity

public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener{

    private DatePickerFragment.OnDateReceiveCallBack mListener;
    private Context context;

    public interface OnDateReceiveCallBack {
        public void onDateReceive(int dd ,int mm, int yy);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        this.context = context;

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

    @Override
    public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
        mListener.onDateReceive(dayOfMonth,monthOfYear,year);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of DatePickerDialog and return it
       return new DatePickerDialog(context, this, year, month, day);
    }

}

<强> MainActivity

  • 实施接口回调
  • 使用函数
  • 将数据传递给dataFragmentObject

public class MainActivity ....implements DatePickerFragment.OnDateReceiveCallBack{

    // implement callback
    public void onDateReceive(int dd ,int mm, int yy){
        dataFragmentObject.displaydate(dd,mm,yy);
    }

}

<强> DataFragment

  • 创建接收数据并使用它的方法

public class DataFragment extends Fragment 
{
    private Button addNew;

    public void displaydate(int year, int monthOfYear, int dayOfMonth) {

        String date = String.format("%02d", dayOfMonth) + "/" + String.format("%02d", monthOfYear + 1) + "/" + String.format("%02d", year);
        Log.d("DTAG", "date: "+date);
        }
    }

    //..code oncreateview

    public void showDatePickerDialog(View v) 
    {
        DialogFragment newFragment = new DatePickerFragment();
        newFragment.show(getFragmentManager(), "datePicker");

    }

}