DialogFragment бросает ClassCastException, если вызвано из фрагмента

My DialogFragment бросает ClassCastException, если вызывается из Fragment, в то время как он нормально работает, если вызван из Activity. Я уже рассмотрел несколько других вопросов с аналогичной проблемой, и в основном они связаны с импортом, но я не смог его решить в своей реализации. Вот моя реализация для DialogFragment.

 Import android.app.AlertDialog;
 Import android.app.Dialog;
 Import android.app.DialogFragment;

 Открытый класс HotspotScanDialog расширяет DialogFragment {

     SetupHotspotDialogListener mListener;

     @Override
     Public Dialog onCreateDialog (Bundle savedInstanceState) {
         ...

         .setAdapter (hotspotAdapter, новый DialogInterface.OnClickListener () {
             @Override
             Public void onClick (диалог DialogInterface, int which) {
                 mListener.onHotspotSelectedListener (hotspotAdapter.getItem (
                         который) .ToString ());
             }
         }) ...
     }

     Открытый интерфейс SetupHotspotDialogListener {
         Public void onHotspotSelectedListener (выбор строки);

     }

     @Override
     Public void onAttach (Активность активности) {
         super.onAttach (активность);

         пытаться {
             MListener = (SetupHotspotDialogListener);
         } Catch (исключение ClassCastException) {
             // Просто чтобы убедиться, что кто-нибудь укажет на мой метательный
             // ClassCastException сам я пробовал и без этого кода.
             Throw new ClassCastException (activity.toString ()
                     + "Должен реализовывать функцию УведомлениеDialogListener");
         }
     }
 }

Вот мой фрагмент, который использует вышеописанный DialogFragment:

 Import android.app.AlertDialog;
 Import android.app.DialogFragment;
 Import android.support.v4.app.Fragment;
 Import com.xxx.yyy.ui.compontent.dialog.HotspotScanDialog;
 Import com.xxx.yyy.ui.compontent.dialog.HotspotScanDialog.SetupHotspotDialogListener;

 Открытый класс SmartMode extends Fragment реализует SetupHotspotDialogListener {

     Private void showWifiSelectionDialog () {
         DialogFragment setupWifiSelectionDialog = новый HotspotScanDialog ();

         / *
          * Использование getFragmentManager () только говорит «Метод
          * Show (FragmentManager, String) в типе DialogFragment не
          * Применимо для аргументов (FragmentManager, String) "
          * /

         setupWifiSelectionDialog.show (getActivity (). getFragmentManager (),
                 Keys.TAG.toString ());
     }

     @Override
     Public void onHotspotSelectedListener (выбор строки) {
         // Log.d (TAG, выбор);
     }
 }

Это журнал ошибок:

02-01 13: 11: 32.750: E / AndroidRuntime (15061): FATAL EXCEPTION: main 02-01 13: 11: 32.750: E / AndroidRuntime (15061): java.lang.ClassCastException: com.milanix.tuki.UiMainActivity @ 41d75350 должен реализовать NoticeDialogListener 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at com.xxx.yyy.ui.compontent.dialog.HotspotScanDialog.onAttach (HotspotScanDialog.java:122) 02-01 13:11: 32.750: E / AndroidRuntime (15061): at android.app.FragmentManagerImpl.moveToState (FragmentManager.java:787) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at android.app.FragmentManagerImpl.moveToState (FragmentManager .java: 1035) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at android.app.BackStackRecord.run (BackStackRecord.java:635) 02-01 13: 11: 32.750: E / AndroidRuntime (15061) ): At android.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:1397) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at android.app.FragmentManagerImpl $ 1.run (FragmentManager.java:426) 02 -01 13: 11: 32.750: E / AndroidRuntime (15061): at android.os.Handl Er.handleCallback (Handler.java:615) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at android.os.Handler.dispatchMessage (Handler.java:92) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at android.os.Looper.loop (Looper.java:137) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at android.app.ActivityThread.main (ActivityThread.java : 4898) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at java.lang.reflect.Method.invokeNative (собственный метод) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at Java.lang.reflect.Method.invoke (Method.java:511) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java : 1006) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:773) 02-01 13: 11: 32.750: E / AndroidRuntime (15061): у dalvik.system.NativeStart.main (родной метод)

