Android Toast có thể dài hơn Toast.LENGTH_LONG không?


263

Khi sử dụng setDuration () cho Toast, có thể đặt độ dài tùy chỉnh hoặc ít nhất là một cái gì đó dài hơn Toast.LENGTH_LONG?


4
@Nicolae bất kỳ lý do bạn xóa toastthẻ? Có vẻ như có liên quan đến câu hỏi ..
Shadow Wizard là Ear For You

2
@ShadowWizard Các thẻ, dường như đối với tôi, sẽ phản ánh các chủ đề của câu hỏi được nhiều người quan tâm. Giống như, ví dụ, nó được gắn thẻ Android và vì vậy một bậc thầy Android sẽ tìm thấy câu hỏi này. Toast hoàn toàn không giúp ích gì cho câu hỏi này và có vẻ giống như một thẻ vô dụng. Nếu bánh mì nướng là một thứ tốt, bởi vì câu hỏi là về Thẻ trong Android, thì độ dài cũng là một thẻ tốt. Hack, mỗi từ trong câu hỏi phải là một thẻ ... Không tôn trọng, chỉ đưa ra quan điểm của tôi :)
Nicu Surdu

11
Tôi sử dụng toastthẻ để. Tôi nghĩ rằng các thẻ ở đó để giúp tìm kiếm và sắp xếp và toastchắc chắn là một tìm kiếm phổ biến. androidtoastcó vẻ hoàn hảo.
ChrisWilson4

Câu trả lời:


142

Các giá trị của LENGTH_SHORTLENGTH_LONGlà 0 và 1. Điều này có nghĩa là chúng được coi là cờ thay vì thời lượng thực tế vì vậy tôi không nghĩ có thể đặt thời lượng thành bất kỳ giá trị nào khác ngoài các giá trị này.

Nếu bạn muốn hiển thị thông báo cho người dùng lâu hơn, hãy xem xét Thông báo trên Thanh trạng thái . Thông báo trên Thanh trạng thái có thể bị hủy theo chương trình khi chúng không còn phù hợp.


1
Cảm ơn lời đề nghị về thanh trạng thái, nhưng tôi sẽ thực hiện một hoạt động hộp thoại tùy chỉnh.

337

Nếu bạn đào sâu hơn về mã android, bạn có thể tìm thấy các dòng chỉ rõ, rằng chúng tôi không thể thay đổi thời lượng của tin nhắn Toast.

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

và giá trị mặc định cho thời lượng là

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

4
Cảm ơn ... đây là chính xác những gì tôi cần.
mcherm

3
Cảm ơn bạn đã đăng các giá trị mặc định! Tôi sợ rằng tôi sẽ không thể tìm thấy chúng.
Amplify91

1
Tôi cũng đang tìm kiếm các giá trị bánh mì nướng mặc định, đây là lần đầu tiên. Chắc chắn nâng cao. Cảm ơn!
Dave

120

Bạn có thể muốn thử:

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

nhân đôi thời gian Nếu bạn chỉ định 3 thay vì 2, nó sẽ nhân ba thời gian..v.v.


