Я хочу показать Toast сразу после того, как пользователь нажимает на CheckBoxPreference в моей PreferenceActivity.
myCheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Toast.makeText(Prefs.this,
"test",
Toast.LENGTH_SHORT).show();
doSomething();
return false;
}
});
Я также попытался поместить Toast в метод doSomething(), но он всегда отображается после обработки всего метода. Я попробовал getBaseContext()
вместо Prefs.this
, но это не помогло.
Любая идея, почему тост не появляется сразу и как это сделать?
Это происходит потому, что прослушиватель onPreferenceClick
работает в потоке пользовательского интерфейса. Этот поток также совпадает с тем, который обрабатывает отображение Toast
. Toast#show
только толкает сообщение в очередь сообщений, которое затем запускает код для отображения Toast
. Эта очередь не будет обрабатываться до тех пор, пока ваш обработчик onPreferenceClick
не будет полностью завершен.
Вы можете попробовать:
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;
}
});
Это приведет к сообщению Toast
в очередь сообщений, после чего ваш тэг doSomething
также будет отправлен в очередь после тоста. Недостатком этого является то, что могут быть сообщения UI, которые будут обрабатываться до вызова doSomething
. Кроме того, если doSomething
работает долго, он будет монополизировать ваш поток пользовательского интерфейса и может привести к тому, что возможная сила ANR будет закрыта. Возможно, вам захочется подумать о запуске doSomething
в AsyncTask
, если потребуется более 150 мс.
Мое решение - это широковещательная передача, а также приемник, зарегистрированный в манифесте android.
в AndroidManifest:
<receiver android:name=".MyReceiver" >
<intent-filter >
<action android:name="showtoast" />
</intent-filter>
</receiver>
отправка трансляции:
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);
}
как показано ниже:
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();
}
}
}