java - 在 Android 屏幕旋转后,是否有适当的方法来保留带有自定义对象列表的对话框?

标签 java android android-fragments dialog

我想根据我的观点提出一个简单但具有误导性的问题。

我有一个对话框,或者更好的是,一个自定义对话框:

public class MyCustomDialog extends Dialog {

public MyCustomDialog(Context context, int layoutResourceId) {
    super(context);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(layoutResourceId);
    LayoutParams params = getWindow().getAttributes();
    params.width = LayoutParams.MATCH_PARENT;
    getWindow().setAttributes((android.view.WindowManager.LayoutParams) params);
}
}

此对话框在实例化时将 layuoutResourceId (R.layout.some_custom_layout.xml) 作为参数。 我需要使用此对话框来显示动态创建的一些主数据和详细数据的自定义列表。为了进行这种操作,我使用了一个名为 MasterDetailArrayAdapter 的自定义适配器类:

public class MasterDetailArrayAdapter extends ArrayAdapter<Item> {

private LayoutInflater mdInflater;

public enum EntryType {
    DETAIL, MASTER
}

public MasterDetailArrayAdapter(Context context, List<Item> items) {
    super(context, 0, items);
    mdInflater = LayoutInflater.from(context);
}

@Override
public int getViewTypeCount() {
    return EntryType.values().length;
}

@Override 
public int getItemViewType(int position) {
    return getItem(position).getViewType();
}

@Override 
public View getView(int position, View convertView, ViewGroup parent) {
    return getItem(position).getView(mdInflater, convertView);
}

此适配器扩展了 Item 的 ArrayAdapter,其中 Item 是我创建的接口(interface):

 public interface Item {

   public int getViewType();
   public View getView(LayoutInflater inflater, View convertView);
 }

所以MasterDetailArrayAdapter在构造的时候就以一个List作为参数。 Item 接口(interface)由 MasterWithValue 类实现(或更好地由 MasterWithValue 扩展的 Master 类实现):

public class MasterWithValue extends Master {

private String value;
private List<Detail> detailList;

public MasterWithValue(String masterName, String masterValue) {
    super(masterName);
    this.value = masterValue;
    this.detailList = new ArrayList<Detail>();
}

@Override 
public int getViewType() {
    return super.getViewType();
}

@Override
public View getView(LayoutInflater inflater, View convertView) {
    View view;
    if (convertView == null) {
        view = inflater.inflate(R.layout.statistics_rowlist_master, null);
    }
    else {
        view = convertView;
    }

    TextView MasterEntryName = (TextView) view.findViewById(R.id.statistics_master_name);
    TextView MasterEntryValue = (TextView) view.findViewById(R.id.statistics_master_value);

    MasterEntryName.setText(super.name);
    MasterEntryValue.setText(this.value);

    return view;
}

public String getMasterValue() {
    return value;
}

public List<Detail> getDetailList() {
    return this.detailList;
}

public void addDetailToMaster(Detail detail) {
    this.detailList.add(detail);
}

 }

和细节类:

public class Detail implements Item {

public final String detailName;
public final String detailValue;

public Detail(String detailName, String detailValue) {
    this.detailName = detailName;
    this.detailValue = detailValue;
}

@Override
public int getViewType() {
    return EntryType.DETAIL.ordinal();
}

@Override
public View getView(LayoutInflater inflater, View convertView) {
    View view;
    if (convertView == null) {
        view = inflater.inflate(R.layout.institutional_rowlist_detail, null);
    }
    else {
        view = convertView;
    }

    TextView detailEntryName = (TextView) view.findViewById(R.id.institutional_detail_name);
    TextView detailEntryValue = (TextView) view.findViewById(R.id.institutional_detail_value);
    detailEntryName.setText(this.detailName);
    detailEntryValue.setText(this.detailValue);

    return view;
}

}

现在是全部构建的代码:

