7

DialogFragmentは、Fragmentから呼び出された場合はClassCastExceptionをスローしますが、Activityから呼び出された場合は正常に機能しています。同様の問題を抱えている他のいくつかの質問をすでに見てきましたが、基本的にそれらはインポートに関連していますが、私の実装ではそれを解決できませんでした。これがDialogFragmentの私の実装です。

android.app.AlertDialogをインポートします;
android.app.Dialogをインポートします。
import android.app.DialogFragment;

パブリッククラスHotspotScanDialogはDialogFragmentを拡張します{

    SetupHotspotDialogListener mListener;

    @オーバーライド
    public Dialog onCreateDialog(Bundle savedInstanceState){
        ..。

        .setAdapter(hotspotAdapter、new DialogInterface.OnClickListener(){
            @オーバーライド
            public void onClick(DialogInterface dialog、int which){
                mListener.onHotspotSelectedListener(hotspotAdapter.getItem(
                        which).toString());
            }
        })..。
    }

    パブリックインターフェイスSetupHotspotDialogListener{
        public void onHotspotSelectedListener(String selection);

    }

    @オーバーライド
    public void onAttach(Activity activity){
        super.onAttach(activity);

        試す {
            mListener =(SetupHotspotDialogListener)アクティビティ;
        } catch(ClassCastExceptionignore){
            //誰かが私の投げを指しているかどうかを確認するためだけに
            //ClassCastException私もこのコードなしで試しました。
            新しいClassCastException(activity.toString()をスローします
                    + "NoticeDialogListenerを実装する必要があります");
        }
    }
}

上記のDialogFragmentを使用している私のフラグメントは次のとおりです。

android.app.AlertDialogをインポートします;
import android.app.DialogFragment;
import android.support.v4.app.Fragment;
インポートcom.xxx.yyy.ui.compontent.dialog.HotspotScanDialog;
インポートcom.xxx.yyy.ui.compontent.dialog.HotspotScanDialog.SetupHotspotDialogListener;

パブリッククラスSmartModeextendsFragmentはSetupHotspotDialogListenerを実装します{

    private void showWifiSelectionDialog(){
        DialogFragment setupWifiSelectionDialog = new HotspotScanDialog();

        / *
         * getFragmentManager()を使用すると、「メソッド
         * DialogFragment型のshow(FragmentManager、String)は
         *引数(FragmentManager、String)に適用可能」
         * /

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

    @オーバーライド
    public void onHotspotSelectedListener(String selection){
        // 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はNoticeDialogListener02-0113:11:32.750を実装する必要があります:E / AndroidRuntime(15061):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): 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):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で。run(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は、それを含むアクティビティに直接結び付けられているだけでなく、DialogFragmentextendsDialogFragmentもありますFragment)。

再びドキュメントから

場合によっては、イベントをアクティビティと共有するためにフラグメントが必要になることがあります。これを行う良い方法は、フラグメント内にコールバック インターフェイスを定義し、ホスト アクティビティがそれを実装することを要求することです。アクティビティがインターフェイスを介してコールバックを受信すると、必要に応じてレイアウト内の他のフラグメントと情報を共有できます。

したがって、から作成する場合は、アクティビティへのコールバックを介して整理することをお勧めしますFragmentDialogFragment

  1. . _ SmartMode Fragment_createDialogRequest()
  2. アクティビティにそのインターフェースを実装させます
  3. 次に、ダイアログを作成する必要があるときに、コールバックを からFragmentに送信しますActivity
  4. 「ダイアログロジックを表示」を配置しますActivity

ダイアログを作成するフラグメントの ask アクティビティのように見えます。アクティビティはダイアログを表示します。

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

}

フラグメントダイアログ:

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 に答える