Objective
Believe that some people have used MIUI, will find millet toast and Android traditional toast special is not the same, he will fly from the bottom up, and then fade away. It looks pretty good, but custom animations are not supported for Android native toast. So how did this effect come true? Here's to tell you ....
Analysis
If the park friends have read my other blog "Android: Profiling source, the control of the toast display", you will know that the native toast is infate out a view instance, and then load it onto the WindowManager to achieve the display effect. Many of us know that WindowManager is able to implement a view that hovers over all application interfaces without the focus, which is the core function that toast needs to have: the simplicity of the message is passed to the user without additional action; Our effect is also based on WindowManager.
Body
We need to customize a toast class, but we don't need to inherit the toast. Now that you're copying a custom toast, we'll start with the toast entry to refine this custom toast.
To create a new class
View Sourceprint?
1.
public
class
MiuiToast {
2.
3.
}
You don't have to inherit other classes (except for object ...). )
Start code
We generally use native Toast as direct toast.maketext (this, text, Toast.length_short). Show (); Where maketext This static method returns a toast instance and then calls the Show method to display the toast.
We'll take care of the Maketext method.
View Sourceprint?
1.
public
static
MiuiToast MakeText(Context context, String text,
boolean
showTime) {
2.
MiuiToast result =
new
MiuiToast(context, text, showTime);
3.
return
result;
4.
}
Logic is simply rude, calling the constructor directly to instantiate a Miuitoast object and returning.
The next step is to construct the Miuitoast method.
View Sourceprint?
01.
private
MiuiToast(Context context, String text,
boolean
showTime ){
02.
mShowTime = showTime;
//记录Toast的显示长短类型
03.
mIsShow =
false
;
//记录当前Toast的内容是否已经在显示
04.
mWdm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
05.
//通过Toast实例获取当前android系统的默认Toast的View布局
06.
mToastView = Toast.makeText(context, text, Toast.LENGTH_SHORT).getView();
07.
mTimer =
new
Timer();
08.
//设置布局参数
09.
setParams();
10.
}
In the construction method, more is the initialization of the data, because the set layout parameters are more, so separate a function to
Look at the SetParams () method
View Sourceprint?
01.
private
void
setParams() {
02.
mParams =
new
WindowManager.LayoutParams();
03.
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
04.
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
05.
mParams.format = PixelFormat.TRANSLUCENT;
06.
mParams.windowAnimations = R.style.anim_view;
//设置进入退出动画效果
07.
mParams.type = WindowManager.LayoutParams.TYPE_TOAST;
08.
mParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
09.
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10.
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11.
mParams.gravity = Gravity.CENTER_HORIZONTAL;
12.
mParams.y =
250
;
13.
}
This setting parameter is more of a reference to the type of setting parameters of the native toast in the source code, where we need to be aware that mparams.windowanimations = r.style.anim_view;//setting into the exit animation effect, This is the cornerstone of our MIUI toast animation. Other parameters are nothing to say, Google is so set their toast ha, next we have to look at the animation configuration XML.
What about this r.style.anim_view situation?
View Sourceprint?
1.
<resources>
2.
<style name=
‘anim_view‘
>
3.
<item name=
‘@android:windowEnterAnimation‘
>
@anim
/anim_in</item>
4.
<item name=
‘@android:windowExitAnimation‘
>
@anim
/anim_out</item>
5.
</style>
6.
</resources>
This defines a reference to the animation and exit animation, and the next step is the moment we set the animation effect!
Anim_in:toast's entry animation
View Sourceprint?
01.
<set xmlns:android=
‘http://schemas.android.com/apk/res/android‘
>
02.
<translate
03.
android:fromXDelta=
‘0‘
04.
android:fromYDelta=
‘0‘
05.
android:toXDelta=
‘0‘
06.
android:toYDelta=
‘85‘
07.
android:duration=
‘1‘
08.
/>
09.
<translate
10.
android:fromXDelta=
‘0‘
11.
android:fromYDelta=
‘0‘
12.
android:toXDelta=
‘0‘
13.
android:toYDelta=
‘-105‘
14.
android:duration=
‘350‘
15.
android:fillAfter=
‘true‘
16.
android:interpolator=
‘@android:anim/decelerate_interpolator‘
17.
/>
18.
<alpha
19.
android:fromAlpha=
‘0‘
20.
android:toAlpha=
‘1‘
21.
android:duration=
‘100‘
22.
/>
23.
<translate
24.
android:fromXDelta=
‘0‘
25.
android:fromYDelta=
‘0‘
26.
android:toXDelta=
‘0‘
27.
android:toYDelta=
‘20‘
28.
android:duration=
‘80‘
29.
android:fillAfter=
‘true‘
30.
android:startOffset=
‘350‘
31.
/>
32.
</set>
Here I have configured four animation effects, if you want to re-set the new animation effect, you can change in this area, ha. Roughly speaking, since before and after loading the animation, WindowManager through Mparams to determine the display position of the toast, so the first translate function is to let the toast at the beginning of loading to jump to the location, The other animation is to finish the toast from the bottom of the effect of flying, the period of time using the Android:startoffset control to achieve the effect of animation cohesion.
Anim_out:toast exiting an animation
View Sourceprint?
1.
<set xmlns:android=
‘http://schemas.android.com/apk/res/android‘
>
2.
<alpha
3.
android:fromAlpha=
‘1‘
4.
android:toAlpha=
‘0‘
5.
android:duration=
‘800‘
/>
6.
</set>
A simple fade-out animation ....
Then let's take a look at the show () method.
View Sourceprint?
01.
public
void
show(){
02.
if
(!mIsShow){
//如果Toast没有显示,则开始加载显示
03.
mIsShow =
true
;
04.
mWdm.addView(mToastView, mParams);
//将其加载到windowManager上
05.
mTimer.schedule(
new
TimerTask() {
06.
@Override
07.
public
void
run() {
08.
mWdm.removeView(mToastView);
09.
mIsShow =
false
;
10.
}
11.
}, (
long
)(mShowTime ?
3500
:
2000
));
12.
}
13.
}
In the Show method we will judge Misshow whether the current toast is already displayed, and if it is showing we have no reason to believe that we would be so sb. To show him again.
Mwdm.addview (Mtoastview, mparams); Loads the view onto the WindowManager, achieves a similar suspension, starts the timer and removes it after a specified time, and the whole logic is like this.
Because--toast! It's so simple!
Give us a peek.
Android App series: Imitation MIUI toast animation effect implementation