Android FragmentDialog的状态和设备轮换

时间:2013-12-28 19:48:26

标签: android alertdialog dialogfragment

带有AlertDialog

DialogFragment将在设备轮换后恢复任何数据(文本视图中的已编辑文本,单选中选择的元素)。并且不会以多重模式恢复已检查的项目。准确一点 - 它会记住使用false启动的字段,并始终重置以true启动的字段(旋转后重置为true)。

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

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

下面的工作演示。 在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 for single choice

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 for multi choice

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

2 个答案:

答案 0 :(得分:0)

您可以使用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);
    }

}

答案 1 :(得分:0)

确定。我可以通过以下代码修改实现所需的行为(init一次并在每次旋转时普遍重新创建,获得正按钮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 bewtween setSingleChoiceItemssetMultiChoiceItems有什么区别。