Um Toast Android pode ter mais de Toast.LENGTH_LONG?

263

Ao usar setDuration () para um Toast, é possível definir um comprimento personalizado ou pelo menos algo mais do que Toast.LENGTH_LONG?

Hussein El Feky
fonte
4
@ Nicolae alguma razão para você remover a toasttag? Parece relevante para a pergunta ..
Shadow Wizard é Ear For You
2
@ShadowWizard As tags, para mim, devem refletir os tópicos da pergunta que é de amplo interesse. Como por exemplo, está marcado como android e, portanto, um guru do Android encontrará essa pergunta. O Toast não ajuda em nada essa questão e parece mais uma etiqueta inútil. Se o brinde é bom, porque a pergunta é sobre Tag no Android, então também o comprimento era uma boa tag. Hack, cada palavra na questão deve ser um tag ... Sem desrespeito, apenas fazendo o meu ponto :)
Nicu Surdu
11
Eu uso a toasttag para. Eu pensei que as tags estavam lá para ajudar na pesquisa e classificação e toasté definitivamente uma pesquisa comum. androide toastparece perfeito.
ChrisWilson4

Respostas:

142

Os valores de LENGTH_SHORTe LENGTH_LONGsão 0 e 1. Isso significa que eles são tratados como sinalizadores em vez de durações reais, então eu não acho que será possível definir a duração para algo diferente desses valores.

Se você deseja exibir uma mensagem para o usuário por mais tempo, considere uma Notificação na Barra de Status . As notificações da barra de status podem ser canceladas programaticamente quando não forem mais relevantes.

Dave Webb
fonte
1
Obrigado pela sugestão sobre a barra de status, mas estou indo com uma atividade de diálogo personalizada.
337

Se você se aprofundar no código do Android, poderá encontrar as linhas que indicam claramente que não podemos alterar a duração da mensagem do Toast.

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

e valores padrão para a duração são

private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds
Se sentir bem
fonte
4
Obrigado ... era exatamente isso que eu precisava.
mcherm
3
Obrigado por postar os valores padrão! Eu estava com medo de não conseguir encontrá-los.
Amplify91
1
Eu também estava procurando os valores padrão do brinde, esse foi o primeiro hit. Definitivamente votado. Obrigado!
Dave
120

Você pode tentar:

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

dobrar o tempo. Se você especificar 3 em vez de 2, ele triplicará o tempo ... etc.

Arturo
fonte
17
a mensagem pisca :(
Deniz
61
Esta solução é ruim porque, por exemplo, se você encerrar a atividade antes da hora da torrada, ela estará piscando repetidamente ...
dwbrito 27/02
@dwbrito: concordo totalmente e, portanto, -1
Fahim Parkar
[+1] para a resposta .... O cancelamento da torrada pode ser manipulado usando-o Toast.cancel()em locais apropriados #
774 Devrath
1
Sim, pode ser implementada, mas o brinde será piscar tanto quanto você especificar a contagem
HendraWD
31

Se você quer Toastpersistir, descobri que você pode invadir o local fazendo uma Timerligação toast.show()repetidamente (a cada segundo, mais ou menos). A chamada show()não interrompe nada se Toasta tela já estiver sendo exibida, mas atualiza a quantidade de tempo que permanece na tela.

iandisme
fonte
3
O problema é que, se o usuário tocar na tela, o brinde será oculto pelo Android, mas depois recriado pelo timer.
Violet Giraffe
2
@VioletGiraffe que é bastante trivial para lidar com algo como uma bandeira booleana no seu ViewGroup OnTouchevento. Para otimizar esse você provavelmente deve fazer o seu temporizador Repita o mais próximo do tempo real o Toasté mostrado na tela (3,5 segundos por muito tempo, 2 segundos para o short)
syklon
18

Eu desenvolvi uma classe Custom Toast com a qual você pode mostrar o Toast pelo período desejado (em mili segundos)

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);
        }
    }
}
Gopal Gopi
fonte
android.view.WindowManager $ BadTokenException: não foi possível adicionar o token de janela nulo não é válido; sua atividade está em execução?
Ahamadullah Saikat
13

