Analysis of setcontentview () method in Android dialog

summary

Dialog is an excellent tool in Android. When using dialog, we usually customize the content layout to be displayed. Dialog comes with three methods to support custom content layout.

The internal implementation principles of these three methods are the same, but their encapsulation depth is different. The three methods can be said to take care of developers with different customization depths.

Setcontentview() process

View the source code of dialog directly, as shown in Figure 1 below.

[figure 1]

In the above figure, mwindow is defined in the dialog class as follows:

So where did it come from? As shown in Figure 2 below.

[figure 2]

As shown in Figure 2 above, the value of this mwindow is also determined when constructing the dialog object. It is provided by policymanager. Then follow the system code.

The makenewwindow (context) method is implemented as follows:

We have to keep following.

At this point, it seems that we have almost seen the end. It turns out that the setcontentview we call is implemented in this phonewindow class. Follow up.

setContentView(int)

The code implementation of this method is shown in Figure 3 below.

[figure 3]

At first glance, the whole implementation process is simple and clear. The layout parameters we passed in are finally loaded into the mcontentparent shown in the figure above. This mcontentparent is a ViewGroup class object.

In the code shown in the above figure, the null judgment is made in line 367. It can be seen that the creation of the instance of this object is related to the installdecor () method. The implementation of this method is complex. Here we only look at the instantiation process of mcontentparent.

[figure 4]

The implementation of this generatelayout () method is complicated. We don't have to understand every line of code. Just know how to create the mcontentparent object inside it

Finally, the contentparent will be returned as the result. Then go back to figure 3. At the code shown in the figure, line 378 completes the operation of loading the layout we passed in into the system container.

Setcontentview (view) and setcontentview (view, ViewGroup. Layoutparams)

This method is more flexible to set the content layout. It is generally used for layouts that require special operations in Java code. Such as setting monitoring, etc. The specific implementation code is shown in Figure 5 below.

[figure 5]

This code is nothing special. Its purpose has been clearly expressed in the code, so I won't repeat it.

Setcontentview (view) failed to set the layout size

When using setcontentview (int), you can directly set the size of the layout by specifying the width and height in the root container of the layout. It should be noted here that I mean directly specifying the width and height pixels in the root view, which can control the size of the layout. If directly set to match_ Parent, then its effect is equivalent to wrap_ CONTENT。 Why is this the result? I didn't delve into the reason, but I guess (and I didn't confirm it later) that it has something to do with the process of resizing the whole view after mcontentparent loaded the layout. Let's turn to the code of ViewGroup. In ViewGroup, there is a piece of code as shown in Figure 6 below.

[figure 6]

For a ViewGroup and its subclasses, its measurespec is either actual or at_ Most, I can't remember the specific relationship between the heads here. But the code shown in Figure 6 is also very straightforward. For match_ Parent, it does follow wrap_ Content. This explains the "puzzling" situation mentioned above. Although this is only my guess, I guess it's eight or nine.

When setcontentview (view) is used, wrap is used regardless of the width and height of the root container in the layout_ Content way to go. Why? Let's go back to the implementation of this method in the code shown in Figure 5. It can be found that phonewindow gives a default viewgroup.layoutparams object. And the values of width and height are unbiased, which is exactly match_ PARENT。 Therefore, when using this method, no matter how the width and height of the root container are set in the layout, it shows the effect of adapting the layout according to the size of the content. Therefore, if you want to control the size of the dialog layout, you'd better honestly build a layoutparams object with a specified width and height value to the phonewindow object. Don't expect others to wipe your ass~~

So, here, let's briefly explore how setcontentview (int) can directly set the size. Let's go back to figure 3 and look at the implementation code of this method, line 378. When mapping XML, the second parameter is passed directly to mcontentparent. When we usually use the mapping layout function, it is reasonable to pass a null directly. In other words, maybe we seldom pay attention to this parameter. Let's transfer to layoutinflator.

import android.view.LayoutInflater;

The code of the inflate () method is still quite long. We won't post it in detail here. We'll only select representative ones.

Clear enough. Here, layouteinflator actively parses all attributes when mapping XML layouts. Of course, the properties of the outer container will be included. Then, a layoutparams object is generated according to the analysis results. Finally, the content layout to be combined with the immediately created layoutparams object is added to the mcontentparent container. In fact, it is equivalent to calling the setcontentview (view, layoutparams) method. So I said at the beginning of the article that the three methods of setting the content layout of dialog are essentially the same, but their encapsulation depth is different.

Set the background of dialog to be completely transparent

Dialog has a gray background by default. Firstly, the background is huge and ugly. Secondly, the existence of the background also affects our customization of the dialog UI.

In activity, you can pass in a style of a dialog without background to the constructor when creating a dialog to construct a dialog without gray background. You can also control the background color of the dialog box to be transparent through Java code. You can also show () dialog box first, and then give it setcontentview () to achieve the purpose of dialog box without background color.

1. By style

2. Control through Java code

The so-called background is actually the background of phonewindow. We only need to set the background of phonewindow to be transparent to achieve the desired results.

3. Display the dialog box before setting the layout

This method only works in activity.

As for why there is no effect in service, I suspect it is due to the fact that if you want to pop up a dialog box in service, you can only set it as a system level dialog box, which requires an additional piece of code. But its specific principle has not been studied.

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYstem_ALERT);

In service. The purpose of background transparency can only be achieved through the above methods 1 and 2.

The above is the whole content of this article. I hope the content of this article can bring some help to your study or work. At the same time, I also hope to support a lot of programming tips!

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
分享
二维码
< <上一篇
下一篇>>