Мне интересно, может ли кто-нибудь дать намек на эту проблему.

Из документов :

onAttach(Activity) called once the fragment is associated with its activity. 

В вашем коде

  mListener = (SetupHotspotDialogListener) activity; 

Line бросает ClassCastException потому что ваша активность не реализует интерфейс SetupHotspotDialogListener . ( Fragment напрямую связан с активностью, которая содержит его, а также с DialogFragment потому что DialogFragment расширяет Fragment ).

Опять из документов

In some cases, you might need a fragment to share events with the activity. A good way to do that is to define a callback interface inside the fragment and require that the host activity implement it. When the activity receives a callback through the interface, it can share the information with other fragments in the layout as necessary.

Поэтому, если вы хотите создать FragmentDialog из Fragment я предлагаю организовать его через обратные вызовы для активности:

  1. Создайте интерфейс обратного вызова в свой класс SmartMode Fragment (как вы делаете в dialogFragment) с помощью одного метода, например createDialogRequest() .
  2. Пусть ваша деятельность реализует этот интерфейс
  3. Затем, когда вам нужно создать диалог, отправьте обратный вызов из Fragment в действие
  4. Место "показать диалоговые логики" в действие

Похоже, что функция «Профиль фрагмента» создает диалог, диалог показывает активность.

EDITED: Я думаю, что нашел лучшую реализацию того, что вам нужно. Я написал простой пример создания fragment dialog фрагмента из фрагмента с получением событий обратного вызова fragment dialog фрагмента в фрагмент.

Мероприятия:

 public class MyFragmentActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_my_fragment); // first start of activity if (savedInstanceState == null) { // put fragment to activity layout MyFragment fragment = new MyFragment(); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.fragmentContainer, fragment, "fragment"); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); ft.commit(); } }} 

Фрагмент:

 public class MyFragment extends Fragment implements MyDialogInterface { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View fragmentView = inflater.inflate(R.layout.fragment, null); // button which shows dialog Button showDialogButton = (Button) fragmentView.findViewById(R.id.showDialog); showDialogButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // create fragment dialog. FragmentDialog dialog = FragmentDialog.getInstance(MyFragment.this); dialog.show(getActivity().getSupportFragmentManager(), "dialog"); } }); return fragmentView; } @Override public void onClickEvent() { // receive click events from dialog fragment Log.e(getClass().getSimpleName(), "onClickEvent"); } 

}

FragmentDialog:

 public class FragmentDialog extends DialogFragment { public interface MyDialogInterface extends Serializable { public void onClickEvent(); } private MyDialogInterface callbackListener; /** * dialogInterface - instance of MyDialogInterface which will handle * callback events */ public static FragmentDialog getInstance(MyDialogInterface dialogInterface) { FragmentDialog fragmentDialog = new FragmentDialog(); // set fragment arguments Bundle args = new Bundle(); args.putSerializable("dialogInterface", dialogInterface); fragmentDialog.setArguments(args); return fragmentDialog; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setStyle(STYLE_NO_TITLE, 0); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View pushDialogView = getActivity().getLayoutInflater().inflate(R.layout.fragment_dialog, null); // get reference to MyDialogInterface instance from arguments callbackListener = (MyDialogInterface) getArguments().getSerializable("dialogInterface"); Button cancelButton = (Button) pushDialogView.findViewById(R.id.button); cancelButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // send click event callbackListener.onClickEvent(); } }); return pushDialogView; }} 

Я использовал фрагменты библиотеки поддержки 4 ( android.support.v4.app.Fragment , android.support.v4.app.DialogFragment , android.support.v4.app.FragmentActivity ).

И макеты:

activity_my_fragment.xml :

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragmentContainer" android:layout_width="match_parent" android:layout_height="match_parent" /> 

fragment.xml :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#a00" android:orientation="vertical" > <Button android:id="@+id/showDialog" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="show doalog" /> </LinearLayout> 

fragment_dialog.xml :

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fe3" android:orientation="vertical" > <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="click me" /> </LinearLayout> 

Идея состоит в том, чтобы отправить ссылку на интерфейс, который будет захватывать события обратного вызова.

Intereting Posts