Eu codifiquei uma classe auxiliar para fazer isso. Você pode ver o código no github: https://github.com/quiqueqs/Toast-Expander/blob/master/src/com/thirtymatches/toasted/ToastedActivity.java

É assim que você exibe uma torrada por 5 segundos (ou 5000 milissegundos):

Toast aToast = Toast.makeText(this, "Hello World", Toast.LENGTH_SHORT);
ToastExpander.showFor(aToast, 5000);
Henrique
fonte
Thx e Nice, mas como podemos parar o thread no Destroy, por exemplo? Eu tentei fazer isso, mas não tenho certeza: public static void cancel (Toast mytoast) {if (null! = T) t.stop (); mytoast.cancel (); }
hornetbzz 17/09/12
10

Sei que estou um pouco atrasado, mas peguei a resposta de Regis_AG e envolvi-a em uma classe auxiliar e funciona muito bem.

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

No código do seu aplicativo, faça algo assim:

    Toaster.makeLongToast("Toasty!", 8000);
Chris Aitchison
fonte
Isso realmente funciona! mas como você pode torná-lo personalizável e palpável?
desenvolvedor android
Desculpe por esta pergunta de novato, mas quando eu crio a classe Toaster acima, ela diz que não pode resolver o símbolo 'App' na linha. Toast final t = Toast.makeText (App.context (), texto, Toast.LENGTH_SHORT); Obrigado e desculpas.
Brian Fleming
oh, desculpe por isso! App.context () é basicamente um código personalizado que eu havia escrito para acessar o ApplicationContext convenientemente de qualquer lugar sem passar por ele. Não é um padrão que você usaria para muitas coisas, mas achei que fazia sentido para o ApplicationContext. Convém editar este trecho para passar ApplicationContext no método como argumento.
precisa
9

Eu sei que a resposta é muito tarde .. Eu tive o mesmo problema e decidi implementar minha própria versão do bare bones Toast, depois de procurar no código-fonte do Android o brinde.

Basicamente, você precisa criar um novo gerenciador de janelas e mostrar e ocultar a janela pela duração desejada usando um manipulador

 //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;

Após a inicialização do layout, você pode usar seus próprios métodos de ocultar e mostrar

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

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

Agora tudo que você precisa é adicionar dois threads executáveis ​​que chamam handleShow () e handleHide () que você pode postar no manipulador.

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

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

e a parte final

public void show() {

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

}

Esta foi uma implementação rápida e suja. Não levamos nenhum desempenho em consideração.

Chris
fonte
1
Tentei executá-lo (incluindo a chamada para "show ()"), mas nada aparece (testado no Android 7.1). Eu acho que você sente falta de alguma coisa. Além disso, onde está a parte que impede a exibição da vista, pois um brinde desaparece após um curto período de tempo?
desenvolvedor Android
8

Brinde LONG_DELAY por 3,5 segundos e SHORT_DELAY brinde por 2 segundos .

O Toast usa internamente o INotificationManager e chama seu método enqueueToast toda vez que um Toast.show () é chamado.

Chamar o show () com SHORT_DELAY duas vezes enfileirará a mesma torrada novamente. ele será exibido por 4 segundos (2 segundos + 2 segundos).

Da mesma forma, chamar o show () com LONG_DELAY duas vezes colocará a mesma torrada novamente. será exibido por 7 segundos (3,5 segundos + 3,5 segundos)

Lava Sangeetham
fonte
6

Aqui está uma classe Toast personalizada que eu criei usando o código acima:

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();  
    }
}
Philipp F
fonte
5

Se você precisar de um Toast longo, há uma alternativa prática, mas é necessário que o usuário clique no botão OK para que ele desapareça. Você pode usar um AlertDialog como este:

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