                      // instantiating a new CustomDialog class
                dialog = new MyCustomDialog(thisContext,  R.layout.institutional_info_custom_list);
                DetailListView = (ListView) dialog.findViewById(R.id.custom_dialog_list);
                final MasterDetailArrayAdapter adapter = new MasterDetailArrayAdapter(ComeHaInvestito.this, MasterAndDetailstatisticsInfoList);         
                DetailListView.setAdapter(adapter);

thisContext是activity的context,MasterAndDetailstatisticsInfoList是Item的a但这不是重点。我的结果是这样的:

enter image description here

一切正常,除非在显示对话框时旋转屏幕:对话框关闭,然后再也不会重新显示。太令人沮丧了,很抱歉这么说,但我整天都在努力弄清楚它,我该如何解决它。

我知道当您旋转设备的屏幕时, Activity 会被销毁并重新创建,但对话框不会。我需要在设备旋转时将其保留在屏幕上,但我不能使用 Manifest 解决方案,因此:

android:configChanges="orientation|keyboardHidden|screenSize

对我不起作用,因为我有一些其他图形 View 以这种方式改变它们在屏幕上的位置旋转。

所以我正在寻找另一种解决方案。我看到 SO 和其他论坛上的每个人几乎每次需要保留有关 android 设备配置更改的一些数据(这包括屏幕方向更改)时都在谈论使用 fragment ,所以我正在考虑这样做,但是有了我的解决方案目前正在使用我不知道如何实现一个 fragment ,该 fragment 将保留我的自定义对话框而不会弄乱我已经编写的代码。 伙计们,我真的需要一些帮助。

有没有办法使用 Fragments 集成自定义对话框类(在我的例子中是 MyCustomDialog)并使其在屏幕方向更改时保留?

感谢关注!希望得到一些帮助!

编辑:我创建了一个名为 ActivityToFragmentInteraction 的接口(interface)。现在有了这个实现,我可以看到屏幕方向发生变化的对话框,但其中的 ListView 仍然消失。我该如何解决?

公共(public)类 MyCustomDialogFragmentWithListItem 扩展 DialogFragment {

private List<Item> dialogFragmentItemList;
private Context context;

private ActivityToFragmentInteraction activityToFragmentInteraction;

public interface ActivityToFragmentInteraction {
    public List<Item> getListItem();
}

public static MyCustomDialogFragmentWithListItem newInstance(int dialogLayoutResourceId, int dialogListViewResourceId) {
    MyCustomDialogFragmentWithListItem dialogFragment = new MyCustomDialogFragmentWithListItem();
    Bundle args = new Bundle();
    args.putInt("dialog_layout", dialogLayoutResourceId);
    args.putInt("dialog_list_view_id", dialogListViewResourceId);
    dialogFragment.setArguments(args);
    return dialogFragment;
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    this.context = getActivity();

    try {
        activityToFragmentInteraction = (ActivityToFragmentInteraction) activity; 
    } 
    catch (ClassCastException e) {
        e.printStackTrace();
    }
}

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) {
    int dialogLayoutResourceId = getArguments().getInt("dialog_layout");
    int dialogListViewResourceId = getArguments().getInt("dialog_list_view_id");
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

    // getting the layout inflater and inflating the view recovered using the dialogLayoutResourceId
    // passed before as argument to the factory method.
    LayoutInflater inflater = getActivity().getLayoutInflater();
    View view = inflater.inflate(dialogLayoutResourceId, null);
    builder.setView(view);

    // getting the List<Item> from the activityToFragmentInteraction interface
    dialogFragmentItemList = activityToFragmentInteraction.getListItem();

    // recovering the ListView of the DialogFragment
    ListView listView = (ListView) view.findViewById(dialogListViewResourceId);
    // setting the adapter for the ListView of the DialogFragment.
    final MasterDetailArrayAdapter adapter = new MasterDetailArrayAdapter(context, dialogFragmentItemList);
    listView.setAdapter(adapter);

    return builder.create();
}

}

最佳答案

您可以使用 DialogFragment .您需要更改的是您的 MyCustomDialog.class 以扩展 DialogFragment,并且创建 ListView 和适配器的责任也将属于您的对话框。

类似这样(我的例子比较简单,但我认为会有助于理解)。

protected void showMyCustomDialog(){
    MyCustomDialog newFragment = new MyCustomDialog();
    newFragment.show(getFragmentManager());
}

protected class MyCustomDialog extends DialogFragment {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        // Inflate and set the layout for the dialog
        // Pass null as the parent view because its going in the dialog layout
        View view = inflater.inflate(R.layout.my_layout, null);
        // now you customize your view!
        //...
        builder.setView(view);
        return builder.create();
    }
}

关于java - 在 Android 屏幕旋转后,是否有适当的方法来保留带有自定义对象列表的对话框?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22541986/

相关文章:

android - 如何在 xml 中添加 TODO 注释?

android - 防止同一 fragment 多次堆叠 (addToBackStack)

android - 旋转后, fragment 事务给出 IllegalStateException

JAVA如何一步步用JOOQ构建sql查询

java - IntelliJ/Maven 不更新来自 Artifactory 的 Artifact

java - Excel中的数据验证字段

java - 使用jsp导入excel数据存入数据库

android - Android Library Project Jar + IntelliJ IDEA 11

android - 如何在 Fragments 中添加一个按钮

android - Fragment 超出屏幕