Тост в PreferenceActivity отображается поздно

1

Я хочу показать 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, но это не помогло. Любая идея, почему тост не появляется сразу и как это сделать?

Теги:
preferenceactivity
toast
preferences

2 ответа

3
Лучший ответ

Это происходит потому, что прослушиватель 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 мс.

  • 0
    Спасибо за подробное объяснение. Метод фактически инициирует рукопожатие OAuth и затем запускает новое действие, показывающее WebView для выполнения авторизации OAuth. Таким образом, когда пользователь нажимает на CheckBox, до начала активности WebView требуется несколько секунд, потому что сначала устанавливается соединение с Twitter для получения токена запроса. -> Причина, по которой я хочу показать тост, состоит в том, чтобы информировать пользователя о том, что что-то происходит, в случае, если он бродит, почему кажется, что ничего не происходит в течение нескольких секунд (до начала / показа активности WebView).
  • 0
    Показать асинктаск с диалогом прогресса
Показать ещё 2 комментария
0

Мое решение - это широковещательная передача, а также приемник, зарегистрированный в манифесте 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();
        }
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню