Class Cast Exception 从子片段中检索选择的日期以显示在父片段中

Class Cast Exception retrieving Chosen date from childfragment to show in parent fragment

我有一个名为 Planningparentfragment,我想在其中显示一个名为 DatePickerfragmentDialogFragmentDatePickerFragment 有一个 button 单击时,将为用户显示 datepicker。用户选择一个日期,该日期应传递给名为 'date'.

的文本视图中的 Parent Fragment

不幸的是,每次我点击 button 应用程序都会崩溃并出现以下错误:

java.lang.ClassCastException: com.example.android.meat_timealpha10.Activities.MainActivity cannot be cast to android.app.DatePickerDialog$OnDateSetListener
    at com.example.android.meat_timealpha10.Fragments.DatePickerFragment.onCreateDialog(DatePickerFragment.java:29)

我知道错误在哪里,但我不知道如何解决。 它指的是 DatePickerDialogFragment:

中的这一行
return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener)getActivity(), year, month, day );

问题是我关注了一个 youtube 视频,那个人似乎没有任何问题。再说一次,他不像我一样使用 nested fragments 。 有谁知道如何修复该错误以便所选日期显示在 textview?

这是我的代码:

XML,共 parent fragment

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Fragments.planning">


    <Button
        android:id="@+id/chooseDate"
        style="@style/Widget.AppCompat.Button.Borderless.Colored"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginBottom="5dp"
        android:elevation="0dp"
        android:hint="touch here to select date"

        android:textSize="20sp" />

    <TextView
        android:id="@+id/date"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:textColor="@color/blue" />
</LinearLayout>

以下是Child Fragment DatePickerFragment

package com.example.android.meat_timealpha10.Fragments;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.widget.DatePicker;
import android.widget.TextView;

import com.example.android.meat_timealpha10.R;

import org.w3c.dom.Text;

import java.text.DateFormat;
import java.util.Calendar;

public class DatePickerFragment extends DialogFragment {

    public String dateHolder;
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);
        return new DatePickerDialog(getActivity(), (DatePickerDialog.OnDateSetListener)getActivity(), year, month, day );
    }   

}

parent fragment 的代码(没有导入)

public class planning extends Fragment implements DatePickerDialog.OnDateSetListener{
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    public planning() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment planning.
     */
    // TODO: Rename and change types and number of parameters
    public static planning newInstance(String param1, String param2) {
        planning fragment = new planning();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }



    }



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_planning,
                container, false);
        final Button chooseDate = (Button)view.findViewById(R.id.chooseDate);




        chooseDate.setOnClickListener(new View.OnClickListener() {
                                      @Override
                                      public void onClick(View v) {

                                        DialogFragment datePicker = new DatePickerFragment();
                                        datePicker.show(getChildFragmentManager(), "date picker");

                                      }
                                      });

        return view;
    }

    @Override
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month);
        c.set(Calendar.DAY_OF_MONTH, day);
        String currentDateString = DateFormat.getDateInstance(DateFormat.FULL).format(c.getTime());
        TextView date = (TextView)view.findViewById(R.id.date);
        date.setText(currentDateString);

    }


    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

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

    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}

我在这方面还很陌生,所以在回答我的问题时请尽量让它足够容易理解。 在此先感谢大家!

正如它所建议的那样,你不能将activity转换为监听器,错误出现在这一行:(DatePickerDialog.OnDateSetListener)getActivity().

您需要在片段中实现 DatePickerDialog.OnDateSetListener 并覆盖 onDateSet 函数:

public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {

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

@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
    ...        
}}