1

AlertDialogwithDialogFragment将在设备旋转后恢复任何数据(文本视图中的编辑文本,单选中的选定元素)。并且不会在多选模式下恢复选中的项目。准确地说 - 它会记住启动的字段false并始终重置启动的字段true(旋转后重置为真)。

这很奇怪,我做错了什么?我希望它恢复所有数据(尤其是当所有视图由对话框本身管理时)。

UPD 1:我实际上理解,我可以在对话框中跟踪任何用户与 UI 的交互,并将其保存在包中的对话框/片段实例之间,甚至是静态变量。但它已经设法自己保存了我的自定义布局的状态(edittext+checkbox)和单项选择并且只有 multichoice对类似代码的行为是错误的。这就是我想了解的。

下面的工作演示。在 Nexus 5 / Android 4.4.2 上测试

仅实现一种方法的活动

    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

好的。通过以下代码修改,我可以实现所需的行为(初始化一次并在每次旋转时普遍重新创建,获得正按钮 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>

那是半答案,因为我仍然不知道android在状态自动保存setSingleChoiceItems和状态自动保存之间有什么区别。setMultiChoiceItems

于 2013-12-29T12:44:08.693 回答