7

如果从 Fragment 调用,我的 DialogFragment 会抛出ClassCastException,而如果从 Activity 调用它会正常工作。我已经看过其他几个有类似问题的问题,基本上这些问题与导入有关,但我无法在我的实现中解决它。这是我对 DialogFragment 的实现。

导入 android.app.AlertDialog;
导入android.app.Dialog;
导入android.app.DialogFragment;

公共类 HotspotScanDialog 扩展 DialogFragment {

    SetupHotspotDialogListener mListener;

    @覆盖
    公共对话 onCreateDialog(Bundle savedInstanceState) {
        ...

        .setAdapter(hotspotAdapter, new DialogInterface.OnClickListener() {
            @覆盖
            public void onClick(DialogInterface dialog, int which) {
                mListener.onHotspotSelectedListener(hotspotAdapter.getItem(
                        其中).toString());
            }
        })...
    }

    公共接口 SetupHotspotDialogListener {
        公共无效 onHotspotSelectedListener(字符串选择);

    }

    @覆盖
    公共无效 onAttach(活动活动){
        super.onAttach(活动);

        尝试 {
            mListener = (SetupHotspotDialogListener) 活动;
        } 捕捉(ClassCastException 忽略){
            // 只是为了确定是否有人会指着我的投掷
            // ClassCastException 我自己也试过没有这个代码。
            抛出新的 ClassCastException(activity.toString()
                    + "必须实现NoticeDialogListener");
        }
    }
}

这是我使用上述 DialogFragment 的片段:

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

公共类 SmartMode 扩展片段实现 SetupHotspotDialogListener {

    私人无效showWifiSelectionDialog(){
        DialogFragment setupWifiSelectionDialog = new HotspotScanDialog();

        /*
         * 使用 getFragmentManager() 只会说“方法
         * DialogFragment 类型中的 show(FragmentManager, String) 不是
         * 适用于参数 (FragmentManager, String)"
         */

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

    @覆盖
    公共无效 onHotspotSelectedListener(字符串选择){
        // Log.d(TAG,selection);
    }
}

这是错误日志:

02-01 13:11:32.750:E/AndroidRuntime(15061):致命异常:主要 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): 在 android.app.FragmentManagerImpl.moveToState(FragmentManager.java:787) 02-01 13:11:32.750: E/AndroidRuntime(15061): 在 android.app.FragmentManagerImpl.moveToState(FragmentManager .java:1035) 02-01 13:11:32.750: E/AndroidRuntime(15061): 在 android.app.BackStackRecord.run(BackStackRecord.java:635) 02-01 13:11:32.750: E/AndroidRuntime(15061 ): 在 android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1397) 02-01 13:11:32.750: E/AndroidRuntime(15061): 在 android.app.FragmentManagerImpl$1.run(FragmentManager.java:426) 02-01 13:11:32.750: E/AndroidRuntime(15061):在 android.os.Handler.handleCallback(Handler.java:615) 02-01 13:11:32.750: E/AndroidRuntime(15061): 在 android.os.Handler.dispatchMessage(Handler.java:92) 02-01 13 :11:32.750: E/AndroidRuntime(15061): 在 android.os.Looper.loop(Looper.java:137) 02-01 13:11:32.750: E/AndroidRuntime(15061): 在 android.app.ActivityThread。 main(ActivityThread.java:4898) 02-01 13:11:32.750: E/AndroidRuntime(15061): at java.lang.reflect.Method.invokeNative(Native Method) 02-01 13:11:32.750: E/AndroidRuntime (15061): 在 java.lang.reflect.Method.invoke(Method.java:511) 02-01 13:11:32.750: E/AndroidRuntime(15061): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller。运行(ZygoteInit.java:1006)02-01 13:11:32.750:E/AndroidRuntime(15061):在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)02-01 13:11: 32.750:E/AndroidRuntime(15061):在 dalvik.system.NativeStart.main(本机方法)

我想知道是否有人可以暗示这个问题。

4

1 回答 1

12

来自文档

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

在您的代码中

 mListener = (SetupHotspotDialogListener) activity;

行抛出ClassCastException,因为您的活动没有实现SetupHotspotDialogListener接口。(Fragment与包含它的活动直接相关,并且DialogFragment因为DialogFragmentextends Fragment)。

再次来自文档

在某些情况下,您可能需要一个片段来与活动共享事件。一个好的方法是在片段内定义一个回调接口并要求宿主活动实现它。当Activity通过接口接收到回调时,它可以根据需要与布局中的其他片段共享信息。

因此,如果您想从中创建FragmentDialogFragment我建议通过对活动的回调来组织它:

  1. 使用SmartMode Fragment一种方法(如createDialogRequest().
  2. 让您的活动实现该接口
  3. 然后,当您需要创建对话框时,将回调发送FragmentActivity
  4. 将“显示对话逻辑”放入Activity

它看起来像片段要求活动创建对话框,活动显示对话框。

编辑:我想我已经找到了更好的实现你需要的东西。我写了一个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");
    }

}

片段对话框:

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>

这个想法是发送对将捕获回调事件的接口的引用。

于 2013-02-01T08:17:52.433 回答