gpt4 book ai didi

android - 如果从 fragment 调用 DialogFragment 抛出 ClassCastException

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:21:50 25 4
gpt4 key购买 nike

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

import android.app.AlertDialog;import android.app.Dialog;import android.app.DialogFragment;public class HotspotScanDialog extends DialogFragment {    SetupHotspotDialogListener mListener;    @Override    public Dialog onCreateDialog(Bundle savedInstanceState) {        ...        .setAdapter(hotspotAdapter, new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                mListener.onHotspotSelectedListener(hotspotAdapter.getItem(                        which).toString());            }        })...    }    public interface SetupHotspotDialogListener {        public void onHotspotSelectedListener(String selection);    }    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);        try {            mListener = (SetupHotspotDialogListener) activity;        } catch (ClassCastException ignore) {            // Just to make sure if anyone will be pointing at my throwing            // ClassCastException myself I have tried without this code as well.            throw new ClassCastException(activity.toString()                    + " must implement NoticeDialogListener");        }    }}

这是我使用上述 DialogFragment 的 fragment :

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;public class SmartMode extends Fragment implements SetupHotspotDialogListener {    private void showWifiSelectionDialog() {        DialogFragment setupWifiSelectionDialog = new HotspotScanDialog();        /*         * using getFragmentManager() only says "The method         * show(FragmentManager, String) in the type DialogFragment is not         * applicable for the arguments (FragmentManager, String)"         */        setupWifiSelectionDialog.show(getActivity().getFragmentManager(),                Keys.TAG.toString());    }    @Override    public void onHotspotSelectedListener(String selection) {        // Log.d(TAG,selection);    }}

这是错误日志:

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 must implement 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.Handler.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(Native Method) 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): at dalvik.system.NativeStart.main(Native Method)

我想知道是否有人可以就此问题给出提示。

最佳答案

来自 docs :

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

在你的代码中

 mListener = (SetupHotspotDialogListener) activity;

行抛出 ClassCastException 因为您的 Activity 没有实现 SetupHotspotDialogListener 接口(interface)。 (Fragment 直接绑定(bind)到包含它的 Activity ,DialogFragment 也是如此,因为 DialogFragment 扩展了 Fragment)。

再次来自 docs

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

因此,如果您想从 Fragment 创建 FragmentDialog,我建议通过对 Activity 的回调来组织它:

  1. 使用 createDialogRequest() 等方法在 SmartMode Fragment 类中创建回调接口(interface)(就像在 dialogFragment 中所做的那样)。
  2. 让您的 Activity 实现该接口(interface)
  3. 然后,当您需要创建对话框时,将回调从Fragment 发送到Activity
  4. 将“显示对话框逻辑”放入Activity

它看起来像 fragment 要求 Activity 创建对话框, Activity 显示对话框。

编辑:我想我已经找到了更好地实现你所需要的东西。我写了一个简单的例子,从 fragment 中创建 fragment 对话框,并将 fragment 对话框 回调事件接收到 fragment 中。

Activity :

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

}

fragment :

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

}

fragment 对话框:

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个库 fragment

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>

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

关于android - 如果从 fragment 调用 DialogFragment 抛出 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14640397/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com