Android Toast advanced-custom Toast
In the previous blog of the advanced goal, we learned the source code of Toast and the whole process from display to disappearance of Toast. Link: Android Toast source code analysis. As the saying goes, it's a good practice. The source code of Toast is not used to demonstrate the technology, but to understand the Toast principle, so as to truly solve our problem. Next I will mention the real issues related to Toast that may be encountered in the two businesses. Let's take a look at how to solve these problems after learning the Toast source code. Two problems are: How to customize the Toast display time. How to modify the Toast animation. Next, we will explain how to solve the real problems encountered in these two businesses after reading the Toast source code.
By studying the Toast source code, we know that Toast display and disappearance are implemented by icationicationmanagerservice by calling the show and hide methods of the TN class, the length of Toast display time is related to the delay time when Handler sends messages. The source code is as follows:
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); }
Previously, I also mentioned in the Toast source code that the Toast desktop display time can only be 2 s and 3.5 s. The key is that the delay time of the long delay variable can only be 2 s and 3.5 s. Therefore, if you are a developer of the Android operating system, you can directly modify the icationicationmanagerservice class code of the Android Framework layer and change LONG_DELAY and SHORT_DELAY to the desired time interval. However, this practice has obvious drawbacks. First, you may be just a small application-layer development engineer who can only change the application-layer code. Second, even if icationicationmanagerservice is modified, only the LONG_DELAY and SHORT_DELAY variables can be modified, and the display time cannot be modified at will. What should we do when there are so many drawbacks? The answer is also very simple. Like the Toast source code, we can create a wheel and customize a Toast. In this way, we can certainly control the display time of Toast. We know from the source code that Toast is displayed based on WindowManager, so we can define a custom Toast. The source code is as follows:
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; } }}}
The principle is very simple. Use WindowManager to display Toast, and then use Handler to send delayed messages to control WindowManager and then delete Toast. Note: here, the Handler of the custom Toast is also the Logoff of the main thread. When the sub-thread calls the custom Toast, the loast. prepare () and loast. loop () codes need to be added.
Modifying the Toast rendering animation Android native Toast class does not provide an interface for us to set the animation effect. The animation effect of each Android native Toast is defined in the TN class com. android. internal. r. style. animation_Toast. Therefore, if you want to modify the animation effect of Android Toast, you still need to upload a Toast and modify params. content of the windowAnimations variable. Next, let's first customize an animation effect. Define a new style in the style. xml file. The xml content is as follows:
Then add two animation effect files under the anim Folder: enter_anim.xml and exit_anim.xml. Enter_anim.xml:
Exit_anim.xml:
Then, modify the params. windowAnimations variable in the Custom Toast code:
params.windowAnimations = com.example.photocrop.R.style.custom_toast_anim_view;