旋转设备后重新打开Android Dialog

时间:2012-01-11 08:05:28

标签: android dialog rotation screen-rotation

我正在编写一个非常简单的应用程序来打开我的自定义共享对话框。 XML布局只包含1个按钮:

<?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"
    android:background="@color/white"
    android:gravity="center_horizontal">

    <Button android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:layout_margin="20dip"
        android:text="Click here to open Share Dialog"
        android:onClick="onBtnShareClick"/>

</LinearLayout>

在Activity上,我创建了一个自定义共享对话框

public class CustomDialog extends Activity {

    private static final int SHOW_DIALOG_SHARE = 1;
    private ArrayAdapter<ShareItem> mShareAdapter;

    @Override
    protected void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        setContentView(R.layout.custom_dialog);

        final ShareItem[] items = {
            //new Item("Menu item", R.drawable.icon_assistance),
            new ShareItem("Banbe", R.drawable.ic_banbe),
            new ShareItem("Facebook", R.drawable.ic_facebook),
            new ShareItem("Twitter", R.drawable.ic_twitter),
            new ShareItem("Gmail", R.drawable.ic_gmail),
            new ShareItem("Other sharing options...", 0)
        };

        mShareAdapter = new ArrayAdapter<ShareItem>(
        this,
        android.R.layout.select_dialog_item,
        android.R.id.text1,
        items){
            public View getView(int position, View convertView, ViewGroup parent) {
                //User super class to create the View
                View v = super.getView(position, convertView, parent);
                TextView tv = (TextView)v.findViewById(android.R.id.text1);

                //Put the image on the TextView
                tv.setCompoundDrawablesWithIntrinsicBounds(items[position].icon, 0, 0, 0);

                //Add margin between image and text (support various screen densities)
                int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
                tv.setCompoundDrawablePadding(dp5);

                return v;
            }
        };
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case SHOW_DIALOG_SHARE:
            return new AlertDialog.Builder(this)
            .setIcon(R.drawable.icon)
            .setTitle(R.string.app_name)
            .setAdapter(mShareAdapter, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int item) {
                    Toast.makeText(CustomDialog.this, "Click on item " + item, Toast.LENGTH_SHORT).show();
                }
            })
            .show();
        }
        return null;
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // TODO Auto-generated method stub
        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onRestoreInstanceState(savedInstanceState);
    }

    public void onBtnShareClick(View v) {
        showDialog(SHOW_DIALOG_SHARE);
    }

    protected class ShareItem {
        public final String text;
        public final int icon;
        public ShareItem(String text, Integer icon) {
            this.text = text;
            this.icon = icon;
        }
        @Override
        public String toString() {
            return text;
        }
    }

}

单击该按钮时,将打开我的共享对话框。一切都好。

现在,我将设备旋转到纵向模式,单击按钮打开对话框。之后,按返回以关闭“共享”对话框。 将设备旋转为横向模式。突然分享对话框重新打开,虽然我没有点击按钮。

当我尝试使用本机共享对话框时,我没有看到此错误。也许自定义共享对话框是原因?

谁能告诉我这里有什么问题?

4 个答案:

答案 0 :(得分:4)

您好您必须在应用程序清单文件中添加屏幕方向支持。

 <activity android:name=".TestApp"
     android:label="@string/app_name"   android:configChanges="orientation">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

并覆盖以下方法,

  public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
  }

答案 1 :(得分:0)

使用create()方法代替show()方法

new AlertDialog.Builder(this).create()

答案 2 :(得分:0)

使用Dialog或AlertDialog无关紧要。为了避免在旋转屏幕时关闭对话框,请使用以下代码:

dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);

答案 3 :(得分:0)

尝试使用将从DialogFragment

扩展的自己的类

例如:

    public class QuestionDialogFragment extends DialogFragment
    {
        public final static String BF_TITLE = "QuestionDialogFragment.BF_TITLE";
        public final static String BF_QUESTION = "QuestionDialogFragment.BF_QUESTION";

        private Callback mCallback;

        public static void init(FragmentManager fragmentManager, String title, String question, Callback callback)
        {
            Bundle bundle = new Bundle();
            bundle.putString(BF_TITLE, title);
            bundle.putString(BF_QUESTION, question);

            QuestionDialogFragment dialog = new QuestionDialogFragment();
            dialog.setCallbackListener(callback);
            dialog.setArguments(bundle);
            dialog.show(fragmentManager, null);
        }

        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);

            setCancelable(false);
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState)
        {
            Bundle bundle = getArguments();

            String title = null;
            String question = null;

            if (bundle != null)
            {
                if (bundle.containsKey(BF_TITLE))
                {
                    title = bundle.getString(BF_TITLE);
                }
                if (bundle.containsKey(BF_QUESTION))
                {
                    question = bundle.getString(BF_QUESTION);
                }
            }

            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
            alertDialogBuilder.setTitle(title);
            alertDialogBuilder.setMessage(question);
            //null should be your on click listener
            alertDialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener()
            {
                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    mCallback.success();
                    dialog.dismiss();
                }
            });
            alertDialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
            {

                @Override
                public void onClick(DialogInterface dialog, int which)
                {
                    mCallback.cancel();
                    dialog.cancel();
                }
            });

            return alertDialogBuilder.create();
        }

        public void setCallbackListener(Callback callback)
        {
            this.mCallback = callback;
        }

        public static interface Callback
        {
            void success();
            void cancel();
        }
}

