Understanding layout

One of the most significant aspects of creating your UI and designing your screens is understanding layout. In Android, screen layout is defined in terms of ViewGroup and LayoutParams objects. ViewGroup is a View that contains other views (has children) and also defines and provides access to the layout.

On every screen all the views are placed in a hierarchical tree, so every element has children, and somewhere at the root is a ViewGroup. All the views on the screen support a host of attributes that pertain to background color, color, and so on. We touched on many of these attributes in section 3.2.2 when we discussed the methods on the View class. Dimensions—width and height—and other properties such as relative or absolute placement and margins are based on the LayoutParams a view requests and what the parent—based on its type, its own dimensions, and the dimensions of all of its children—can accommodate.

The main ViewGroup classes are shown in the class diagram you saw in figure 3.4. The diagram in figure 3.6 expands on this class structure to show the specific LayoutParams inner classes of the view groups and layout properties each type provides.

As figure 3.6 shows, the base ViewGroup.LayoutParams class are height and width. From there an AbsoluteLayout type with AbsoluteLayout.LayoutParams allows you to specify the exact X and Y coordinates of the child View objects placed within.

As an alternative to absolute layout, you can use the FrameLayout, LinearLayout, and RelativeLayout subtypes, which all support variations of LayoutParams that are derived from ViewGroup.MarginLayoutParams. A FrameLayout is intended to simply frame one child element, such as an image. A FrameLayout does support multiple children, but all the items are pinned to the top left—meaning they will overlap each other in a stack. A LinearLayout aligns child elements in either a horizontal or a vertical line. Recall that we used a LinearLayout in code in our ReviewListView in listing 3.5. There we created our View and its LayoutParams directly in code. And, in our previous Activity examples, we used a RelativeLayout in our XML layout files that was inflated into our code (again, we will cover XML resources in detail in section 3.3). A RelativeLayout specifies child elements relative to each other (above, below, toLeftOf, and so on).

ViewGroup

ViewGroup.LayoutParams height width

ViewGroup.MarginLayoutParams marginBottom

AbsoluteLayout

AbsoluteLayout.LayoutParams x (position) y (position)

ViewGroup.MarginLayoutParams marginBottom marginLeft marginRight marginTop marginLeft marginRight marginTop

FrameLayout

AbsoluteLayout

FrameLayout.LayoutParams gravity

AbsoluteLayout.LayoutParams x (position) y (position)

LinearLayout

LinearLayout.LayoutParams gravity weight

RelativeLayout

RelativeLayout.LayoutParams above below alignLeft alignRight toLeftOf toRightOf centerHorizontal centerVertical

Figure 3.6 Common ViewGroup classes with LayoutParams and properties provided

So the container is a ViewGroup, and a ViewGroup supports a particular type of Lay-outParams. Child View elements are then added to the container and must fit into the layout specified by their parents. A key concept to grasp is that even though a child View has to lay itself out based on its parents' LayoutParams, it can also specify a different layout for its own children. This design creates a very flexible palette upon which you can constructjust about any type of screen you desire.

For each dimension of the layout a view needs to provide, based on the LayoutParams of its parents, it specifies one of three values:

The FILL_PARENT constant means take up as much space in that dimension as the parent does (subtracting padding). WRAP_CONTENT means take up only as much space as is needed for the content within (adding padding). A child View therefore requests a size, and the parent makes a decision. In this case, unlike what happens sometimes with actual kids, the children have to listen—they have no choice, and they can't talk back.

Child elements do keep track of what size they initially asked to be, in case layout is recalculated when things are added or removed, but they cannot force a particular size. Because of this View elements have two sets of dimensions, the size and width they want to take up (getMeasuredWidth() and getMeasuredHeight()) and the actual size they end up after a parent's decision (getWidth() and getHeight()).

Layout takes place in a two-step process: first measurements are taken, using the LayoutParams, then items are placed on the screen. Components are drawn to the screen in the order they are found in the layout tree: parents first, then children (parents end up behind children, if they overlap in positioning).

Layout is a big part of understanding screen design with Android. Along with placing your View elements on the screen, you need to have a good grasp of focus and event handling in order to build effective applications.

0 0

Post a comment