Чи може Android Toast довше Toast.LENGTH_LONG?


263

Під час використання setDuration () для Toast, чи можна встановити власну довжину або хоча б щось довше Toast.LENGTH_LONG?


4
@Nicolae з якоїсь причини ви видалили toastтег? Це виглядає відповідно до питання ..
Shadow Wizard is Ear For You

2
@ShadowWizard Теги, як мені здається, повинні відображати теми питання, що представляє широкий інтерес. Як, наприклад, він позначений тегом Android, і тому гуру андроїда знайде це питання. Тост зовсім не допомагає цьому питанню і, здається, більше схожий на марний тег. Якщо тост - це добре, оскільки питання стосується тегів в Android, то також довжина була хорошим тегом. Рубайте, кожне слово в питанні повинно бути тегом ... Без поваги, я просто зазначаю :)
Nicu Surdu

11
Я використовую toastтег для. Я подумав, що теги були там, щоб допомогти шукати та сортувати, і toastце, безумовно, звичайний пошук. androidі toastздаються ідеальними.
ChrisWilson4

Відповіді:


142

Значення LENGTH_SHORTі LENGTH_LONGдорівнюють 0 і 1. Це означає, що вони розглядаються як прапори, а не фактичні тривалості, тому я не думаю, що можна буде встановити тривалість нічого іншого, крім цих значень.

Якщо ви хочете відображати повідомлення користувачеві довше, розгляньте Повідомлення про рядок стану . Сповіщення про рядок стану можна програмно скасувати, коли вони більше не стосуються.


1
Дякуємо за пропозицію щодо рядка стану, але я збираюся із користувацькою діалоговою діяльністю.

337

Якщо ви копаєте глибше андроїд-код, ви можете знайти рядки, які чітко вказують, що ми не можемо змінити тривалість повідомлення Toast.

 NotificationManagerService.scheduleTimeoutLocked() {
    ...
    long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
    }

значення за замовчуванням - тривалість

private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds

4
Дякую ... це було ТОЧНО те, що мені було потрібно.
mcherm

3
Дякуємо, що опублікували значення за замовчуванням! Я боявся, що не зможу їх знайти.
Amplify91

1
Я також шукав значення тостів за замовчуванням, це був перший удар. Однозначно схвалено. Дякую!
Дейв

120

Ви можете спробувати:

for (int i=0; i < 2; i++)
{
      Toast.makeText(this, "blah", Toast.LENGTH_LONG).show();
}

подвоїти час. Якщо ви вкажете 3 замість 2, це потроїть час .. і т.д.


