Тост в PreferenceActivity отображается поздно - PullRequest
1 голос
/ 29 августа 2010

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

Ответы [ 2 ]

3 голосов
/ 29 августа 2010

Это происходит потому, что слушатель 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 также будет отправлен в очередь после тоста.Недостатком этого является то, что могут быть сообщения пользовательского интерфейса, которые будут обработаны до вызова doSomething.Кроме того, если doSomething работает долго, это монополизирует ваш поток пользовательского интерфейса и может вызвать возможное закрытие ANR.Вы можете подумать о запуске doSomething в AsyncTask, если это займет более 150 мс или около того.

0 голосов
/ 05 мая 2016

Мое решение - использовать широковещательную рассылку и сделать регистратор зарегистрированным в 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();
        }
    }
}
...