編輯:關於Android編程
目錄結構 前言 進階目標 控制Toast顯示時間 修改Toast動畫效果
CSDN竟然支持Markdown語法了,對我這種懶得自己搭建博客的人確實是好消息,再復習Markdown語法的同時,我准備把之前寫的一篇Android Toast進階用Markdown語法重寫一遍。
上一篇博客我們學習了Toast的源碼,了解了Toast從顯示到消失的全過程,學習鏈接:Android Toast源碼分析。俗話說的好,學以致用。我們學習Toast源碼不是用來炫技的,而是用來了解Toast原理,從而真正解決我們問題的。下面我就提兩個業務中可能遇到的跟Toast相關的真實問題,看看學習了Toast源碼之後,該如何解決這些問題。兩個問題是:
1. 如何自定義Toast的顯示時間。
2. 如何修改Toast的出現動畫。
接下來,我們分別講解閱讀了Toast源碼之後,如何解決這兩個業務中真實遇到的問題。
通過對Toast源碼的學習,我們知道Toast的顯示和消失是NotificationManagerService調用TN類的show和hide方法實現的,而Toast的顯示時間的長短則跟Handler發送消息的延遲時間相關。具體源碼如下:
private void scheduleTimeoutLocked(ToastRecord r)
{
mHandler.removeCallbacksAndMessages(r);
Message m = Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
long delay = r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY;
mHandler.sendMessageDelayed(m, delay);
}
之前Toast源碼裡也講過,為什麼Toast的桌面顯示時間只能是2s和3.5s,關鍵就是在於long delay變量的延遲時間只能是2s和3.5s。因此,如果你是Android操作系統的開發人員,你可以直接修改Android Framework層的NotificationManagerService類代碼,將LONG_DELAY和SHORT_DELAY改成你想要的時間間隔。但是,這種做法的弊端很明顯。首先,你可能只是一個小小的應用層開發工程師,只能改動應用層代碼。其次,就算修改NotificationManagerService,也只能改動LONG_DELAY和SHORT_DELAY兩個變量,無法做到隨意修改顯示時間。
弊端這麼多,那我們應用層開發工程師該怎麼辦呢?答案也很簡單,仿照Toast源碼,我們自己造個輪子,自定義一個Toast,這樣我們肯定就可以控制Toast的顯示時間了。通過源碼我們知道,Toast是基於WindowManager來顯示的,那我們完全可以撸一個自定義Toast出來,源碼如下:
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
public class ToastCustom {
private static final int MESSAGE_TIMEOUT = 2;
private WindowManager wdm;
private double time;
private View mView;
private WindowManager.LayoutParams params;
private WorkerHandler mHandler;
private ToastCustom(Context context, String text, double time) {
wdm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mHandler = new WorkerHandler();
Toast toast = Toast.makeText(context, text, Toast.LENGTH_LONG);
mView = toast.getView();
params = new WindowManager.LayoutParams();
params.height = WindowManager.LayoutParams.WRAP_CONTENT;
params.width = WindowManager.LayoutParams.WRAP_CONTENT;
params.format = PixelFormat.TRANSLUCENT;
params.windowAnimations = toast.getView().getAnimation().INFINITE;
params.type = WindowManager.LayoutParams.TYPE_TOAST;
params.setTitle("Toast");
params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
this.time = time;
}
public static ToastCustom makeText(Context context, String text, double time) {
ToastCustom toastCustom = new ToastCustom(context, text, time);
return toastCustom;
}
public void show() {
wdm.addView(mView, params);
mHandler.sendEmptyMessageDelayed(MESSAGE_TIMEOUT, (long) (time * 1000));
}
public void cancel() {
wdm.removeView(mView);
}
private class WorkerHandler extends Handler {
@Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case MESSAGE_TIMEOUT:
cancel();
break;
}
}
}
}
原理很簡單,利用WindowManager來顯示Toast,然後利用Handler機制發送延遲消息控制WindowManager再將Toast刪除。需要注意一點:這裡自定義Toast的Handler用的也是主線程的Looper,子線程調用該自定義Toast需要增加Looper.prepare()和Looper.loop()代碼。
Android原生的Toast類並沒有提供給我們設置動畫效果的接口,每個Android原生的Toast的動畫效果都是在TN類中定義好的com.android.internal.R.style.Animation_Toast,因此,如果你想要修改Android?Toast的動畫效果,還是需要自己撸一個Toast,修改一下params.windowAnimations變量的內容即可。接下來,讓我們先自定義一個動畫效果。在style.xml文件中定義一個新的style,xml內容如下:
然後在anim文件夾下面增加兩個動畫效果文件,分別為enter_anim.xml和exit_anim.xml。
enter_anim.xml
exit_anim.xml
然後,修改一下自定義Toast代碼中的params.windowAnimations變量即可:
params.windowAnimations = com.example.photocrop.R.style.custom_toast_anim_view;
前言由於大部分android初級教程都沒教怎麼選擇時間,初學者碰到這種難免會有些不知所措,難道要讓用戶自己輸入日期時間?先不說用戶體驗不好,處理用戶輸入各式各樣的日期格式
圖片輪播Banner現在算是比較常見的功能了,可以用來循環播放廣告或者是熱門內容在這裡我利用ViewPager模擬實現了Banner的功能,效果圖如下:可以看到,在剛打開
GlideGlide是一個高效、開源、 Android設備上的媒體管理框架,它遵循BSD、MIT以及Apache 2.0協議發布。Glide具有獲取、解碼和展示視頻劇照、
本文實例講述了Android編程實現ImageView圖片拋物線動畫效果的方法。分享給大家供大家參考,具體如下:想實現拋物線動畫,必須知道拋物線的方程,這時候數學其作用了