1

AlertDialogwithDialogFragmentは、デバイスの回転後にデータ (テキスト ビューで編集されたテキスト、単一選択で選択された要素) を復元します。また、マルチチョイス モードでチェックされたアイテムは復元されません。正確に言うと、 で開始されたフィールドを記憶しfalse、常に で開始されたフィールドをリセットしますtrue(回転後に true にリセットされます)。

それは非常に奇妙です、私は何を間違っていますか? すべてのデータを復元したい (特に、すべてのビューがダイアログ自体によって管理されている場合)。

UPD 1 : ダイアログ内の UI とのユーザー インタラクションを追跡し、バンドルまたは静的変数のダイアログ/フラグメント インスタンス間で保存できることを実際に理解しています。しかし、それはすでにカスタムレイアウトの状態(編集テキスト+チェックボックス)と単一選択の選択を単独で保存することに成功しています。そして、同様のコードで間違った動作をするのはマルチチョイスだけです。それが私が理解したいことです。

以下の動作デモ。Nexus 5 / Android 4.4.2 でテスト済み

メソッドを 1 つだけ実装したアクティビティ

    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Button single  = (Button) findViewById(R.id.single);
    single.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            df_single newDialog = new df_single();
            newDialog.show(MyActivity.this.getFragmentManager(), "dialog");
        }
    });
    Button multi  = (Button) findViewById(R.id.multi);
    multi.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            df_multi newDialog = new df_multi();
            newDialog.show(MyActivity.this.getFragmentManager(), "dialog");
        }
    });
}

レイアウトです

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent">
<Button android:id="@+id/single" android:layout_width="200dp" android:layout_height="wrap_content" android:text="list single"/>
<Button android:id="@+id/multi" android:layout_width="200dp" android:layout_height="wrap_content" android:text="list multi"/>

単一選択のDialogFragment

public class df_single extends DialogFragment {
public df_single() {    }

public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle("Single");
    String[] items = new String[]{"1", "2", "3", "4", "5"};
    builder.setSingleChoiceItems(items, 1, null);
    return builder.create();
}
}

複数選択のDialogFragment

public class df_multi extends DialogFragment {
public df_multi() {    }

public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle("Multi");
    String[] items = new String[]{"1", "2", "3", "4", "5"};
    boolean[] checked = new boolean[]{true, false, true, false, true};
    builder.setMultiChoiceItems(items, checked, null);
    Dialog answer = builder.create();
    return answer;
}
}
4

2 に答える 2

1

onSaveInstanceState メソッドを使用して選択した要素を永続化し、選択した要素の位置を復元できます。

public class df_single extends DialogFragment {
    public df_single() {    }
    public static final int DEFAULT_ELEMENT_POSITION;
    int selectedElement;

    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle("Single");
        selectedElement = savedInstanceState.getInt("selectedElement", DEFAULT_ELEMENT_POSITION);
        String[] items = new String[]{"1", "2", "3", "4", "5"};
        builder.setSingleChoiceItems(items, selectedElement, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        selectedElement = which;
                    }
                });
        return builder.create();
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {            
        savedInstanceState.putInt("selectedElement", selectedElement);
        super.onSaveInstanceState(savedInstanceState);
    }

}

于 2013-12-28T20:20:59.780 に答える
1

Ok。次のコード変更を使用して、目的の動作を実現できます (一度初期化して各ローテーションで普遍的に再作成し、肯定的なボタン clickListener で結果を取得し、自分で状態を保持しません)。

public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle("Multi");

    final String[] items = new String[]{"1", "2", "3", "4", "5"};
    boolean[] checked = new boolean[]{true, false, true, false, true};

    LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View listRoot = inflater.inflate(R.layout.list, null);
    builder.setView(listRoot);

    final ListView list = (ListView)listRoot.findViewById(R.id.list);
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_multichoice, android.R.id.text1, items);

    list.setAdapter(adapter);
    list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    for (int i = 0; i < checked.length; i++)
        list.setItemChecked(i, checked[i]);

    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialogInterface, int which) {
            View view = ((AlertDialog) dialogInterface).findViewById(R.id.list);
            assert view != null;
            assert view instanceof ListView;
            SparseBooleanArray checked = ((ListView) view).getCheckedItemPositions();
            for (int i = 0; i < items.length; i++)
                Log.d("checked", checked.get(i)?"YES":"NO");
        }
    });

    return builder.create();
}

どこlist.xmlがちょうど

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">
    <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"/>
</LinearLayout>

それは半答えです。状態の自動保存のコンテキストsetSingleChoiceItemsとの間のアンドロイドの違いはまだわからないからです。setMultiChoiceItems

于 2013-12-29T12:44:08.693 に答える