17
повідомлення блимає :(
Deniz

61
Це рішення погано, тому що, наприклад, якщо ви припините діяльність до часу тосту, воно буде блимати знову і знову ...
dwbrito

@dwbrito: повністю згоден, а значить -1
Фахім Паркар

[+1] для відповіді .... Скасовувати тост можна, використовуючи Toast.cancel()у відповідних місцях
Devrath

1
Так, його можна реалізувати, але тост буде блимати стільки, скільки ви вказали, кількість
HendraWD

31

Якщо ви хочете Toastзберегти, я виявив, що ви можете зламати шлях до нього, здійснюючи Timerдзвінок toast.show()повторно (щосекунди або так слід робити). Якщо дзвінок show()вже не Toastвідображається, дзвінки нічого не порушують , але він оновить кількість часу перебування на екрані.


3
Проблема з цим полягає в тому, якщо користувач торкнеться екрану, тост буде приховано Android, але потім відтворено таймером.
Фіолетова жирафа

2
@VioletGiraffe - це досить тривіально, щоб впоратися з чимось на зразок булевого прапора у вашому ViewGroup OnTouchзаході. Для оптимізації цього, ймовірно, слід змусити повторити таймер якомога ближче до фактичного часу, Toastякий відображається на екрані (3,5 секунди тривалий, 2 секунди короткого)
syklon

18

Я розробив клас Custom Toast, за допомогою якого ви можете показати Toast протягом потрібної кількості тривалості (у мілілі секунди)

import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;

public final class ToastHelper {

    private static final String TAG = ToastHelper.class.getName();

    public static interface OnShowListener {
        public void onShow(ToastHelper toast);
    }

    public static interface OnDismissListener {
        public void onDismiss(ToastHelper toast);
    }

    private static final int WIDTH_PADDING_IN_DIP = 25;
    private static final int HEIGHT_PADDING_IN_DIP = 15;
    private static final long DEFAULT_DURATION_MILLIS = 2000L;

    private final Context context;
    private final WindowManager windowManager;
    private View toastView;

    private int gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
    private int mX;
    private int mY;
    private long duration = DEFAULT_DURATION_MILLIS;
    private CharSequence text = "";
    private int horizontalMargin;
    private int verticalMargin;
    private WindowManager.LayoutParams params;
    private Handler handler;
    private boolean isShowing;
    private boolean leadingInfinite;

    private OnShowListener onShowListener;
    private OnDismissListener onDismissListener;

    private final Runnable timer = new Runnable() {

        @Override
        public void run() {
            cancel();
        }
    };

    public ToastHelper(Context context) {
        Context mContext = context.getApplicationContext();
        if (mContext == null) {
            mContext = context;
        }
        this.context = mContext;
        windowManager = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        init();
    }

    private void init() {
        mY = context.getResources().getDisplayMetrics().widthPixels / 5;
        params = new WindowManager.LayoutParams();
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
        params.format = android.graphics.PixelFormat.TRANSLUCENT;
        params.type = WindowManager.LayoutParams.TYPE_TOAST;
        params.setTitle("ToastHelper");
        params.alpha = 1.0f;
        // params.buttonBrightness = 1.0f;
        params.packageName = context.getPackageName();
        params.windowAnimations = android.R.style.Animation_Toast;
    }

    @SuppressWarnings("deprecation")
    @android.annotation.TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private View getDefaultToastView() {
        TextView textView = new TextView(context);
        textView.setText(text);
        textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
        textView.setClickable(false);
        textView.setFocusable(false);
        textView.setFocusableInTouchMode(false);
        textView.setTextColor(android.graphics.Color.WHITE);
        // textView.setBackgroundColor(Color.BLACK);
        android.graphics.drawable.Drawable drawable = context.getResources()
                .getDrawable(android.R.drawable.toast_frame);
        if (Build.VERSION.SDK_INT < 16) {
            textView.setBackgroundDrawable(drawable);
        } else {
            textView.setBackground(drawable);
        }
        int wP = getPixFromDip(context, WIDTH_PADDING_IN_DIP);
        int hP = getPixFromDip(context, HEIGHT_PADDING_IN_DIP);
        textView.setPadding(wP, hP, wP, hP);
        return textView;
    }

    private static int getPixFromDip(Context context, int dip) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dip, context.getResources().getDisplayMetrics());
    }

    public void cancel() {
        removeView(true);
    }

    private void removeView(boolean invokeListener) {
        if (toastView != null && toastView.getParent() != null) {
            try {
                Log.i(TAG, "Cancelling Toast...");
                windowManager.removeView(toastView);
                handler.removeCallbacks(timer);
            } finally {
                isShowing = false;
                if (onDismissListener != null && invokeListener) {
                    onDismissListener.onDismiss(this);
                }
            }
        }
    }

    public void show() {
        if (leadingInfinite) {
            throw new InfiniteLoopException(
                    "Calling show() in OnShowListener leads to infinite loop.");
        }
        cancel();
        if (onShowListener != null) {
            leadingInfinite = true;
            onShowListener.onShow(this);
            leadingInfinite = false;
        }
        if (toastView == null) {
            toastView = getDefaultToastView();
        }
        params.gravity = android.support.v4.view.GravityCompat
                .getAbsoluteGravity(gravity, android.support.v4.view.ViewCompat
                        .getLayoutDirection(toastView));
        if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) {
            params.horizontalWeight = 1.0f;
        }
        if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) {
            params.verticalWeight = 1.0f;
        }
        params.x = mX;
        params.y = mY;
        params.verticalMargin = verticalMargin;
        params.horizontalMargin = horizontalMargin;

        removeView(false);
        windowManager.addView(toastView, params);
        isShowing = true;
        if (handler == null) {
            handler = new Handler();
        }
        handler.postDelayed(timer, duration);
    }

    public boolean isShowing() {
        return isShowing;
    }

    public void setDuration(long durationMillis) {
        this.duration = durationMillis;
    }

    public void setView(View view) {
        removeView(false);
        toastView = view;
    }

    public void setText(CharSequence text) {
        this.text = text;
    }

    public void setText(int resId) {
        text = context.getString(resId);
    }

    public void setGravity(int gravity, int xOffset, int yOffset) {
        this.gravity = gravity;
        mX = xOffset;
        mY = yOffset;
    }

    public void setMargin(int horizontalMargin, int verticalMargin) {
        this.horizontalMargin = horizontalMargin;
        this.verticalMargin = verticalMargin;
    }

    public long getDuration() {
        return duration;
    }

    public int getGravity() {
        return gravity;
    }

    public int getHorizontalMargin() {
        return horizontalMargin;
    }

    public int getVerticalMargin() {
        return verticalMargin;
    }

    public int getXOffset() {
        return mX;
    }

    public int getYOffset() {
        return mY;
    }

    public View getView() {
        return toastView;
    }

    public void setOnShowListener(OnShowListener onShowListener) {
        this.onShowListener = onShowListener;
    }

    public void setOnDismissListener(OnDismissListener onDismissListener) {
        this.onDismissListener = onDismissListener;
    }

    public static ToastHelper makeText(Context context, CharSequence text,
            long durationMillis) {
        ToastHelper helper = new ToastHelper(context);
        helper.setText(text);
        helper.setDuration(durationMillis);
        return helper;
    }

    public static ToastHelper makeText(Context context, int resId,
            long durationMillis) {
        String string = context.getString(resId);
        return makeText(context, string, durationMillis);
    }

    public static ToastHelper makeText(Context context, CharSequence text) {
        return makeText(context, text, DEFAULT_DURATION_MILLIS);
    }

    public static ToastHelper makeText(Context context, int resId) {
        return makeText(context, resId, DEFAULT_DURATION_MILLIS);
    }

    public static void showToast(Context context, CharSequence text) {
        makeText(context, text, DEFAULT_DURATION_MILLIS).show();
    }

    public static void showToast(Context context, int resId) {
        makeText(context, resId, DEFAULT_DURATION_MILLIS).show();
    }

    private static class InfiniteLoopException extends RuntimeException {
        private static final long serialVersionUID = 6176352792639864360L;

        private InfiniteLoopException(String msg) {
            super(msg);
        }
    }
}

