每个布局文件必须包含一个根元素,它必须是一个View或ViewGroup中的对象。一旦你定义的根元素,你可以添加额外的布局对象或小工具的子元素,逐步建立一个视图定义你的布局层次。例如,下面是一个使用一个垂直的LinearLayout保存一个TextView和一个Button一个XML布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a Button" /> </LinearLayout>当你宣布XML布局,保存扩展名为.xml的文件,在你的Android项目的RES/布局/目录中,所以它会正确编译。
加载XML资源
当您编译应用程序时,每个XML布局文件被编译成一个View资源。你应该从你的应用程序代码中加载布局资源,在你的Activity.onCreate()回调的实现。这样做,通过调用的setContentView(),它传递的参考布局资源的形式:R._layout.layout文件名。例如,如果你的XML布局保存为主要_layout.xml,你会加载它为您的活动,像这样:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); }在活动中的onCreate()回调方法由Android框架,当你的活动启动(详情参见关于生命周期的讨论,在活动文档)。
属性
每个视图和一个ViewGroup对象支持他们自己的各种XML属性。一些属性特定于一个View对象(例如,TextView的支持文本大小属性),但是这些属性也继承任何View对象可能扩展此类。一些适用于所有视图对象,因为他们从根View类继承(如id属性)。而且,其他属性被认为是“布局参数”,这是描述View对象的特定布局方向,由对象的父ViewGroup中对象定义的属性。
ID
任何View对象可以有与之关联的整数ID,唯一标识在树中的视图。当应用程序被编译,这个ID被参考为一个整数,但ID通常分配布局XML文件作为字符串中,在id属性。这是一个XML属性适用于所有视图对象(由视图类中定义),你会经常使用它。语法一个ID,一个XML标签里面:
android:id="@+id/my_button"
该符号(@)在字符串的开头表示XML解析器应该解析和扩展ID字符串的其余部分,将其识别为一个ID资源。的加号(+)指这是必须创建并添加到我们的资源(在R.java文件)的新的资源名。有一些是由Android框架提供的其他标识资源。当引用一个Android资源ID,你不需要加符号,但必须加上Android包名称空间,就像这样:
android:id="@android:id/empty"有了Android包名称空间,我们现在引用的android.R资源类,而不是本地资源类的ID。
<Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/>然后创建视图对象的实例,并从布局(通常在OnCreate()方法)捕捉到它:
Button myButton = (Button) findViewById(R.id.my_button);
创建RelativeLayout的时候定义的ID为视图对象是很重要的。在一个相对布局,同级次可以定义它们的布局相对于另一同级视图,这是由独特的ID引用。
一个ID不必在整个树的唯一的,但它应该是你正在寻找树的部分中是唯一的(这往往会对整个树,因此最好在可能的情况是完全独一无二的)。
布局参数
命名布局一些XML布局属性定义布局参数是适合于它所在的ViewGroup中查看。
每一个ViewGroup类实现扩展ViewGroup.LayoutParams嵌套类。这个子类包含了定义大小和位置的每个子视图,以适合视图组的属性类型。正如你在图1中看到,父视图组定义布局参数为每个子视图(包括子视图组)。
图1.可视化与每个视图相关联的布局参数的视图层次的。
需要注意的是每一个的LayoutParams子都有自己的语法设置值。每个子元素必须定义的LayoutParams所适合它的父,虽然它也可以定义不同的LayoutParams为它自己的孩子。
所有视图基包括一个宽度和高度(layout_width和layout_height),和每个视图需要定义它们。许多的LayoutParams还包括可选的边距和边框。
你可以精确测量指定的宽度和高度,但你可能不希望经常这样做。更多的时候,你会使用这些常量来设置宽度或高度之一:
WRAP_CONTENT告诉你,以规模本身其内容所需的尺寸。
match_parent(API级别前8名为FILL_PARENT)告诉你的看法变得一样大,它的父视图组将允许。
在一般情况下,指定使用绝对单元的布局的宽度和高度等的像素不被推荐。相反,使用相对测量,如密度无关的像素单元(DP),WRAP_CONTENT,或match_parent,是一种更好的方法,因为它有助于确保您的应用程序将跨越多种设备屏幕尺寸的正常显示。在接受测试类型可用资源文件中定义。
布局位置
的图的几何形状是矩形的。甲视图具有一个位置,表示为一对左,顶部坐标,和两个维度,表示为宽度和高度。的单位的位置和尺寸是象素。
有可能通过调用方法getLeft()和共达()以检索视图的位置。前者返回的左,或X,坐标表示视图的矩形。后者顶返回,或Y,坐标表示视图的矩形。这些方法都返回观点相对的位置,它的父。例如,当getLeft()返回20,这意味着该视图位于20个像素其直接父的左边缘的右边。
此外,一些方便的方法提供,以避免不必要的计算,即GetRight时()和getBottom()。这些方法返回表示视图的矩形的右边缘和下边缘的坐标。例如,调用GetRight时()是类似于以下计算:getLeft()+的getWidth()。
大小,填充和利润
一个视图的大小来表示,其宽度和高度。视图实际拥有2对宽度和高度值。
第一对被称为测量宽度和测量高度。这些尺寸定义视图有多大希望成为其父之内。所测量的尺寸可以通过调用getMeasuredWidth()和getMeasuredHeight()来获得。
第二对被简单地称为宽度和高度,或有时拉伸宽度和绘图高度。这些尺寸限定在屏幕视图的实际尺寸,在拉丝时间及布局之后。这些值可以,但不必,是从所测量的宽度和高度不同。的宽度和高度可以通过调用的getWidth()和getHeight()来获得。
为了测量它的尺寸,以便考虑到它的填充。填充被表示在用于左,上,右和视图的底部部分的像素。填充可以使用的像素的一个特定号码,以抵消视图的内容。例如,2的左填充将由2个像素推视图的内容到左边缘的右边。填充可以使用setPadding(INT,INT,INT,int)方法来设置和查询调用getPaddingLeft(),getPaddingTop(),getPaddingRight()和getPaddingBottom()。
即使一个视图可以定义一个填充,它不提供对利润率任何支持。然而,视图组提供这样的支持。请参阅ViewGroup中和ViewGroup.MarginLayoutParams了解更多信息。
常见的布局
在的ViewGroup类的每个子类提供了一个独特的方式在它显示了你的意见窝。下面是一些内置到Android平台比较常见的布局类型。
注:虽然您可以嵌套在另一个布局的一个或多个布局,获得了这幅你的UI设计,你要努力保持你的布局层次尽可能浅。您的布局绘制速度更快,如果它有较少的嵌套布局(宽视图层次比深视图层次更高)。
建筑平面布置与适配器
当你的布局内容是动态还是不预先确定的,可以使用布局子类适配器视图来填充,享有在运行时的布局。该适配器视图类的子类使用适配器将数据绑定到其布局。适配器的行为作为数据源和所述适配器视图布局-适配器之间的中间人检索数据(从源诸如数组或数据库查询),并且每个条目成可以加入到适配器视图布局的视图变换。
通过适配器支持常见的布局包括:
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);该构造函数的参数是:
ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);要自定义每个项目可以覆盖toString()方法用于在数组中的对象的外观。或者,创建视图的每个项目,它比一个TextView一些其他的(例如,如果你想要一个ImageView的每个数组项),延长一个ArrayAdapter类并覆盖getView()返回要用于每个项目的视图的类型。
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; int[] toViews = {R.id.display_name, R.id.phone_number};当你实例化SimpleCursorAdapter,通过使用每项结果的布局,包含结果,而这两个数组的指针:
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); ListView listView = getListView(); listView.setAdapter(adapter);该SimpleCursorAdapter然后创建使用所提供的布局由列项将每个到相应toViews图的图在光标的每一行。
如果,你的应用程序的生命过程中,您更改由适配器读取的基本数据,你应该叫notifyDataSetChanged()。这将通知所连接的观点,即数据已经8e0改变,它应该刷新本身。
处理点击事件
您可以响应通过实现AdapterView.OnItemClickListener界面单击一个AdapterView上的每一项活动。 例如:
// Create a message handling object as an anonymous class. private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id) { // Do something in response to the click } }; listView.setOnItemClickListener(mMessageClickedHandler);