2010-08-29 5 views
1

Je veux afficher un Toast juste après que l'utilisateur ait cliqué sur une CheckBoxPreference dans mon PreferenceActivity.Toast dans PreferenceActivity est affiché en retard

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

J'ai aussi essayé de mettre le toast dans la méthode doSomething(), mais il a toujours montré après toute la méthode est traitée. J'ai essayé getBaseContext() au lieu de Prefs.this, mais cela n'a pas aidé. Une idée de pourquoi le Toast n'apparaît pas immédiatement et comment le faire?

Répondre

3

Cela se produit car le programme d'écoute onPreferenceClick s'exécute dans le thread d'interface utilisateur. Ce fil est également le même que celui qui gère l'affichage du Toast. Toast#show ne fait que pousser un message dans la file d'attente des messages qui exécutera ensuite le code pour afficher Toast. Cette file d'attente ne sera pas traitée avant que votre gestionnaire onPreferenceClick soit 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 de ceci est qu'il pourrait y avoir des messages d'interface utilisateur qui seront traités avant l'appel de doSomething. En outre, si doSomething est en cours d'exécution, il monopolisera votre thread d'interface utilisateur et pourrait entraîner une fermeture possible de force ANR. Vous voudrez peut-être penser à courir doSomething dans un AsyncTask si cela prend plus de 150ms environ.

+0

Merci pour expliquer en détail. La méthode initie en fait une négociation OAuth, puis démarre une nouvelle activité montrant un WebView pour effectuer l'autorisation OAuth. Ainsi, lorsque l'utilisateur clique sur le CheckBox, il faut quelques secondes avant que l'activité WebView soit démarrée, car une connexion à Twitter est d'abord établie pour recevoir le jeton de demande. -> La raison pour laquelle je veux montrer le toast est d'informer l'utilisateur que quelque chose se passe au cas où il se promène, pourquoi rien ne semble se passer pendant quelques secondes (avant que l'activité WebView ne soit démarrée/affichée). – Manuel

+0

Afficher une asynctask avec une boîte de dialogue de progression – Falmarri

+0

Qu'est-ce que Prefs.this ?? –

0

Ma solution est d'utiliser broadcast, et de faire un récepteur enregistré dans le manifeste android.

dans AndroidManifest:

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

diffusion envoi:

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