Frage

Ich schreibe eine sehr einfache Anwendung, um mein benutzerdefiniertes Freigabedialog zu öffnen. Das XML -Layout enthält nur 1 Taste:

<?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>

Und bei Aktivität erstelle ich ein benutzerdefiniertes Freigabendialog

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

}

Wenn Sie auf die Schaltfläche klicken, wird mein Freigabendialog geöffnet. Alles gut.

Jetzt drehe ich das Gerät in den Porträtmodus und klicke auf die Schaltfläche, um den Dialogfeld zu öffnen. Drücken Sie danach zurück, um den Dialog der Freigabe zu schließen. Drehen Sie das Gerät in den Landschaftsmodus. Plötzlich wird das Teilen des Teilens wieder geöffnet, obwohl ich nicht auf die Schaltfläche geklickt habe.

Wenn ich versuche, den nativen Dialogfeld "Sharing" zu verwenden, sehe ich diesen Fehler nicht. Vielleicht ist ein benutzerdefinierter Freigabendialog die Ursache?

Kann mir jemand sagen, was hier los ist?

War es hilfreich?

Lösung

Hallo, Sie müssen in Ihrer Anwendungsmanifestdatei die Unterstützung bei der Bildschirmausrichtung hinzufügen.

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

Und überschreiben auch die folgende Methode,

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

Andere Tipps

Verwenden Sie die Methode create () anstelle der Show () -Methode

neuer alertdialog.builder (this) .create ()

Versuchen Sie, eine eigene Klasse zu verwenden, die sich aus erstreckt Dialogfragment

Zum Beispiel:

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

Und verwenden Sie es überall in Ihrem Code:

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

Wenn Sie stattdessen nur stattdessen eine eigene Ansicht erstellen möchten, stattdessen Standard -Dialogfenster:

  Dialog onCreateDialog(Bundle savedInstanceState) 

verwenden

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

Zum Beispiel:

Erstellen Sie Werte/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>

und für dieses Layout ändern Sie die eigene Klasse als:

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

und die gleiche Verwendung:

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

Für beide Ansätze wirkt sich auf den Weg von OnsavEInstancestate (Bündel Outstaat) und sparen den Zustand nach der Rotation. Ich denke, es ist ein besserer und universeller Ansatz als Benutzer des einfachen Dialogs.

Es spielt keine Rolle, ob Dialog oder AlertDialog verwendet wurde. Verwenden Sie diesen Code, um das Schließen des Dialogfelds beim Drehen von Bildschirm zu vermeiden:

dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top