17
tin nhắn nhấp nháy :(
Deniz

61
Giải pháp này rất tệ bởi vì, ví dụ, nếu bạn thoát khỏi hoạt động trước thời điểm bánh mì nướng, nó sẽ nhấp nháy liên tục ...
dwbrito 27/213

@dwbrito: hoàn toàn đồng ý và do đó -1
Fahim Parkar

[+1] cho câu trả lời .... Việc hủy bỏ bánh mì nướng có thể được xử lý bằng cách sử dụng Toast.cancel()ở những nơi thích hợp
Devrath

1
Có, nó có thể được thực hiện, nhưng bánh mì nướng sẽ nhấp nháy nhiều như bạn chỉ định số lượng
HendraWD

31

Nếu bạn muốn Toasttiếp tục, tôi thấy bạn có thể hack theo cách của mình bằng cách Timergọi toast.show()liên tục (mỗi giây hoặc lâu hơn nên làm). Gọi show()không phá vỡ bất cứ điều gì nếu Toastnó đã hiển thị, nhưng nó sẽ làm mới lượng thời gian nó ở trên màn hình.


3
Vấn đề với điều này là nếu người dùng chạm vào màn hình, bánh mì nướng sẽ bị ẩn bởi Android nhưng sau đó được tạo lại bằng bộ đếm thời gian.
Hươu cao cổ Violet

2
@VioletGiraffe đó là chuyện nhỏ để xử lý với một cái gì đó giống như một lá cờ boolean trong ViewGroup OnTouchsự kiện của bạn . Để tối ưu hóa điều này, có lẽ bạn nên làm cho bộ đếm thời gian của mình lặp lại gần với thời gian thực tế Toastđược hiển thị trên màn hình (dài 3,5 giây, ngắn 2 giây)
syklon

18

Tôi đã phát triển một lớp Toast tùy chỉnh mà bạn có thể hiển thị Toast với thời lượng mong muốn (tính bằng Milli giây)

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: Không thể thêm cửa sổ - mã thông báo null không hợp lệ; hoạt động của bạn có chạy không?
Ahamadullah Saikat

13

Tôi đã mã hóa một lớp người trợ giúp để làm việc này. Bạn có thể xem mã tại github: https://github.com/quiqueqs/Toast-Expander/blob/master/src/com/thundredmatches/toOK/ToOKActivity.java

Đây là cách bạn hiển thị bánh mì nướng trong 5 giây (hoặc 5000 mili giây):

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

Thx và Nice nhưng làm thế nào chúng ta có thể dừng chuỗi trênDestroy chẳng hạn? Tôi đã cố gắng làm điều đó nhưng không chắc chắn: hủy bỏ tĩnh tĩnh công khai (Toast mytoast) {if (null! = T) t.stop (); mytoast.celon (); }
hornetbzz

10

Tôi biết tôi đến hơi muộn, nhưng tôi đã lấy câu trả lời của Regis_AG và gói nó trong một lớp trợ giúp và nó hoạt động rất tốt.

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

Trong mã ứng dụng của bạn, chỉ cần làm một cái gì đó như thế này:

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

Điều này thực sự hoạt động! Nhưng làm thế nào bạn có thể làm cho nó tùy biến, và có thể chạm vào?
nhà phát triển Android

Xin lỗi cho câu hỏi của người mới này, nhưng khi tôi tạo lớp Toaster ở trên, nó nói rằng nó không thể giải quyết biểu tượng 'Ứng dụng' trong dòng. Toast cuối cùng t = Toast.makeText (App.context (), văn bản, Toast.LENGTH_SHORT); Cảm ơn, và xin lỗi.
Brian Fleming

Oh xin lỗi về điều đó! App.context () về cơ bản là một đoạn mã tùy chỉnh mà tôi đã viết để truy cập ApplicationContext một cách thuận tiện từ mọi nơi mà không cần đưa nó đi khắp nơi. Không phải là một mẫu bạn sẽ sử dụng cho nhiều thứ, nhưng tôi thấy rằng nó có ý nghĩa đối với ApplicationContext. Bạn có thể muốn chỉnh sửa đoạn mã này để truyền ApplicationContext vào phương thức làm đối số.
Chris Aitchison

9

Tôi biết câu trả lời là khá muộn .. Tôi đã có cùng một vấn đề và quyết định thực hiện phiên bản Toast xương trần của riêng tôi, sau khi xem mã nguồn của Android để nướng bánh mì.

Về cơ bản, bạn cần tạo một trình quản lý Cửa sổ mới, đồng thời hiển thị và ẩn cửa sổ trong khoảng thời gian mong muốn bằng trình xử lý

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

Sau khi khởi tạo bố cục, bạn có thể sử dụng các phương thức ẩn và hiển thị của riêng mình

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

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

Bây giờ, tất cả những gì bạn cần là thêm hai luồng có thể chạy được gọi là handShow () và handleHide () mà bạn có thể đăng lên Handler.

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

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

và phần cuối cùng

public void show() {

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

}

Đây là một triển khai nhanh chóng và bẩn thỉu .. Không xem xét bất kỳ hiệu suất nào.


1
Tôi đã cố chạy nó (bao gồm cả lệnh gọi "show ()") nhưng không có gì xuất hiện (đã thử nghiệm trên Android 7.1). Tôi nghĩ rằng bạn bỏ lỡ một cái gì đó. Ngoài ra, phần nào ở đây ngăn không cho chế độ xem bị xóa, vì bánh mì nướng biến mất sau một thời gian ngắn?
nhà phát triển Android

8

Hiển thị bánh mì nướng LONG_DELAY trong 3,5 giây và hiển thị bánh mì nướng SHORT_DELAY trong 2 giây .

Toast sử dụng nội bộ INotificationManager và gọi phương thức enqueueToast mỗi khi gọi Toast.show ().

Gọi chương trình () với SHORT_DELAY hai lần sẽ ghi lại cùng một bánh mì nướng. nó sẽ hiển thị trong 4 giây (2 giây + 2 giây).

tương tự, gọi chương trình () với LONG_DELAY hai lần sẽ ghi lại cùng một bánh mì nướng. nó sẽ hiển thị trong 7 giây (3,5 giây + 3,5 giây)


6

Đây là một lớp Toast tùy chỉnh mà tôi đã thực hiện bằng cách sử dụng đoạn mã trên:

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

Nếu bạn cần một Toast dài, có một sự thay thế thực tế, nhưng nó yêu cầu người dùng của bạn nhấp vào nút OK để làm cho nó biến mất. Bạn có thể sử dụng AlertDialog như thế này:

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

Nếu bạn có một tin nhắn dài, rất có thể, bạn không biết người dùng sẽ mất bao lâu để đọc tin nhắn, vì vậy đôi khi bạn nên yêu cầu người dùng nhấp vào nút OK để tiếp tục. Trong trường hợp của tôi, tôi sử dụng kỹ thuật này khi người dùng nhấp vào biểu tượng trợ giúp.


1
Điều này là thông minh, nhưng không thể được thực hiện trong một cái gì đó như Service, nơi không có UI.
mike47

@mikejeep Trên thực tế, gần đây tôi đã thấy một ví dụ của Google, hiển thị hộp thoại không có hoạt động: developer.android.com/samples/AppShortype/index.html
nhà phát triển Android

5

Như những người khác đã đề cập, Android Toasts có thể là LENGTH_LONG hoặc LENGTH_SHORT. Không có cách nào khác, bạn cũng không nên theo bất kỳ 'hack' nào được đăng.

Mục đích của Toasts là hiển thị thông tin "không thiết yếu" và do hiệu ứng kéo dài của chúng, các tin nhắn có thể được đưa ra khỏi bối cảnh nếu thời lượng của chúng vượt quá một ngưỡng nhất định. Nếu Toasts stock đã được sửa đổi để chúng có thể hiển thị lâu hơn LENGTH_LONG, thông báo sẽ tồn tại trên màn hình cho đến khi quá trình của ứng dụng bị chấm dứt khi các chế độ xem bánh mì được thêm vào WindowManager chứ không phải Viewgroup trong ứng dụng của bạn. Tôi sẽ cho rằng đây là lý do tại sao nó được mã hóa cứng.

Nếu bạn thực sự cần hiển thị thông báo kiểu bánh mì nướng dài hơn ba giây rưỡi, tôi khuyên bạn nên xây dựng chế độ xem được đính kèm với nội dung của Hoạt động, theo cách đó nó sẽ biến mất khi người dùng thoát khỏi ứng dụng. Thư viện SuperToasts của tôi xử lý vấn đề này và nhiều vấn đề khác, vui lòng sử dụng nó! Bạn rất có thể sẽ quan tâm đến việc sử dụng SuperActivityToasts


4

Đơn giản chỉ cần sử dụng SuperToast để làm bánh mì nướng thanh lịch trong mọi tình huống. Làm cho bánh mì nướng của bạn đầy màu sắc . Chỉnh sửa màu phông chữ của bạn và kích thước của nó . Hy vọng nó sẽ là tất cả trong một cho bạn.



3

Đây là một phương pháp rất đơn giản giúp tôi làm việc:

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

Thời lượng của LENGTH_SHORT là 2 giây và LENGTH_LONG là 3,5 giây, Ở đây, thông báo bánh mì nướng sẽ được hiển thị trong 6 giây vì nó được đặt trong một vòng lặp for. Nhưng một nhược điểm của phương pháp này là sau mỗi 2 giây, một hiệu ứng mờ dần có thể xuất hiện. nhưng nó không đáng chú ý lắm Hy vọng nó hữu ích


2

Người dùng không thể xác định thời lượng của Toast. bởi vì hàm calendarTimeoutLocked () của NotificationManagerService không sử dụng thời lượng trường. mã nguồn là như sau.

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

Sử dụng Crouton, nó là một thư viện Toast rất linh hoạt.

Bánh mì

Bạn có thể sử dụng nó giống như bánh mì nướng:

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

hoặc thậm chí bạn có thể đi sâu hơn một chút và tùy chỉnh nó nhiều hơn, như đặt thời gian thành vô hạn! ví dụ ở đây tôi muốn hiển thị một thông báo bánh mì nướng cho đến khi người dùng nhận ra nó bằng cách nhấp vào nó.

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

Bố trí Custome sẽ được thổi phồng cho bánh mì nướng.

<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

Thời lượng bánh mì nướng có thể được hack bằng cách sử dụng một luồng chạy bánh mì nướng độc quyền. Công việc này (chạy bánh mì nướng trong 10 giây, sửa đổi giấc ngủctr theo ý thích của bạn):

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

Một bánh mì nướng với nền tùy chỉnh và chế độ xem đã lừa tôi. Tôi đã thử nghiệm nó trong máy tính bảng nexus 7 và tôi nhận thấy không có hoạt hình mờ dần trong quá trình lặp. Đây là việc thực hiện:

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

}