Se você tiver uma mensagem longa, é provável que não saiba quanto tempo levará para o usuário ler a mensagem; portanto, às vezes, é uma boa ideia exigir que ele clique no botão OK para continuar. No meu caso, uso essa técnica quando um usuário clica em um ícone de ajuda.

Steven
fonte
1
Isso é inteligente, mas não pode ser implementado em algo como a Service, onde não há interface do usuário.
precisa saber é o seguinte
@mikejeep Na verdade, recentemente vi um exemplo do Google, mostrando uma caixa de diálogo sem atividade: developer.android.com/samples/AppShortcuts/index.html
desenvolvedor Android
5

Conforme mencionado por outras pessoas, o Android Toasts pode ser LENGTH_LONG ou LENGTH_SHORT. Não há como contornar isso, nem você deve seguir nenhum dos 'hacks' publicados.

O objetivo do Toasts é exibir informações "não essenciais" e, devido ao seu efeito prolongado, as mensagens podem ficar muito fora de contexto se sua duração exceder um determinado limite. Se os Toasts de estoque foram modificados para que possam ser exibidos por mais de LENGTH_LONG, a mensagem permanecerá na tela até o processo do aplicativo terminar, pois as visualizações de brinde são adicionadas ao WindowManager e não um ViewGroup no seu aplicativo. Eu diria que é por isso que é codificado.

Se você absolutamente precisar mostrar uma mensagem no estilo brinde por mais de três segundos e meio, recomendo criar uma exibição anexada ao conteúdo da Atividade, para que ela desapareça quando o usuário sair do aplicativo. Minha biblioteca do SuperToasts lida com esse problema e muitos outros, fique à vontade para usá-lo! Você provavelmente estaria interessado em usar SuperActivityToasts

John P.
fonte
4

Basta usar o SuperToast para fazer um brinde elegante em qualquer situação. Faça sua torrada colorida . Edite a cor da fonte e também o tamanho . Espero que seja tudo em um para você.

Muhammad Jobayer
fonte
3

Aqui está um método muito simples que funcionou para mim:

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

A duração de LENGTH_SHORT é de 2 segundos e LENGTH_LONG é de 3,5 segundos. Aqui, a mensagem de brinde será mostrada por 6 segundos, uma vez que está dentro de um loop for. Mas uma desvantagem desse método ocorre após cada 2 s, um pequeno efeito de desbotamento pode surgir. mas não é muito perceptível. Espero que seja útil

Liya
fonte
2

O usuário não pode definir a duração do Toast. porque a função scheduleTimeoutLocked () de NotificationManagerService não usa a duração do campo. o código fonte é o seguinte.

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);
    }
cronaldoyang
fonte
2

Use Crouton, é uma biblioteca Toast muito flexível.

Crouton

Você pode usá-lo como brindes:

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

ou você pode ir um pouco mais fundo e personalizá-lo mais, como definir o tempo para infinito! por exemplo, aqui quero mostrar uma mensagem de brinde até que o usuário a reconheça clicando nela.

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

Layout de custódia que será inflado para o brinde.

<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>
Muhammad Alfaifi
fonte
2

A duração do brinde pode ser hackeada usando um segmento que executa o brinde exclusivamente. Isso funciona (executa a torrada por 10 segundos, modifica o sono e o ctr ao seu gosto):

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();
ExeCode
fonte
1

Um brinde com plano de fundo e vista personalizados fez o truque para mim. Testei-o no tablet nexus 7 e não notei nenhuma animação de fadein fadeout durante o loop. Aqui está a implementação:

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

}

Aqui está o texto personalizado usado no código acima:

<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" />

@ drawable / fragment_background está fazendo meu brinde ter um canto arredondado como na versão kitkat. Você também pode adicionar outras visualizações no arquivo. Quaisquer modificações para aprimoramento e comentários são incentivadas, pois planejo implementar isso no meu aplicativo ao vivo.

Argumento ilegal
fonte
1

