布局
布局定义了可见的ui结构,比如activity的UI或者app组件。你可以通过下面两种方法来生命布局。
- 在xml文件中声明ui。Android提供了一套直接的xml词汇,对应view的类和子类。比如说组件和布局。
- 在运行时构建布局元素。你的可以通过编程来在运行时创建布局对象,或者改变他们的属性。
Android框架允许你使用一种或者集中方法来创建ui。例如你可以用xml声明app的默认的布局,包括在其中显示的元素和他们的属性。接下来你可以同哦过代码来改变这些显示对象,包括在xml中声明的对象。
使用xml的好处就是可以将显示和控制分离。你的ui描述是独立于app代码之外的,这意味着你可以修改和适配他们,而不必修改代码或者重新编译。比如你可以为不同的屏幕方向,不同的屏幕大小,不同的语言定制不同的xml布局。另外使用xml使得结构更加可视化,这使得发现问题更加容易。这个文档侧重xml的布局定义,如果你对运行时定义感兴趣可以查看ViewGroup或者View的参考。
通常,xml用来生命ui元素的词汇都是和结构的了类名紧密相关的。可以通过xml猜测出对应的类,以及通过属性猜出对应的方法。但是并不是完全相同。
更多不同类型的布局请看Common Layout Objext。在HelloViews的guide中也有介绍。
写一个XML
使用xml词汇你可以快速定义布局文件。如同html文件有很多内部标签。
每个布局文件都必须包含一个根标签,它必须是一个view或者viewgroup对象。定义根标签以后,你可以添加其他的对象或者组件,以子元素的形式,来逐渐构造你自己的层次树。比如下面这个包含了textView和Button的LinearLayout。
<?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/layout/文件夹下面,这样才可以正确编译。
更多的关于xml布局的语法可以在LayoutResource文档中查看。
加载XML资源
当你编译你的工程的时候,每一个xml中的布局都会编译成为一个View资源。你可以在Activity.OnCreate的回调函数的实现中来加载资源。通过调用setContentView函数传入你的布局资源,用R.layout.layou_file_name的形式。例如你的xml布局文件的名字是main_layout.xml那么你可以加载你的Activity用这种方式。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
onCreate回到方法在Activity启动的时候由系统框架进行启动。关于生命周期的更多内容可以参见文档Acitivity。
属性
每个view或者viewgroup在xml中都有特码呢的不同的xml属性。一些对于view对象来说是特有的,比如说textView支持textSize属性,同时属性在继承这些类的对象中也是存在的。一些典型的对于所有view对象都是有的属相,是应为都是从一个view类继承而来的,比如说id属性。同时,一些属性被划分为“layout parameters”,他们是用来描述布局对象的方向的,如同这个对象的母viewgroup中定义的那样。
Id
每一个都可能有一个整形的id,用来唯一的表示树中的view。当app编译的时候,id被引用为一个integer,但是通常其在xml资源中是一个字符串。id属性。这是所有的view对象都有的属性并且使用十分频繁。Id在xml标签中的语法为。
android:id="@+id/my_button"
@标志告诉xml解析器解析后面的更多拓展,并且把他解析为id资源。+符号表示这是一个新的资源名称,必须要被加入到资源中(R.java文件)。还有以下android框架提供的id资源。当引用一个android资源id的时候,你不需要使用+,但是必须要加上android包命名空间。比如:
android:id="@android:id/empty"
使用这里出现的android包命名空间,我们引用的是android.R当中的资源类而不是本地的资源类。
为了创建view并在app中引用他们,一种典型的模式就是:
1. 在资源文件中定义一个id
<Buttonandroid:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text"/>
2. 创建一个资源中对应的对象实例,在资源文件中捕获它。通常是在onCreate方法中。
Button myButton=(Button)
findViewById(R.id.my_button);
当使用relativielayout的时候,为空间生命布局是十分重要的。因为我们需要制定一些view相对于其他view的位置,需要使用id。
Id在整个树上可以不是唯一的,只需要在你搜索的一段树上是唯一的。但是搜索的树通常就是整个树,所有最好是全局唯一的。
布局参数 Layout Parameters
Xml布局属性命名为layout_something的时候,就是几乎是一个确定view在viewgroup当中位置的属性。
每一个viewgroup都实现了一个拓展自ViewGroup.LayoutParms的内部类。子类包含了这些可以确定自布局尺寸和位置的参数,根据于viewgroup。如同你在图1中看到的,viewgroup为每一个子view定义了布局参数(包括子viewgroup)。
注意到每一个LayoutParam子类都有自己的设定值的语法。每一个子元素都必须定义和母view相适合的LayoutParams,尽管它其中可能也为其自己的子view定义了不同的LayoutParms。
所有的viewgroup都包含一个width和height属性(layout_width和layou_height),每一个view都必须定义这两个属性。汗多的LayoutParam中也包含可选的margins和borders属性。
你可以将height和width指定为确定的值,但是你通常都不会这么做。通常你会使用下面的参数来制定高和宽。
-wrap_content告诉你view根据他的内容的需要来限定自己。
-match_parent告诉你的组件在parentview允许的范围内尽可能的大。
通常而言,使用例如像素等的绝对数值类说明高和宽是不推荐的。取而代之的是,使用相对的测量比如说dp(density-independent pixel unite),wrapcontent或者matchparent是更好的方法。因为这保证了你的app在不同设备屏幕型号上都可以恰当地显示。可以接受的测量的类型在 Available Resource文档中进行了定义。
布局位置
view的几何形状是对应的矩形。view是有位置的,使用左和上的一对数值坐标表示,以及宽度和高度两个维度。位置和维度的单位是像素。
可以通过调用getLeft和getTop两个函数来获取view的位置。前者返回view对应 的矩形的左或者x坐标。后者返回对应矩形的上,或者y坐标。这两个方法返回都是相对于父view的位置。例如getLeft方法的返回值为20,着意味着view距离父空间的做边界右方20个像素。
另外,还提供了一下方法来避免不必要的计算,比如说getRight以及getBottom。这些方法返回对应的矩形的右边和底边坐标。例如,调用getRight方法相当于做个了getLeft+getWith的计算。
尺寸,填充和边缘
view的尺寸以宽度和高度表示。一个view实际上有两对width和height值。
第一对的值叫做测量宽和测量高。measured width 和measured height。这些维度定义了view在父view想要占有多大。这两个维度可以通过getMeasuredWidth()和getMeasureHeight()来获取。
第二对简单的叫做width和height。或者叫做drawing width或者drawing height。这些维度定义了view在屏幕上面的真实的尺寸,是在布局以后的绘图时刻的。这些值可能但是不是一定的不同于measured width和measured height。可以使用getWidth和getHeight来获取这两个值。
想要测量它的维度,view需要考虑到他的填充padding。padding以像素的形式表达left,top,right,bottom。padding可以被用来设置view内容的偏移像素数。例如,左padding两个像素将会把view的内容向左边界的右方移动2个像素。可以使用setPadding来设置Padding。可以通过getPeddingLeft,getPaddingTop,getPadingRight,getPaddingBottom来获取。
尽管view可以定义一些填充,但是他不能定义任何 边缘margin的支持。但是,viewgroup提供了一些支持。可以通过viewgroup和viewgroup.MarginLayoutParams来查看更多的消息。
更多关于维度的信息,请看Dimension Values。
典型的布局
viewGroup的每一个子类都提供了一个独特的方法来现实其中的view。下面是一些android平台内置的布局类型。
提示:尽管你可以在一个布局中反之一个或者更多的布局来达到你的ui的目的。但是你最好限制你的层次越少越好。因为更少的内部布局意味着layout的绘制速度更快。(款的布局层次比一个深的布局层次更好。)
线性布局
布局
布局定义了可见的ui结构,比如activity的UI或者app组件。你可以通过下面两种方法来生命布局。
- 在xml文件中声明ui。Android提供了一套直接的xml词汇,对应view的类和子类。比如说组件和布局。
- 在运行时构建布局元素。你的可以通过编程来在运行时创建布局对象,或者改变他们的属性。
Android框架允许你使用一种或者集中方法来创建ui。例如你可以用xml声明app的默认的布局,包括在其中显示的元素和他们的属性。接下来你可以同哦过代码来改变这些显示对象,包括在xml中声明的对象。
使用xml的好处就是可以将显示和控制分离。你的ui描述是独立于app代码之外的,这意味着你可以修改和适配他们,而不必修改代码或者重新编译。比如你可以为不同的屏幕方向,不同的屏幕大小,不同的语言定制不同的xml布局。另外使用xml使得结构更加可视化,这使得发现问题更加容易。这个文档侧重xml的布局定义,如果你对运行时定义感兴趣可以查看ViewGroup或者View的参考。
通常,xml用来生命ui元素的词汇都是和结构的了类名紧密相关的。可以通过xml猜测出对应的类,以及通过属性猜出对应的方法。但是并不是完全相同。
更多不同类型的布局请看Common Layout Objext。在HelloViews的guide中也有介绍。
写一个XML
使用xml词汇你可以快速定义布局文件。如同html文件有很多内部标签。
每个布局文件都必须包含一个根标签,它必须是一个view或者viewgroup对象。定义根标签以后,你可以添加其他的对象或者组件,以子元素的形式,来逐渐构造你自己的层次树。比如下面这个包含了textView和Button的LinearLayout。
<?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/layout/文件夹下面,这样才可以正确编译。
更多的关于xml布局的语法可以在LayoutResource文档中查看。
加载XML资源
当你编译你的工程的时候,每一个xml中的布局都会编译成为一个View资源。你可以在Activity.OnCreate的回调函数的实现中来加载资源。通过调用setContentView函数传入你的布局资源,用R.layout.layou_file_name的形式。例如你的xml布局文件的名字是main_layout.xml那么你可以加载你的Activity用这种方式。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
}
onCreate回到方法在Activity启动的时候由系统框架进行启动。关于生命周期的更多内容可以参见文档Acitivity。
属性
每个view或者viewgroup在xml中都有特码呢的不同的xml属性。一些对于view对象来说是特有的,比如说textView支持textSize属性,同时属性在继承这些类的对象中也是存在的。一些典型的对于所有view对象都是有的属相,是应为都是从一个view类继承而来的,比如说id属性。同时,一些属性被划分为“layout parameters”,他们是用来描述布局对象的方向的,如同这个对象的母viewgroup中定义的那样。
Id
每一个都可能有一个整形的id,用来唯一的表示树中的view。当app编译的时候,id被引用为一个integer,但是通常其在xml资源中是一个字符串。id属性。这是所有的view对象都有的属性并且使用十分频繁。Id在xml标签中的语法为。
android:id="@+id/my_button"
@标志告诉xml解析器解析后面的更多拓展,并且把他解析为id资源。+符号表示这是一个新的资源名称,必须要被加入到资源中(R.java文件)。还有以下android框架提供的id资源。当引用一个android资源id的时候,你不需要使用+,但是必须要加上android包命名空间。比如:
android:id="@android:id/empty"
使用这里出现的android包命名空间,我们引用的是android.R当中的资源类而不是本地的资源类。
为了创建view并在app中引用他们,一种典型的模式就是:
1. 在资源文件中定义一个id
<Buttonandroid:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text"/>
2. 创建一个资源中对应的对象实例,在资源文件中捕获它。通常是在onCreate方法中。
Button myButton=(Button)
findViewById(R.id.my_button);
当使用relativielayout的时候,为空间生命布局是十分重要的。因为我们需要制定一些view相对于其他view的位置,需要使用id。
Id在整个树上可以不是唯一的,只需要在你搜索的一段树上是唯一的。但是搜索的树通常就是整个树,所有最好是全局唯一的。
布局参数 Layout Parameters
Xml布局属性命名为layout_something的时候,就是几乎是一个确定view在viewgroup当中位置的属性。
每一个viewgroup都实现了一个拓展自ViewGroup.LayoutParms的内部类。子类包含了这些可以确定自布局尺寸和位置的参数,根据于viewgroup。如同你在图1中看到的,viewgroup为每一个子view定义了布局参数(包括子viewgroup)。
注意到每一个LayoutParam子类都有自己的设定值的语法。每一个子元素都必须定义和母view相适合的LayoutParams,尽管它其中可能也为其自己的子view定义了不同的LayoutParms。
所有的viewgroup都包含一个width和height属性(layout_width和layou_height),每一个view都必须定义这两个属性。汗多的LayoutParam中也包含可选的margins和borders属性。
你可以将height和width指定为确定的值,但是你通常都不会这么做。通常你会使用下面的参数来制定高和宽。
-wrap_content告诉你view根据他的内容的需要来限定自己。
-match_parent告诉你的组件在parentview允许的范围内尽可能的大。
通常而言,使用例如像素等的绝对数值类说明高和宽是不推荐的。取而代之的是,使用相对的测量比如说dp(density-independent pixel unite),wrapcontent或者matchparent是更好的方法。因为这保证了你的app在不同设备屏幕型号上都可以恰当地显示。可以接受的测量的类型在 Available Resource文档中进行了定义。
吧他的子布局按照水平或者竖直线性排列。如果window的长度大于屏幕的时候会创建一个滚动条。
Linear Layout
一种将子view组织成水平或者垂直的线性关系的布局
Relative Layout
可以让你制定view之间的相互关系,比如说A在B的左边或者A和父控件的上边界对齐
Web View
显示网页
使用适配器建立一个布局
当你的布局的内容是动态的或者不是可以事先准备好的,那么你可以使用AdapterView的子类的布局来在运行时填充布局。通过继承AdaperVied使用一个Adapter来绑定数据和布局。Adapter充当了另一个数据和布局的中间层的角色。从数据源,比如说数组或者数据库查询获取到的消息,来转化每一个实体到AdapterView布局的每一个view中。
使用adper的典型的布局包括:
LIst View
显示一个可以滚动的单栏目列表
Grid View
显示一个包含栏目和行的可以滚动的列表。
使用数据填充adapter view
你可以通过绑定AdapterView对象到一个Adapter的实例来填充一个ListView或者GridView这种的AdapterView。这个Adapter可以从外部数据源获取数据并且创建显示每一个数据实体的view。
android提供了一种adapterview的子类来获取不同的数据并为adapterview创建views。两种典型的adaper是:
ArrayAdapter
当你的数据是一个数组的时候使用这种adpter。默认而言,ArrayAdapter通过调用toString方法在每一个item上,并且防止一个TextView控件来初始化一个新的ArrayAdapter。
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);
这个构造函数的参数是:
- 你的app的context
- 包含为每一个array中string对应的TextView的布局。
-string array
接下来只需要调用你的ListView的setAdapter
ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);
想要定制以每一个项目的外观,你可以重写对象数组的toString方法。或者给每一个item创建了一个TextView以外的view,,比如说给每一个数组的项目创建一个ImageView,通过拓展ArrayAdapter类并重写getView()方法来返回你想给每个项的view。
SimpleCursorAdapter
当你的数据是从Cursor中取出来的时候,就应该使用这种视图。当使用SimpleCursorAdapter的时候,你必须要指定给Cursor中每一行的数据的布局,以及指定Cursor中的需要显示到view上的栏目。比如,你想创建一个人的姓名和电话号的列表,可以通过执行一个查询获得Cursor,其中每一行包括姓名和电话号。接着你需要创建一个string数组指定Cursor中的那一栏你想在布局中现实。以及穿件一个integer数组指定对应的栏目的放入view的。
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; int[] toViews = {R.id.display_name, R.id.phone_number};
当你实例化SimpleCursorAdapter以后,传入每一个项目的布局,包含内容的Cursor,以及上面说的 两个数组。
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); ListView listView = getListView(); listView.setAdapter(adapter);
SimpleCursoeAdapter就会给Cursor中的每一行创建一歌view,使用提供的布局文件,并且使得每一栏目和int数组指定的view对应。
如果在app的存活阶段你改变了已经读出的数据,你应该调用notifyDataSetChanged()方法。这会提醒view这些数据已经变化了,从而触发更新。
点击事件的处理
你可以响应对于AdapterView每一个项目的点击的响应。通过构造AdapterView.OnItemClickListener接口。例如:
// 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);