Đây là textview tùy chỉnh được sử dụng trong mã trên:

<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 đang làm cho bánh mì nướng của tôi có góc tròn như trong phiên bản kitkat. Bạn có thể thêm các khung nhìn khác trong tệp. Mọi sửa đổi để cải thiện và nhận xét đều được khuyến khích khi tôi dự định thực hiện điều này trong ứng dụng trực tiếp của mình.


1

Lên lịch đếm ngược cho đến một thời điểm trong tương lai, với các thông báo thường xuyên trên các khoảng thời gian trên đường đi. Ví dụ về hiển thị đếm ngược 30 giây trong trường văn bản:

     CountDownTimer mới (30000, 1000) {

     void void onTick (millisUntilFinished dài) {
         mTextField.setText ("giây còn lại:" + millisUntilFinished / 1000);
     }

     khoảng trống công khai trênFinish () {
         mTextField.setText ("xong!");
     }
  }.khởi đầu();



1

Văn bản này sẽ biến mất trong 5 giây.

    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

Chỉnh sửa: Như Itai Spector trong bình luận cho biết nó sẽ được hiển thị khoảng 3,5 giây, vì vậy hãy sử dụng mã này:

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

Tôi nghĩ rằng văn bản này sẽ biến mất sau 3,5 giây
Itai Spector