android.view.WindowManager $ BadTokenException: Неможливо додати вікно - нулевий маркер недійсний; чи працює ваша діяльність?
Агамадулла Сайкат

13

Я зашифрував клас помічників для цього. Код ви можете побачити на сайті github: https://github.com/quiqueqs/Toast-Expander/blob/master/src/com/thirtymatches/toasted/ToastedActivity.java

Ось як би ви показували тост протягом 5 секунд (або 5000 мілісекунд):

Toast aToast = Toast.makeText(this, "Hello World", Toast.LENGTH_SHORT);
ToastExpander.showFor(aToast, 5000);

Thx і Nice, але як ми можемо зупинити нитку наDestroy, наприклад? Я намагався це зробити, але не впевнений: публічна статична ануляція скасування (Toast mytoast) {if (null! = T) t.stop (); mytoast.cancel (); }
hornetbzz

10

Я знаю, що я трохи спізнююсь, але я взяв відповідь Regis_AG і завернув її в клас помічників, і це чудово працює.

public class Toaster {
  private static final int SHORT_TOAST_DURATION = 2000;

  private Toaster() {}

  public static void makeLongToast(String text, long durationInMillis) {
    final Toast t = Toast.makeText(App.context(), text, Toast.LENGTH_SHORT);
    t.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 0);

    new CountDownTimer(Math.max(durationInMillis - SHORT_TOAST_DURATION, 1000), 1000) {
      @Override
      public void onFinish() {
        t.show();
      }

      @Override
      public void onTick(long millisUntilFinished) {
        t.show();
      }
    }.start();
  }
}

У коді програми просто зробіть щось подібне:

    Toaster.makeLongToast("Toasty!", 8000);

Це насправді працює! але як можна зробити його налаштованим та дотичним?
андроїд розробник

Вибачте за це питання для новачків, але коли я створюю вищевказаний клас Toaster, він говорить, що він не може вирішити символ "App" у рядку. заключний тост t = Toast.makeText (App.context (), текст, Toast.LENGTH_SHORT); Дякую і вибачте.
Брайан Флемінг

