Les applications de dialogue rouvrir après une rotation périphérique
-
27-10-2019 - |
Question
Je vous écris une application très simple pour ouvrir ma commande de dialogue de partage. mise en page XML ne contient que 1 bouton:
<?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>
Et sur l'activité, je crée un partage personnalisé de dialogue
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;
}
}
}
cliquez sur le bouton, mon partage de dialogue sera ouvert. Tout bien.
Maintenant, je tourne l'appareil en mode portrait, cliquez sur le bouton pour ouvrir la boîte de dialogue. Après cela, le dos de presse pour fermer le partage de dialogue. dispositif Rotation en mode paysage . Soudain dialogue Partage est réouverte bien que je n'ai pas cliqué sur le bouton.
Quand j'essayer d'utiliser le natif de partage de dialogue je ne vois pas ce bug. Peut-être une mesure de partage de dialogue est la cause?
Quelqu'un peut-il me dire quel est le problème ici?
La solution
Salut Vous devez ajouter le support d'orientation de l'écran dans votre fichier manifeste d'application.
<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>
Et aussi passer outre la méthode suivante,
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
Autres conseils
méthode utilisation create () au lieu de la méthode show ()
new AlertDialog.Builder (this) .Create ()
Essayez une utilisation propre classe qui sera étend de DialogFragment
Par exemple:
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();
}
}
Et l'utiliser partout dans votre 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;
}
});
Si vous voulez créer votre propre point de vue à la place fenêtre de dialogue standard juste à la place:
Dialog onCreateDialog(Bundle savedInstanceState)
utilisation
View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
Par exemple:
besoin de créer des valeurs / mise en page / 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>
et ce changement de mise en page propre classe:
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);
}
}
}
et le même usage:
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;
}
});
Pour les deux approches fonctionnera onSaveInstanceState void (Bundle outstate) et enregistrer l'état après la rotation. Je pense qu'il est mieux et approche universelle alors la boîte de dialogue utilisateur simple.
Peu importe si Dialog ou AlertDialog a été utilisé. Afin d'éviter la fermeture de la boîte de dialogue lorsque vous faites pivoter l'écran, utilisez ce code:
dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);