Here is a sample activity that I will use to reproduce the issue. There are two layout files, activity.xml is used as the content of the activity, content.xml is the view inflated in the onCreate() method and added to the acitivity's view hierarchy programmatically.
The resulting app looks like the following:
If you didn't spot the mistake in the above code like me at the first place, then you'll be surprised that the FrameLayout with id my_content and red background does not respect the 200px * 200px dimension specified in the layout file.
It turns out that the LayoutParams of the out most view in the inflated view hierarchy is ignored. And this is for good reason! Since different subclasses of ViewGroup has different attributes in their corresponding LayoutParams, there is no guarantee that the layout parameters specified for the top level view in the layout file makes sense to the parent view, which is unknown, to which it will be added. One might argue that layout_width and layout_height shall be understood by any ViewGroup, but Android just decided to make no special case here and ignore layout_width and layout_height together with other parameters.
If the layout parameters of the out most view is ignore, then what will be used when it is added to a parent view? There has to be some layout parameters in place, right? It turns out that ViewGroup owns the following method:
protected LayoutParams generateDefaultLayoutParams()Which shall be implemented to provide the default layout parameter for a child view. In the case of FrameLayout, which our inflated view hierarchy is added to, this simply set both layout_width and layout_height to MATCH_PARENT, thus the result we see in the above screenshot.
Then how to set the layout parameter other than the default one? There are three ways that I found:
- Set layout parameter explicitly before adding the view hierarchy to its parent. This is not ideal since it's undesirable to hard-code dimensions rather than specify them in xml file.
- Use the version of addView that asks for layout parameters.
- This is the most desirable way. When inflating the view, specify the parent view. The parent view is used to ensure that the layout parameter is applicable to it. For the case of layout_width or layout_height, you don't even need to use the real parent view that the inflated view hierarchy will be added to. In fact, any instance of ViewGroup will do, and one can set the third parameter to false so that the inflated view is not added during the call. This technique is especially useful since sometimes you don't have access to the parent view. One example is when specifying the content view for a PopupWindow. The PopupWindow code adds the content view to its parent, which you don't control.
No comments:
Post a Comment