о, вибачте з цього приводу! App.context () - це в основному фрагмент спеціального коду, який я написав для зручного доступу до ApplicationContext з будь-якого місця, не передаючи його навколо. Це не шаблон, який ви використовуєте для багатьох речей, але я виявив, що це має сенс для ApplicationContext. Ви можете відредагувати цей фрагмент для передачі ApplicationContext в метод як аргумент.
Кріс Айчісон

9

Я знаю, що відповідь є досить пізньою. У мене виникло те саме питання, і я вирішив реалізувати власну версію тостів з голими кістками, вивчивши вихідний код Android для тостів.

В основному вам потрібно створити новий менеджер вікон та показати та приховати вікно на потрібну тривалість роботи за допомогою обробника

 //Create your handler
 Handler mHandler = new Handler();

//Custom Toast Layout
mLayout = layoutInflater.inflate(R.layout.customtoast, null);

//Initialisation 

mWindowManager = (WindowManager) context.getApplicationContext()
            .getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();

params.gravity = Gravity.BOTTOM
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.format = PixelFormat.TRANSLUCENT;
params.windowAnimations = android.R.style.Animation_Toast;
params.type = WindowManager.LayoutParams.TYPE_TOAST;

Після ініціалізації макета ви можете використовувати власні методи ховання та показу

    public void handleShow() {
    mWindowManager.addView(mLayout, mParams);
    }

    public void handleHide() {
        if (mLayout != null) {
            if (mLayout.getParent() != null) {
                mWindowManager.removeView(mLayout);
            }
                         mLayout = null;
        }

Тепер все, що вам потрібно, - це додати дві запущені нитки, які викликають handleShow () та handleHide (), які ви могли б опублікувати в Handler.

    Runnable toastShowRunnable = new Runnable() {
        public void run() {
            handleShow();
        }
    };

 Runnable toastHideRunnable = new Runnable() {
        public void run() {
            handleHide();
        }
    }; 

і заключна частина

public void show() {

    mHandler.post(toastShowRunnable);
    //The duration that you want
    mHandler.postDelayed(toastHideRunnable, mDuration);

}

Це було швидким та брудним впровадженням. Не враховували жодної роботи.


1
Я намагався запустити його (включаючи дзвінок до "show ()"), але нічого не з'являється (тестується на Android 7.1). Я думаю, що ти щось сумуєш. Крім того, де тут частина, яка заважає видалити погляд, як тост зникає через короткий час?
андроїд розробник

8

LONG_DELAY тост-дисплей протягом 3,5 сек і SHORT_DELAY- тост-дисплей протягом 2 сек .

Тост внутрішньо використовує INotificationManager і викликає метод enqueueToast кожен раз, коли викликається Toast.show ().

Зателефонуйте на шоу () SHORT_DELAY двічі, знову потягне за собою той самий тост. він відображатиметься протягом 4 секунд (2 сек + 2 сек).

аналогічно, дзвінок на шоу () з LONG_DELAY двічі потягне за собою той самий тост знову. він відображатиметься протягом 7 сек (3,5 сек + 3,5 сек)


6

Ось спеціальний клас Toast, який я створив за допомогою наведеного вище коду:

import android.content.Context;
import android.os.CountDownTimer;
import android.widget.Toast;

public class CustomToast extends Toast {
    int mDuration;
    boolean mShowing = false;
    public CustomToast(Context context) {
        super(context);
        mDuration = 2;
    }


    /**
     * Set the time to show the toast for (in seconds) 
     * @param seconds Seconds to display the toast
     */
    @Override
    public void setDuration(int seconds) {
        super.setDuration(LENGTH_SHORT);
        if(seconds < 2) seconds = 2; //Minimum
        mDuration = seconds;
    }

    /**
     * Show the toast for the given time 
     */
    @Override
    public void show() {
        super.show();

        if(mShowing) return;

        mShowing = true;
        final Toast thisToast = this;
        new CountDownTimer((mDuration-2)*1000, 1000)
        {
            public void onTick(long millisUntilFinished) {thisToast.show();}
            public void onFinish() {thisToast.show(); mShowing = false;}

        }.start();  
    }
}

5

Якщо вам потрібен довгий тост, є практична альтернатива, але він вимагає від вашого користувача натиснути кнопку ОК, щоб зникнути. Ви можете використовувати AlertDialog так:

String message = "This is your message";
new AlertDialog.Builder(YourActivityName.this)
    .setTitle("Optional Title (you can omit this)")
    .setMessage(message)
    .setPositiveButton("ok", null)
    .show();

Якщо у вас довге повідомлення, швидше за все, ви не знаєте, скільки часу знадобиться користувачеві, щоб прочитати повідомлення, тому іноді корисно вимагати від користувача натиснути кнопку ОК, щоб продовжити. У моєму випадку я використовую цю техніку, коли користувач натискає на значок довідки.


1
Це розумно, але не може бути реалізовано у щось на зразок a Service, де немає інтерфейсу користувача.
mike47

@mikejeep Насправді я нещодавно бачив приклад Google, який показує діалог без активності: developer.android.com/samples/AppShortcuts/index.html
андроїд розробник

5

Як зазначають інші Android Toasts, це може бути LENGTH_LONG або LENGTH_SHORT. Нічого цього не обходиться, і не слід слідувати за жодним із опублікованих «хакерів».

Мета Tost - відображення "несуттєвої" інформації, і через їх триваючу дію повідомлення можуть виноситися далеко за рамки контексту, якщо їх тривалість перевищує певний поріг. Якщо біржові тости були змінені, щоб вони могли відображатись довше, ніж LENGTH_LONG, повідомлення затримається на екрані, поки процес програми не припиниться, оскільки подання тостів буде додано до WindowManager, а не ViewGroup у вашому додатку. Я би припустив, що це важко закодовано.

Якщо вам абсолютно потрібно показувати повідомлення в стилі тостів довше трьох з половиною секунд, я рекомендую створити подання, яке приєднується до вмісту Діяльності, таким чином воно зникне, коли користувач закриє програму. Моя бібліотека SuperToasts займається цією проблемою та багатьма іншими, сміливо використовуйте її! Вам, швидше за все, буде цікаво використовувати SuperActivityToasts


4

Просто використовуйте SuperToast, щоб зробити елегантний тост за будь-яку ситуацію. Зробіть тост барвистим . Відредагуйте свій колір шрифту, а також його розмір . Сподіваюся, що для вас все буде в одному.



3

Ось дуже простий метод, який працював для мене:

for (int i=0; i < 3; i++) { Toast.makeText(this, "MESSAGE", Toast.LENGTH_SHORT).show(); }

Тривалість LENGTH_SHORT - 2 секунди, а LENGTH_LONG - 3,5 секунди, тут повідомлення про тост буде показано протягом 6 секунд, оскільки воно укладено в циклі for. Але недоліком цього методу є те, що через кожні 2 секунди може виникнути невеликий ефект завмирання. але це не дуже помітно. Сподіваюся, це корисно


2

Користувач не може встановити тривалість тосту. тому що функція NotificationManagerService's rasporedTimeoutLocked () не використовує тривалість поля. вихідний код наступний.

private void scheduleTimeoutLocked(ToastRecord r, boolean immediate)
    {
        Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
        long delay = immediate ? 0 : (r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
        mHandler.removeCallbacksAndMessages(r);
        mHandler.sendMessageDelayed(m, delay);
    }

2

Використовуйте Crouton, це дуже гнучка бібліотека Toast.

Крутон

Ви можете використовувати його як тости:

Crouton.makeText(context, "YOUR_MESSAGE", Style.INFO);

а можна навіть трохи глибше і налаштувати його більше, як встановити час на нескінченність! наприклад, тут я хочу показати тост-повідомлення, поки користувач не визнає його, натиснувши на нього.

private static void showMessage(final Activity context, MessageType type, String header, String message) {
    View v = context.getLayoutInflater().inflate(R.layout.toast_layout, null);
    TextView headerTv = (TextView) v.findViewById(R.id.toastHeader);
    headerTv.setText(header);
    TextView messageTv = (TextView) v.findViewById(R.id.toastMessage);
    messageTv.setText(message);
    ImageView toastIcon = (ImageView) v.findViewById(R.id.toastIcon);

    final Crouton crouton = getCrouton(context, v);
    v.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Crouton.hide(crouton);
        }
    });

    crouton.show();
}

