Выбрать главу
Weight

What happens if we have two widgets that should split the available free space? For example, suppose we have two multi-line fields in a column, and we want them to take up the remaining space in the column after all other widgets have been allocated their space.

To make this work, in addition to setting android:layout_width (for rows) or android:layout_height (for columns) to fill_parent, you must also set android:layout_weight. This property indicates what proportion of the free space should go to that widget. If you set android:layout_weight to be the same value for a pair of widgets (e.g., 1), the free space will be split evenly between them. If you set it to be 1 for one widget and 2 for another widget, the second widget will use up twice the free space that the first widget does, and so on.

Gravity

By default, everything is left-and top-aligned. So if you create a row of widgets via a horizontal LinearLayout, the row will start flush on the left side of the screen.

If that is not what you want, you need to specify a gravity. Using android:layout_gravity on a widget (or calling setGravity() at runtime on the widget’s Java object), you can tell the widget and its container how to align it vis-à-vis the screen.

For a column of widgets, common gravity values are left, center_horizontal, and right for left-aligned, centered, and right-aligned widgets, respectively.

For a row of widgets, the default is for them to be aligned so their text is aligned on the baseline (the invisible line that letters seem to “sit on”), though you may wish to specify a gravity of center_vertical to center the widgets along the row’s vertical midpoint.

Padding

By default, widgets are tightly packed next to each other. If you want to increase the whitespace between widgets, you will want to use the android:padding property (or call setPadding() at runtime on the widget’s Java object).

The padding specifies how much space there is between the boundaries of the widget’s “cell” and the actual widget contents. Padding is analogous to the margins on a word-processing document — the page size might be 8.5”×11”, but 1” margins would leave the actual text to reside within a 6.5”×9” area.

The android:padding property allows you to set the same padding on all four sides of the widget, with the widget’s contents centered within that padded-out area. If you want the padding to differ on different sides, use android:paddingLeft, android:paddingRight, android:paddingTop, and android:paddingBottom (see Figure 7-1).

Figure 7-1. The relationship between a widget, its cell, and the padding values

The value of the padding is a dimension, such as 5px for 5 pixels’ worth of padding.

LinearLayout Example

Let’s look at an example (Containers/Linear) that shows LinearLayout properties set both in the XML layout file and at runtime.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

 xmlns:android="http://schemas.android.com/apk/res/android"

 android:orientation="vertical"

 android:layout_width="fill_parent"

 android:layout_height="fill_parent">

 <RadioGroup android:id="@+id/orientation"

  android:orientation="horizontal"

  android:layout_width="wrap_content"

  android:layout_height="wrap_content"

  android:padding="5px">

  <RadioButton

   android:id="@+id/horizontal"

   android:text="horizontal" />

  <RadioButton

   android:id="@+id/vertical"

   android:text="vertical" />

 </RadioGroup>

 <RadioGroup android:id="@+id/gravity"

  android:orientation="vertical"

  android:layout_width="fill_parent"

  android:layout_height="wrap_content"

  android:padding="5px">

  <RadioButton

   android:id="@+id/left"

   android:text="left" />

  <RadioButton

   android:id="@+id/center"

   android:text="center />

  <RadioButton

   android:id="@+id/right"

   android:text="right" />

 </RadioGroup>

</LinearLayout>

Note that we have a LinearLayout wrapping two RadioGroup sets. RadioGroup is a subclass of LinearLayout, so our example demonstrates nested boxes as if they were all LinearLayout containers.

The top RadioGroup sets up a row (android:orientation="horizontal") of RadioButton widgets. The RadioGroup has 5px of padding on all sides, separating it from the other RadioGroup. The width and height are both set to wrap_content, so the radio buttons will take up only the space that they need.

The bottom RadioGroup is a column (android:orientation="vertical") of three RadioButton widgets. Again, we have 5px of padding on all sides and a “natural” height (android:layout_height="wrap_content"). However, we have set android:layout_width to be fill_parent, meaning the column of radio buttons “claims” the entire width of the screen.

To adjust these settings at runtime based on user input, we need some Java code:

package com.commonsware.android.containers;

import android.app.Activity;

import android.os.Bundle;

import android.view.Gravity;

import android.text.TextWatcher;

import android.widget.LinearLayout;

import android.widget.RadioGroup;

import android.widget.EditText;

public class LinearLayoutDemo extends Activity

 implements RadioGroup.OnCheckedChangeListener {

 RadioGroup orientation;

 RadioGroup gravity;

 @Override

 public void onCreate(Bundle icicle) {

  super.onCreate(icicle);

  setContentView(R.layout.main);

  orientation=(RadioGroup)findViewById(R.id.orientation);

  orientation.setOnCheckedChangeListener(this);

  gravity=(RadioGroup)findViewById(R.id.gravity);