@ItaiSpector: Vui lòng kiểm tra Mã mới của tôi.
Alireza Noorali

1

Không, và hầu hết / tất cả các bản hack được liệt kê ở đây không còn hoạt động trong Android 9. Nhưng có một giải pháp tốt hơn nhiều: nếu bạn cần nhắn tin, hãy sử dụng hộp thoại.

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

Mặc dù đây không phải là câu trả lời mà Hussein đang tìm kiếm, nhưng đây là một lựa chọn tốt hơn tất cả những 'hack' đó!
Daniel EK van der Nikol

0

Một cách tiếp cận rất đơn giản để tạo một tin nhắn dài hơn một chút như sau:

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

Lưu ý rằng ví dụ trên loại bỏ tùy chọn LENGTH_SHORT để giữ cho ví dụ đơn giản.

Nói chung, bạn sẽ không muốn sử dụng tin nhắn Toast để hiển thị các tin nhắn trong khoảng thời gian rất dài, vì đó không phải là mục đích dự định của lớp Toast. Nhưng đôi khi, lượng văn bản bạn cần hiển thị có thể khiến người dùng mất nhiều hơn 3,5 giây để đọc và trong trường hợp đó, một khoảng thời gian kéo dài (ví dụ, đến 6,5 giây, như được hiển thị ở trên), IMO, có thể hữu ích và phù hợp với mục đích sử dụng.


0

Đặt bánh mì nướng cho một khoảng thời gian cụ thể tính bằng mili giây:

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

Sau khi thất bại với mọi giải pháp khả dụng, cuối cùng tôi đã có cách giải quyết bằng cách sử dụng đệ quy.

Mã số:

//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
Hầu hết các giải pháp cho câu hỏi này liên quan đến việc gọi "hiển thị" liên tục để giữ cho bánh mì nướng được hiển thị đang làm như vậy với cùng một ví dụ bánh mì nướng, trong khi bạn thực sự tạo ra một phiên bản bánh mì nướng mới mỗi giây và chỉ định rằng mỗi cái sẽ được hiển thị cho LONG thời lượng (thông thường 3,5 giây). Điều này không chỉ không hiệu quả vì bạn tiếp tục tạo thêm các thể hiện đối tượng, mà Android còn đưa các thông điệp nướng bánh vào hàng đợi để hiển thị lần lượt từng khoảng thời gian được chỉ định. Vì vậy, nếu bạn gọi nó với thời lượng 5, thông báo sẽ thực sự hiển thị trong 17,5 giây.
Niall

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

Một giải pháp rất đơn giản cho câu hỏi. Hai hoặc ba lần trong số họ sẽ làm cho Toast tồn tại lâu hơn. Đó là cách duy nhất xung quanh.


Mặc dù âm thanh hack, nhưng đánh giá cao suy nghĩ!
Sony Kadavan

tại sao lại đánh giá thấp một giải pháp tương tự được đề cập bởi @Arturo sử dụng cùng một mẹo với vòng lặp for
tồi tàn

Cách tiếp cận này làm việc cho tôi. Sẽ là tốt để nghe từ những người xuống bầu tại sao họ làm như vậy.
Christopher Mills

-8

Bạn có thể đặt thời gian mong muốn tính bằng mili giây trong Toast.makeText();phương pháp như sau:

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

1
Câu trả lời là ĐÚNG! API đã được mở rộng tại một số thời điểm để cho phép sử dụng một giá trị khác ngoài LENGTH_LONG hoặc LENGTH_SHORT. Tôi
RTS

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.