Question

Je veux montrer un toast juste après que l'utilisateur clique sur un CheckBoxPreference dans mon PreferenceActivity.

myCheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                Toast.makeText(Prefs.this,
                        "test",
                        Toast.LENGTH_SHORT).show();
                doSomething();
                return false;
            }
        });

J'ai essayé aussi de mettre le toast dans la méthode doSomething (), mais il est toujours affiché après toute la méthode est traitée. J'ai essayé getBaseContext() au lieu de Prefs.this, mais il n'a pas aidé. Toute idée pourquoi le Toast ne fois pas présenté à la façon de le faire faire?

Était-ce utile?

La solution

Cela se produit parce que l'auditeur de onPreferenceClick est en cours d'exécution dans le thread d'interface utilisateur. Ce fil est aussi le même que celui qui les poignées affichant la Toast. Toast#show pousse seulement un message sur la file d'attente de messages qui exécuter du code alors que l'affichage de Toast. Cette file d'attente ne sera pas traitée jusqu'à ce que votre gestionnaire de onPreferenceClick est complètement terminé.

Vous pouvez essayer:

myCheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                Toast.makeText(Prefs.this,
                        "test",
                        Toast.LENGTH_SHORT).show();

                Prefs.this.runOnUiThread(new Runnable() {
                    @Override
                        public void run() {
                            doSomething();
                        }
                    });
                return false;
            }
    });

Cela entraînera le Toast à la poste à la file d'attente de messages, votre doSomething sera également affiché à la file d'attente après le pain grillé. L'inconvénient est qu'il pourrait y avoir des messages UI qui seront traités avant doSomething est appelée. En outre, si doSomething est longue marche, il va monopoliser votre thread d'interface utilisateur et pourrait provoquer un proche possible de la force de l'ANR. Vous voudrez peut-être penser à courir doSomething dans un AsyncTask si elle prend plus de 150 ms environ.

Autres conseils

Ma solution est d'utiliser la diffusion, et faire un récepteur enregistré dans le manifeste Android.

AndroidManifest:

    <receiver android:name=".MyReceiver" >
        <intent-filter >
            <action android:name="showtoast" />
        </intent-filter>
    </receiver>

broadcasts:

public static void BroadcastMessage(Context context, Bundle extra)
{
    Intent intent = new Intent();
    intent.setPackage(context.getPackageName());
    intent.setAction("showtoast");
    if (extra != null)
        intent.putExtras(extra);
    context.sendBroadcast(intent);
}

récepteur comme ci-dessous:

public class MyReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        if ("showtoast".equalsIgnoreCase(intent.getAction()) && (bundle != null)
        {
            String title = bundle.getString("title", "");

            View view;
            TextView mTextView;
            LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.my_toast_layout, null);
            mTextView = (TextView) view.findViewById(R.id.tv_title);
            mTextView.setText(title);

            Toast toast = new Toast(context.getApplicationContext());
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.setView(view);
            toast.setDuration(Toast.LENGTH_LONG);
            toast.show();
        }
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top