首页 > 代码库 > Android UI基础

Android UI基础

Android UI概述

Android UI由View和ViewGroup组成。

ViewGroup是不可见的,用于组织和排版View和ViewGroup。

View用户显示内容,以及响应用户的操作。

可以按照需要安排UI的叠放,不过叠放的层数越少,性能上来说越好。

Android UI可以在code中生产,不过更加方便的方式是在Android的XML文件中定义UI。

 

Layouts 通过XML方式实现

可以通过2种方式定义界面结构。

1. 在XML定义视图结构

2. 在运行时动态创建视图结构

通过XML定义视图结构,可以有效的做到代码与界面分离,并且提高界面结构的可读性。

 

XML书写方式

xml的file必须包含一个root,可以是View或者ViewGroup。在节点下面增加子界面的方式来构造界面结构。

xml的基本书写结构可以参照http://developer.android.com/guide/topics/resources/layout-resource.html

 

加载xml资源

在编译程序阶段,所有的XML layout文件都会编译到一个统一的View资源里面。

在需要使用layout资源的时候,需要将资源加载到程序中,一般的做法是在 Activity.onCreate()中做加载的资源的操作。

如果界面的文件名称是main_layout.xml,则可以如下方式加载。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
    }
XML layout属性

每个View或者ViewGroup都有自己特有或者继承下来的属性。

 

ID

每一个View或者ViewGroup都有一个ID属性。该属性由class View定义。其定义语法为:

android:id="@+id/my_button"

@ 的意思是指示XML parser解析并且展开后面的内容,将其作为一个ID的资源。

+ 的意思是指示这是一个新的ID,需要将其加到资源定义文件R.java中去。

 

有一些系统自定的ID,如果引用这些系统自定义的ID,则不需要加+号,但需要加上包的命名空间,其定义的语法为:

android:id="@android:id/empty"
 
常用的定义一个view或者widget,并且在代码中调用的方式如下:
1.定义一个View,并且配置一个唯一的ID
<Button android:id="@+id/my_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/my_button_text"/>
2.使用这个唯一的ID在代码中创建实例
Button myButton = (Button) findViewById(R.id.my_button);
IDs在RelativeLayout中会显的更加的重要,因为需要通过IDs来指定其旁边的View。哪个View在自己的左边,哪个View在自己的右边,或者上面或者下面。

 

Layout相关的参数

在XML文件中,通常使用layout_something来定义View在ViewGroup中的位置

ViewGroup类会实现一个嵌套类来扩展ViewGroup.LayoutParams.这个内嵌的子类会定义类型来指定子View的位置和大小。

如下图所示,父view group会为其子view或者子view group都定义layout参数

<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

Layout参数对于其父节点和对于其子节点的含义都可能是不一样的,因此要区别对待。

每一个view group一般都会包含width和height参数(layout_width and layout_height),因此每个再其内的view都需要定义这俩个属性。

一般我们不会将其指定为某一个宽度或者高度,一般写为相对的,这样可以保证适应于多种屏幕大小的设备。

  • wrap_content:根据内容的大小调节大小
  • fill_parent:最大化达到父几点所允许的,在API level 8后名字改为match_parent
Layout的位置

View作为一个几何图形,具有4个属性对应于他所属的容器,分别是left, top, width和height,每个属性的单位是pixel

参考API文档,可以很多函数获取位置以及View的大小信息。getLeft(),getTop(),getRight(),getBottom()。

获取的值一般都是相对应与父节点的位置和大小信息

Size,Padding和Margins

Size由View的width和height来表示。

width和height有2种类型,一种是对应于父容器的measured width和measured height,其是相对于父容器的高度和宽度。可以由getMeasuredWidth()和getMeasuredHeight()获取。

另外一种是针对于整个界面的实际width和height,可以由getWidth()和getHeight()获取。

Padding也会被计算入measure size内,Padding,顾名思义,是内容与View空间直接的间隔。可以由函数setPadding(int, int, int, int)进行设置。可由getPaddingLeft(),getPaddingTop(),getPaddingRight(),getPaddingBottom()获取相对应额值。

View并未提供Margins属性,该属性一般由ViewGroup设置。

Layout的通常模式

每一个ViewGroup都会提供一种特有的排列方式。下面是几种常看见的方式。

Note:尽管可以通过在layout中嵌入其他的layout方式来设计一个结构复杂的layout,但是这样会导致layout的结构变的复杂。不利于UI的性能。尽量保持UI嵌套的层数少些。

Linear Layout
Relative Layout
Web View
将内容排列成横列或者竖列显示,如果超出屏幕,则显示滚动条。 可以灵活的设置子view的位置,已经子view之间的位置。 像浏览器一样显示HTML文档
绑定数据源

如果需要在界面上显示的内容是动态获取的话,可以使用使用Adapter和继承AdapterView的View来动态显示。

Adapter是数据源和AdapterView之前的桥梁,由他从数据源获取数据,然后转换为一组实体,填充到View。

一般的数据显示模式如下:

List View
Grid View
可以上下滚动的单行列表 可以滚动的行和列的表格
在Adapter中填入数据

可以简单的使用继承自AdapterView的View来绑定Adapter,来获取外部数据源的数据。

Andorid也提供了一些继承自Adapter的子类用于处理不同的数据形式来建立View,下面是3种比较常见的Adapter:

ArrayAdapter

当数据源是一个数组的时候,可以使用这个Adapter,默认,ArrayAdapter在调用toString()后会为每个Item创建一个TextView。

举个例子,如果想在ListView中显示一个字符串数组,需要实例化一个ArrayAdapter,指定其Layout,每个String的名称,和String列表

ArrayAdapter adapter = new ArrayAdapter<String>(this, 
        android.R.layout.simple_list_item_1, myStringArray);
参数分别为:app Context,含义显示String的TextView的layout,String列表
第二步:在ListView上设置Adapter
ListView listView = (ListView) findViewById(R.id.listview);
listView.setAdapter(adapter);

如果需要定义String的输出格式,可以重载toString(),或者可以不用TextView,换做其他可以显示丰富内容的控件,比如ImageView。

可以方便的扩展ArrayAdaptergetView()来满足不同的显示样式。

SimpleCursorAdapter

如果数据源是来自于游标(Cursor)的时候,使用这个Adapter。使用这个Adapter的时候,需要指定Cursor的哪个行,哪个列插入Layout的View。

举例来说,有一个游标包含了People的数据,People包含name和number字段。

这时候,需要创建一个字符串数组用于指定哪些字段需要显示。一个整形数组,用于指定字段需要显示到哪个控件上

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会将fromColumns的内容填入toViews的View中。

如果,在程序的周期内,如果在Adapter内的数据被改变,那么必须调用notifyDataSetChanged(),这个函数将会通知与这个adapter相关的View并且刷新自己。

处理点击事件

可以通过实现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);
<style type="text/css"> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }</style>

 

参考文档:http://developer.android.com/guide/topics/ui/declaring-layout.html