并在代码中的任何位置使用它:

            QuestionDialogFragment.init(
                getFragmentManager(),
                "Some title",
                "Some question?",
                new QuestionDialogFragment.Callback()
                {
                    @Override
                    public void success()
                    {
                        // @TODO if user choice YES;
                    }

                    @Override
                    public void cancel()
                    {
                        // @TODO if user choice CANCEL;
                    }
                });

如果您想要创建自己的视图而不是标准对话框窗口:

  Dialog onCreateDialog(Bundle savedInstanceState) 

使用

  View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)

例如:

需要创建值/ layout / your_fragment_layout.xml

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
                 android:id="@+id/kom_purchase_dialog_root_view">

        <TextView
            android:id="@+id/kom_purchase_dialog_message_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="some text"/>

        <LinearLayout
            android:layout_gravity="bottom"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <Button
                android:id="@+id/kom_purchase_dialog_negative_button"
                android:layout_alignParentBottom="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:text="Cancel"/>

            <Button
                android:id="@+id/kom_purchase_dialog_positive_button"
                android:layout_toRightOf="@+id/kom_purchase_dialog_negative_button"
                android:layout_alignParentBottom="true"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="wrap_content"
                android:text="Ok"/>
        </LinearLayout>
    </FrameLayout>

并为此布局将自己的类更改为:

public class QuestionDialogFragment2 extends DialogFragment
{

    public final static String BF_TITLE = "QuestionDialogFragment.BF_TITLE";
    public final static String BF_QUESTION = "QuestionDialogFragment.BF_QUESTION";

    private Callback mCallback;

    public static void init(FragmentManager fragmentManager, String title, String question, Callback callback)
    {
        Bundle bundle = new Bundle();
        bundle.putString(BF_TITLE, title);
        bundle.putString(BF_QUESTION, question);

        QuestionDialogFragment2 dialog = new QuestionDialogFragment2();
        dialog.setCallbackListener(callback);
        dialog.setArguments(bundle);
        dialog.show(fragmentManager, null);
    }

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setCancelable(false);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        Bundle bundle = getArguments();

        String title = null;
        String question = null;

        if (bundle != null)
        {
            if (bundle.containsKey(BF_TITLE))
            {
                title = bundle.getString(BF_TITLE);
            }
            if (bundle.containsKey(BF_QUESTION))
            {
                question = bundle.getString(BF_QUESTION);
            }
        }
        View view = super.onCreateView(inflater, container, savedInstanceState);
        if (view == null)
        {
            view = inflater.inflate(R.layout.your_fragment_layout, null, false);
            view.setTag(new Holder(view));
        }
        Holder holder = (Holder) view.getTag();
        holder.messageTextView.setText(question);
        holder.positiveButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mCallback.success();
            }
        });
        holder.negativeButton.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mCallback.cancel();
            }
        });
        return view;
    }

    public void setCallbackListener(Callback callback)
    {
        this.mCallback = callback;
    }

    public static interface Callback
    {
        void success();
        void cancel();
    }

    private final class Holder
    {
        public TextView messageTextView;
        public Button positiveButton;
        public Button negativeButton;

        private Holder(View view)
        {
            messageTextView = (TextView) view.findViewById(R.id.question_dialogfragment_message_textview);
            positiveButton = (Button) view.findViewById(R.id.question_dialogfragment_positive_button);
            negativeButton = (Button) view.findViewById(R.id.question_dialogfragment_negative_button);
        }
    }
}

和相同的用法:

            QuestionDialogFragment2.init(
                getFragmentManager(),
                "Some title",
                "Some question?",
                new QuestionDialogFragment2.Callback()
                {
                    @Override
                    public void success()
                    {
                        // @TODO if user choice YES;
                    }

                    @Override
                    public void cancel()
                    {
                        // @TODO if user choice CANCEL;
                    }
                });

对于这两种方法,无效onSaveInstanceState(Bundle outState)并在旋转后保存状态。我认为这是更好的通用方法,然后使用简单的对话框。