官方文档地址:http://developer.android.com/guide/topics/ui/declaring-layout.html
PS:API Guides里面的内容不免都简单些,翻译还是很渣,明明知道意思,但按着它的原话翻感觉就是很怪……
一个布局为用户接口定义了视觉上的结构,像activity或app widget的UI界面。你可以使用两种方式来声明布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextViewandroid:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView"/> <Buttonandroid: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文件的语法可以参考Layout Resources文档。 载入XML资源(Load the XML Resource) 当你编译你的应用程序的时候,每一个XML文件会被编译成一个View资源。你应该通过你的程序代码载入布局文件资源,在你的Activity.onCreate()回调里实现。只要调用setContentView()就可以了,传递一个如下格式的布局资源的参数:R.layout.layout_file_name。如果你的XML布局文件保存为main_layout.xml,你应该在Activity中载入它,像这样:
publicvoid onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); }onCreate()回调方法是在Activity启动的时候由Android框架负责调用的(关于生命周期的讨论,请查看Activities文档)。 属性(Attributes) 每个View和ViewGroup对象支持众多的XML属性。一些属性是特定于一个View对象的(比如,TextView有textSize属性),但很多属性都是继承于它们的父类View。所以所有的View对象都是相似的,因为它们都继承于View类(比如所有的view都有id属性)。其它的一些属性像“layout parameters”,这些属性是用于描述View对象里面的具体的布局细节,方向灯,这些都是在父类ViewGroup中定义的。 ID 任何一个View对象都有一个整型的ID与之关联,使之在树中有唯一的标示符。当应用程序被编译的时候,ID将作为一个整型,但在XML布局文件中,ID属性通常都是一个字符串。这对大部分View对象都是通用的,你会经常使用到它,在XML标签里面,ID的语法如下:
android:id="@+id/my_button"在字符串开头的at符号(@)指明XML解析器应该解析ID字符串剩下的部分并标示它为一个ID资源。加号(+)表示这是一个新的资源名,应该被创建并且添加到资源中去(在R.java文件中)。Android框架提供了一些ID资源。当你要引用Android资源ID,你不需要加上加号,但你必须要加上android包的命名空间,像这样:
android:id="@android:id/empty"当我们使用android包命名空间的时候,我们正在使用一个来自android.R资源类的ID,而不是本地的资源类。 为了创建Views,并且能在程序里引用它们,通常是这样的模式: 1.在布局文件中定义一个view/widget,并注册一个唯一的ID:
<Buttonandroid:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/>2.然后创建一个view对象的实例,并从布局中捕获它(通常是在onCreate()方法中):
Button myButton =(Button) findViewById(R.id.my_button);当使用RelativeLayout的时候,为view对象定义ID是非常重要的。在相对布局中,view对象定义它们的布局关系通过其它的view对象,这都必须引用唯一的ID。 在整个树中,ID不需要是唯一的,但是,你应该要确保在你搜寻的局部的树中,ID必须是唯一的。(通常都是搜寻整个树,所以最好的办法就是ID绝对唯一。) 布局参数(Layout Parameters) XML布局属性都是叫layout_something的,这些属性定义了View在ViewGroup中的正确位置。 每个ViewGroup类都实现了内置的一个类ViewGroup.LayoutParams。这个子类包含了各种属性来定义子元素的大小和位置,使它们可以在正确的位置。如figure 1所示,父类view group为每一个子view都定义了布局参数(包括子view group) 记住没个LayoutParams子类都有自己的语法去设置值。每一个子元素必须定义LayoutParams用来适应它的父类,虽然这可能会为它自己的子元素定义不同的LayoutParams。 所有的view group都包含了宽度和高度(layout_width和layout_height),并且每一个view都必须定义这两个属性。大部分LayoutParams也有可选的外边距和边界。 你可以使用精确的值来指定宽度和高度,虽然你不会经常这么做的。通常你会使用下面的常量来设置宽度和高度:
ArrayAdapter adapter =newArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);构造方法里的参数:
ListView listView =(ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);
想要自定义每一项的输出,你可以为你的数组中的每一个对象覆写toString()。或者为每一项创建一个view,里面可能需要显示更多的东西,(比如,如果你希望在每一项里显示一个ImageView),继承ArrayAdapter然后覆写getView()方法,去返回一个自己想要的view对象。
SimpleCursorAdapter
当你的数据来自一个Cursor对象的时候,你需要使用这个适配器。当使用SimpleCursorAdapter的时候,你必须指定一个布局供每一行使用。比如,如果你想要创建一个人名和电话的列表,你可以执行一个查询,返回的Cursor包含着每一个人的信息以及电话号码。然后,你需要创建一个字符串数组用来指定Cursor中的每一列都对应着布局中的那个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 =newSimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews,0); ListView listView = getListView(); listView.setAdapter(adapter);SimpleCursorAdapter随后会为每一行都创建一个视图,把fromColums的数据都关联到toViews上面。 如果在你应用的生命内,你改变了适配器所绑定的数据源,你需要调用notifyDataSetChanged()方法。这个会通知它附着的视图数据已经改变了,它应该刷新自己。 处理点击事件(Handling click events) 你可以实现AdapterView.OnItemClickListener接口为每一项设置点击事件。比如:
// Create a message handling object as an anonymous class. privateOnItemClickListener mMessageClickedHandler =newOnItemClickListener(){ publicvoid onItemClick(AdapterView parent,View v,int position,long id){ // Do something in response to the click } }; listView.setOnItemClickListener(mMessageClickedHandler);