private static Crouton getCrouton(final Activity context, View v) {
    Crouton crouton = Crouton.make(context, v);
    crouton.setConfiguration(new Configuration.Builder().setDuration(Configuration.DURATION_INFINITE).build());
    return crouton;
}

Макет твір, який буде завищений на тост.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:animateLayoutChanges="true"
    android:background="@drawable/shadow_container"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:padding="@dimen/default_margin"
    tools:ignore="Overdraw">

    <ImageView
        android:id="@+id/toastIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/default_spacing_full"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/toastHeader"
            style="@style/ItemText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/toastMessage"
            style="@style/ItemSubText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

</LinearLayout>

2

Тривалість тостів можна зламати за допомогою нитки, яка експлуатує виключно тост. Це працює (працює тост протягом 10 секунд, змінює сон і ctr на ваш смак):

final Toast toast = Toast.makeText(this, "Your Message", Toast.LENGTH_LONG);

Thread t = new Thread(){
    public void run(){
          int ctr = 0;
          try{
               while( ctr<10 ){
                    toast.show();
                    sleep(1000);
                    ctr++;
               }
          } catch (Exception e) {
               Log.e("Error", "", e);
          }
     }
 };
 t.start();

1

Тост із власним фоном та видом зробив для мене трюк. Я перевірив його на планшеті Nexus 7, і під час циклу я не помітив анімації fadein fadeout. Ось реалізація:

