Has just sent a large version, finally have the time to summarize the technical point, today is to summarize the last version used floating window, similar to WeChat public post effect, can drag can click and drag the future according to the position of the drag of different floating window images, an automatic suction effect, or so the app is not in at the front desk automatically hidden. It has been successfully launched and many problems have been solved. There are no major problems on the line. Today, I want to tell you my method of using the suspension window and the pits in it. I hope it can be helpful to you. We can also discuss with you if there is any problem.



At the beginning, the demand for suspension Windows was also a little empty, because I had never done this before. I only heard about this pit, but I found it was a real pit when I finished it. Without further ado, let’s get straight to the point. Let’s start with my research on this need. When encountering unfulfilled requirements, I habituously search for third-party libraries related to suspension Windows on Github, hoping to stand on the shoulders of giants. As a result, I found a third-party Git library: github.com/yhaolpz/Flo… I downloaded the demo and ran it again, and found it was not bad. It supports sliding events and clicking events, can set the size, and can set the display and hiding of the suspension window. In my heart, I was ready to carry it to my own project, but when I just wanted to move it, I found something was wrong. Our project applied for permission when it was needed, rather than opening the APP and applying for permission and displaying it. So I a disorderly change, as a result of this set of do not understand, change to find more and more disorderly bug, mentality has collapsed. At this time, I suddenly had a flash of inspiration, so I first went to the issue to find out if anyone had encountered the same problem, and sure enough, I found it. The same problem has been solved, the code has been forked and modified. The git library is: github.com/baneyue/Flo… Thank you very much for your efforts. Standing on the shoulders of giants is such a wonderful feeling. I also want to create more technical blogs to share with others, because everyone’s technical needs are not the same, and different application scenarios will lead to the same bugs.

Second, there is no mature official library to do this, which leads to more or less different problems for many developers. Moreover, the suspension window is window, and the API provided by Google itself is difficult to use, for example, it can only add but not replace. In addition, multiple add will lead to crash, which is a weird and embarrassing design for developers. Finished the work or have to do their own work, here to introduce a third party suspension window code, the code is relatively simple, I may be a post you can understand.

Suspension window key code interpretation

1. How do I apply for permission

Let’s start with a static application

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />Copy the code

Then, in order to be compatible with high API, dynamic permission application needs to be carried out, which needs to be differentiated by API version and vendor. Use TYPE_APPLICATION_OVERLAY if the version is larger than 26, otherwise use TYPE_PHONE. Secondly, before 6.0, there is no need to apply dynamically for suspension window permission, but Xiaomi is a special case, and the application method of different versions of Xiaomi may be different. The application method above 6.0 is the same as that of other mobile phones, but it is different below 6.0



Miui 6.0 has the following application permissions

The following application permissions of Xiaomi 6.0 are related to xiaomi MIUI version, as shown in the figure below. MIUI versions need to be distinguished. The specific code is directly used by me from the above third-party library. If necessary, you can go to Github to pull it and use it directly.





The normal application process, that is, the application process of mobile phones above 6.0, is to jump to a blank permission application interface wrapped by itself, and then jump to the suspension window application interface of the system for permission application. No matter whether the user gives permission or not, the current empty page is closed. Due to different systems, the appearance level of the permission application page seen on different mobile phones may be different.





2. How to realize the suspension window can be dragged with fingertips

The idea is very simple: listen on the imageView onTouchListener of the hover window, record the current x and Y positions in the ACTION_DOWN event that you just clicked on, and then obtain the position of the move after each move. This is the most basic operation for customizing a View.



3. How to achieve the top absorption effect of the left and right sides of the suspension window

The idea is also very simple. After listening to the finger lifting movement, judge whether the current position is close to the left or right. If it is close to the left, it will move to the left in the way of position animation, and if it is close to the right, it will move to the right.



4. Core, the method of adding suspension Windows

In accordance with the android official way to add. That is, get the WindowManager of the system, set the parameters, call the addView() method of WindowManager to add. Note that when hiding the hover window, it is best to remove it and add it the next time you need to display it.





Pit spot in a glance, full of dry goods

Adding views more than once will cause a crash

Many people will encounter this. Sometimes, it is impossible to ensure that the flag is added only once. Even if the flag is given, it will be inaccurate due to system reasons. Add a try to the addView method. Add a try to the addView method. Catch catches the exception, the security of no problem.



Oppo R9 (5.1.1) has permissions, but returns no permissions

This code deals with applications for permissions below 6.0. The red part above is the original code, and the green part below is modified. Because oppo gave false permission to hover window every time when it was detected below 6.0, the project would pop up a box and ask the user to give permission every time. Finally, it would be better to directly default to all permissions below OPpo 6.0. Because the fact is also such, besides millet, other brand 6.0 is the following authority.



Pit point 3 how to deal with the hierarchical relationship between input method and suspension window

The suspension window in wechat is under the input method, so the interaction students also require our suspension window to be under the input method. I looked at the WindowManager source code, and I hung window priority TYPE_APPLICATION_OVERLAY. The overlay says it is under the input method, but it actually appears above the input method.



The problem is, all that trouble in the source code for half a day to find is a dark, finally, everything comes to him who waits, I found him, also windowManager is a flag is dedicated to the relationship for floating window and input method, but because before setting, so resulting in the default input method or under the floating window.



Now that the source has been found, it’s easy to set flag_ALt_FOCUSable_im as shown below. Later, I found that there is a post that summarizes flag very well, and it is also recommended to everyone. Students who want to know about other flags can go to see this post: blog.csdn.net/qq_33275597…



How to close the suspension window when exiting app or pressing the home button

There’s no place to set whether or not the hover window is only used within the app, so by default it will display its own hover window on the desktop. For example, displaying floating Windows of other apps in wechat is a terrible experience, and it’s a miracle that users don’t uninstall it for you. In order to solve this problem, the initial implementation was to log all the activities that passed by, increment them by 1 when they were displayed, and decrease them by 1 when the page was suspended. If reduced to the current count of 0, all the pages were closed and the hover window could be hidden.



In fact, there are some problems with this. On some phones, if you press the back button on the home page, it still cannot be hidden. This is a system level compatibility issue. Behind in order to solve this problem, I made a deal with again, by registering registerActivityLifecycleCallbacks monitored app Taiwan before and after the callback, detect if the current page is destroyed, the window should be suspended to hide.



Click the suspension window five times to open multiple pages

If your hover window click opens a page, remember to set the launch mode of the page to “singleTop” or “singleTask” to reuse the same page and avoid the “back to hell” operation.

android:launchMode="singleTop"Copy the code

android:launchMode="singleTask"Copy the code



Summary: Suspension window pit, only those who have actually done it can understand, but fortunately there are a lot of third party code available to CV. However, even CV does not mean that we can rest easy, there will always be other problems with different application scenarios. Here I summarize some of the pits I have encountered, and I will continue to update if there are more pits in the future. I believe that the more pits you step on, the faster you will grow. I also hope that my work experience can help you avoid mistakes, just as I learned from the work of my predecessors.


Demo address: github.com/dongrong-fu…