Programe uma contagem regressiva até uma hora no futuro, com notificações regulares em intervalos ao longo do caminho. Exemplo de exibição de uma contagem regressiva de 30 segundos em um campo de texto:

     novo CountDownTimer (30000, 1000) {

     public void onTick (long millisUntilFinished) {
         mTextField.setText ("segundos restantes:" + millisUntilFinished / 1000);
     }

     public void onFinish () {
         mTextField.setText ("pronto!");
     }
  }.começar();


Houssin Boulla
fonte
1

Este texto desaparecerá em 5 segundos.

    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

Edit: Como o Itai Spector no comentário disse que será mostrado cerca de 3,5 segundos, então use este código:

    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();
Alireza Noorali
fonte
Eu acho que este texto irá desaparecer após 3,5 segundos
Itai Spector
@ItaiSpector: Verifique meu novo código, por favor.
Alireza Noorali
1

Não, e a maioria dos hacks listados aqui não funciona mais no Android 9. Mas há uma solução muito melhor: se você precisar de uma mensagem, use uma caixa de diálogo.

(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();
Al Ro
fonte
Embora essa não seja a resposta que Hussein estava procurando, é uma opção melhor do que todos esses 'hacks'!
Danny EK van der Kolk
0

Uma abordagem muito simples para criar uma mensagem um pouco mais longa é a seguinte:

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

Observe que o exemplo acima elimina a opção LENGTH_SHORT para manter o exemplo simples.

Geralmente, você não deseja usar uma mensagem Toast para exibir mensagens por intervalos muito longos, pois esse não é o objetivo pretendido da classe Toast. Mas há momentos em que a quantidade de texto que você precisa exibir pode levar mais de 3,5 segundos para ler o usuário e, nesse caso, uma pequena extensão de tempo (por exemplo, para 6,5 ​​segundos, como mostrado acima) pode, IMO, ser útil e consistente com o uso pretendido.

Carl
fonte
0

Define o brinde para um período específico em mili-segundos:

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);
        }
    }
}
LEMUEL ADANE
fonte
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();
      }
Pa Palca
fonte
0

Depois de falhar com todas as soluções disponíveis, finalmente tive uma solução alternativa usando a recursão.

Código:

//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);
}
umair151
fonte
2
A maioria das soluções nesta questão relacionadas à chamada "show" repetidamente para manter a torrada exibida está fazendo o mesmo com a mesma instância de torrada, enquanto a sua está realmente criando uma nova instância de torrada a cada segundo e especificando que cada uma deve ser mostrada por muito tempo. duração (normalmente 3,5 segundos). Isso não é apenas ineficiente porque você continua criando instâncias extras de objetos, mas também o Android coloca mensagens brinde em uma fila para serem exibidas uma após a outra pela duração especificada. Portanto, se você ligasse para isso com uma duração de 5, a mensagem seria exibida por 17,5 segundos.
Niall
-1
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show(); 
Toast.makeText(this, "Text", Toast.LENGTH_LONG).show();

Uma solução muito simples para a pergunta. Duas ou três delas farão o Toast durar mais tempo. É a única maneira de contornar.

GoLfWRC
fonte
Embora sons hackear, mas aprecio o pensamento!
Sony Kadavan
por isso que downvoted uma solução semelhante mencionado por @Arturo usa a mesma doçura com o loop
Pobre
Essa abordagem funcionou para mim. Seria bom ouvir aqueles que votaram contra por que o fizeram.
Christopher Mills
-8

Você pode definir o tempo desejado em milissegundos no Toast.makeText();método desta forma:

//40 seconds
long mToastLength = 40*1000 
//this toast will be displayed for 40 seconds.
Toast.makeText(this, "Hello!!!!!", mToastLength).show(); 
android.app
fonte
1
A resposta é CORRETA! A API foi estendida em algum momento para permitir o uso de um valor diferente de LENGTH_LONG ou LENGTH_SHORT. I
rts