public static void customToast(Context context, String message, int duration) {

    for (int i = 0; i < duration; i++) {
        Toast toast = new Toast(context);
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setGravity(Gravity.CENTER, 0, 0);
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.toast_layout, null);
        TextView textViewToast = (TextView) view
                .findViewById(R.id.textViewToast);
        textViewToast.setText(message);
        toast.setView(view);
        toast.show();
    }

}

Ось спеціальний перегляд тексту, який використовується у наведеному вище коді:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/textViewToast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/fragment_background"
android:padding="8dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="@color/blue" />

@ dravable / fragment_background змушує мій тост мати закруглений кут, як у версії kitkat. Ви також можете додати інші файли у файл. Будь-які зміни для вдосконалення та коментарі рекомендуються, оскільки я планую реалізувати це в своєму додатку в реальному часі.


1

Сплануйте зворотний відлік часу до майбутнього, регулярно повідомляючи його проміжки часу. Приклад показу 30-секундного відліку в текстовому полі:

     новий CountDownTimer (30000, 1000) {

     публічна недійсність onTick (довгі мільйониUntilFinished) {
         mTextField.setText ("залишилось секунд:" + millisUntilFinished / 1000);
     }

     публічна недійсність onFinish () {
         mTextField.setText ("зроблено!");
     }
  } .start ();



1

Цей текст зникне через 5 секунд.

    final Toast toast = Toast.makeText(getApplicationContext(), "My Text", Toast.LENGTH_SHORT);
    toast.show();

    Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
           @Override
           public void run() {
               toast.cancel(); 
           }
    }, 5000); // Change to what you want

Редагувати: Як сказав Itai Spector у коментарі, це відображатиметься приблизно через 3,5 секунди, тому використовуйте цей код:

    int toastDuration = 5000; // in MilliSeconds
    Toast mToast = Toast.makeText(this, "My text", Toast.LENGTH_LONG);
    CountDownTimer countDownTimer;
    countDownTimer = new CountDownTimer(toastDuration, 1000) {
        public void onTick(long millisUntilFinished) {
            mToast.show();
        }

        public void onFinish() {
            mToast.cancel();
        }
    };

    mToast.show();
    countDownTimer.start();

Я думаю, що цей текст зникне через 3,5 секунди
Itai Spector

@ItaiSpector: Перевірте мій новий код, будь ласка.
Аліреза Нооралі

1

Ні, і більшість / усі перераховані тут хаки більше не працюють в android 9. Але є набагато краще рішення: якщо повідомлення потрібно зависати, скористайтеся діалоговим вікном.

(new AlertDialog.Builder(this)).setTitle("Sorry!")
.setMessage("Please let me know by posting a beta comment on the play store .")
.setPositiveButton("OK", null).create().show();

Хоча це не відповідь, яку шукав Хуссейн, це кращий варіант, ніж усі ці «хаки»!
Danny EK van der Kolk

0

Дуже простий підхід до створення трохи довшого повідомлення полягає в наступному:

private Toast myToast;

public MyView(Context context) {
  myToast = Toast.makeText(getContext(), "", Toast.LENGTH_LONG);
}

