How Android dynamically adds a view and displays it in a specified location. Analysis of binding principle between Android decorview and activity

Recently, when making product requirements, PM asked to add a novice guidance animation on a button to guide users to click. As Rd, I have written the relevant logic. After the self-test is completed, carry out the test and PM review the effect.

After reading it, PM asked a question, can the animation effect range be a little larger? The PM explained that the size of the button itself is not very large, which will lead to insufficient guidance effect and insufficient user desire to click. I thought about it. It seems very reasonable, but can I do it?

The answer is of course. If you simply expand the size of the animation from the current layout, you have to change the original layout. This guide only appeared a few times. In order to guide, I changed the original layout. Personally, I think the change is quite large. unworthy!

Therefore, I want to use the clipchildren attribute to try to make the child view break through the parent layout, but this will also affect other child views and is not easy to locate with the center of the button.

Is there any other scheme that can be realized without changing the original layout as much as possible?

yes , we have!

I believe everyone will be familiar with the following code:

After this code is executed, the activity_ Main this layout is added to the decorview. For the relationship between activity and decorview, you can see this article: analysis of the binding principle between Android decorview and activity

Decorview is the root container of an application window, which is essentially a FrameLayout. Decorview has only one child view, which is a vertical LinearLayout, including two child elements, one is titleview (container of actionbar), the other is contentview (container of window content), which is also a FrameLayout (Android. R.id.content), the commonly used setcontentview is to set its sub view. We will do an article on contentview later.

In addition, for FrameLayout, if no gravity is specified for its child views, they will be stacked in the upper left corner, who is added later and who is on it. In fact, you can also use the following two methods to determine the placement position:

It can be found that these two methods are actually realized by setting the offset of translation. In this way, we can specify the location displayed by the view.

So how to get the position required in PM requirements? If this button is wrap_ Content, the width of the button cannot be determined? Then you can only get the view instance corresponding to the button. Through this instance, you can get the width and height of the button.

After knowing the width and height of the button, combined with the two methods of setting the display position described above, some people should have guessed what to do. If you can know the display position of the button, you can determine the display position of the animation view by calling these two methods. How do I get the display position of the button. Now we have to introduce another method.

Let's take a look at the implementation of getglobalvisiblerect,

Simply put, rect is the result of the combination of the width and height of the view and the offset of the view. I won't tangle with the specific calculation process. Let's talk about the meaning of each number below:

For getlocalvisiblerect:

For getglobalvisiblerect: is its position in the middle of the screen. See the GIF diagram below for details

I believe you will know what to do after you have the above knowledge base. The next step is actual combat.

Objective: to center an ImageView on a textview.

Steps:

After the above four steps, you can add a view to any location.

Final effect:

The following is the specific implementation code. In order to facilitate the reuse of this logic, I encapsulated it a little. The builder mode is adopted. Although my variables are relatively few, there are many attributes that need to be used when the encapsulated function is powerful enough. At this time, we can realize the power of the builder mode. For example, you can set gravity and pass in different targetviews. Now I write it directly to ImageView.

The following is a management class simply encapsulated in builder mode:

In fact, after adding, you have to consider the click of events. For example, you can set a callback. When you click to guide the animation, first hide the animation, and then actively promote the click logic of the button.

In addition, the management class written above has a logic vulnerability of repeatedly adding ImageView. You should check it before each addition to ensure that it will not be added repeatedly.

At this point, the whole knowledge point will be finished.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>