private Runnable extendStatusMessageLengthRunnable = new Runnable() {
  @Override
    public void run() {
    //Show the toast for another interval.
    myToast.show();
   }
}; 

public void displayMyToast(final String statusMessage, boolean extraLongDuration) {
  removeCallbacks(extendStatusMessageLengthRunnable);

  myToast.setText(statusMessage);
  myToast.show();

  if(extraLongDuration) {
    postDelayed(extendStatusMessageLengthRunnable, 3000L);
  }
}

Зауважте, що наведений вище приклад виключає параметр LENGTH_SHORT, щоб зробити приклад простим.

Зазвичай ви не хочете використовувати повідомлення Toast для відображення повідомлень протягом дуже довгих інтервалів, оскільки це не призначене для класу Toast призначення. Але бувають випадки, коли кількість потрібного для відображення тексту може зайняти користувачеві більше 3,5 секунд для читання, і в цьому випадку невелике продовження часу (наприклад, до 6,5 секунд, як показано вище) може, IMO, бути корисним і відповідати передбачуваному використанню.


0

Встановлює тост до певного періоду в мілісекундах:

public void toast(int millisec, String msg) {
    Handler handler = null;
    final Toast[] toasts = new Toast[1];
    for(int i = 0; i < millisec; i+=2000) {
        toasts[0] = Toast.makeText(this, msg, Toast.LENGTH_SHORT);
        toasts[0].show();
        if(handler == null) {
            handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    toasts[0].cancel();
                }
            }, millisec);
        }
    }
}

0
  private Toast mToastToShow;
  public void showToast(View view) {
 // Set the toast and duration
 int toastDurationInMilliSeconds = 10000;
 mToastToShow = Toast.makeText(this, "Hello world, I am a toast.",  Toast.LENGTH_LONG);

 // Set the countdown to display the toast
 CountDownTimer toastCountDown;
 toastCountDown = new CountDownTimer(toastDurationInMilliSeconds, 1000 /*Tick duration*/) {
  public void onTick(long millisUntilFinished) {
     mToastToShow.show();
  }
  public void onFinish() {
     mToastToShow.cancel();
     }
    };

    // Show the toast and starts the countdown
     mToastToShow.show();
     toastCountDown.start();
      }

0

Після провалу кожного доступного рішення я нарешті вирішив використовувати рекурсію.

Код:

//Recursive function, pass duration in seconds
public void showToast(int duration) {
    if (duration <= 0)
        return;

    Toast.makeText(this, "Hello, it's a toast", Toast.LENGTH_LONG).show();
    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            showToast(duration-1);
        }
    }, 1000);
}

2
Більшість рішень у цьому питанні, що стосуються виклику "шоу" неодноразово, щоб зберігати тост відображається, роблять це з тим самим тостом екземпляра, тоді як ваш насправді створює новий екземпляр тосту щосекунди і уточнює, що кожне з них повинно бути показане для LONG тривалість (як правило, 3,5 секунди). Це не тільки неефективно, тому що ви продовжуєте створювати додаткові екземпляри об’єктів, але також Android ставить тости-повідомлення в чергу, щоб їх відображали одне за одним протягом їх визначеної тривалості. Тож якби ви зателефонували цьому тривалістю 5, повідомлення фактично відображатиметься протягом 17,5 секунд.
Найл

-1
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show(); 
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show();

Дуже просте рішення питання. Дві або тричі з них змусять Тост протриматися довше. Це єдиний шлях.


Хоча звуки рубають, але цінуй мислення!
Sony Kadavan

чому відмовився від подібного рішення, згаданого @Arturo, використовує той самий трюк з циклом for
пошарпаний

Такий підхід спрацював для мене. Було б добре почути від тих, хто голосував, чому вони так зробили.
Крістофер Міллс

-8

Ви можете встановити бажаний час у мілісекундах таким Toast.makeText();способом:

//40 seconds
long mToastLength = 40*1000 
//this toast will be displayed for 40 seconds.
Toast.makeText(this, "Hello!!!!!", mToastLength).show(); 

1
Відповідь ПРАВИЛЬНА! API було розширено в певний момент часу, щоб дозволити використовувати значення, відмінне від LENGTH_LONG або LENGTH_SHORT. I
rts

Я не думаю, що так. Подивіться на android.googlesource.com/platform/frameworks/base/+/…
AntiCZ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.