Android View 系统 1 - View树

View简介

在Android操作系统中,几乎所有的UI元素都是基于ViewViewGroup创建出来的。View就是一块可以用来进行绘画,可以处理输入事件进行交互的矩形区域,而ViewGroup就是一种可以容纳View的矩形容器。
下图就是ViewGroupView组成的UI布局结构。ViewViewGroup通过这种树形结构组合在一起,构成了我们在手机屏幕上看到的一个个的复杂的界面。

View层次结构的图示

从设计模式的角度看,ViewGroupView是组合模式的典型应用。View是基本的控件元素,ViewManager接口定义了添加、删除View的接口addView、removeViewViewGroup实现了ViewParent的接口,因此可以作为容器管理View,同时ViewGroup又继承自View,可以被其他的ViewGroup管理。这样ViewGroupView就可以组成上面的树状结构了。

View类图结构

实际的代码实现过程中很少会直接使用ViewGroupView,而是使用继承自它们的之类,如FrameLayoutLinearLayoutListView等是ViewGroup的子类,TextViewImageViewSurfaceView等是View的子类。

创建View树

上面介绍了ViewGroupView是通过View树的形式组合在一起的,一个View树也就是一个Layout布局,下面就介绍一下怎样创建、管理Layout布局。

Layout资源创建View

最常见的创建Layout的方式就是使用Layout资源。Android 应用的代码目录结构里,在资源res文件夹下有一个layout文件夹,应用中使用的layout资源都会放在这个文件夹下。父View与子View是以XML的形式嵌套在一起的,下面就是一个layout的例子:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="I am a TextView" />
    </FrameLayout>
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="I am a Button" />
</LinearLayout>

同时layout之间也可以相互嵌套,如下面的形式:

<include layout="@layout/other_layout"/>

当在代码中需要使用XML资源里定义的layout时可以使用下面的代码:

LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.main, null);

很多类中将通过LayoutInflater加载资源的过程也封装好了,只需要提供资源就可以了,如设置ActivityContentView的代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_layout);
}

通过Layout资源创建View树的优势是层次结构清晰,管理方便。同时View树中各个View的属性也可以在layout资源里进行设置。缺点是无法在应用运行时对View树结构进行变化。

从代码创建View树

从Java代码中通过ViewGroupaddViewremoveView等接口同样可以管理View树,如下面的代码:

TextView text = new TextView(this);
Button button = new Button(this);

FrameLayout frame = new FrameLayout(this);
frame.addView(text);

LinearLayout linear = new LinearLayout(this);
linear.setOrientation(LinearLayout.VERTICAL);
linear.addView(frame);
linear.addView(button);

从代码中创建View树最多的应用场景是在使用AdapterView的子类的时候,如ListView、GridView、Spinner等。继承自AdapterView的控件一般会通过一个适配器Adapter来添加、删除自己的子View

ListView list = new ListView(this);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_list_item_1, myStringArray);
list.setAdapter(adapter);

在代码中创建View树的优点是对View的管理比较灵活,可以在程序运行过程中动态的管理View树的状态,缺点就是代码实现比较复杂,程序的扩展性不好不容易维护。

通常在开发过程中这两种创建View树的方式是结合在一起使用的。

管理View

View树里的每一个View都会有一个整型ID,用来方便对这个View进行查找管理,View的ID可以在布局文件里定义(如前面布局资源文件里为TextView指定的android:id="@+id/text")也可以在View实例创建后通过View.setId(int id)方法设置。通过View树中根节点的findViewById(int id)方法就可以查找到id对应的View。

LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.main, null);
TextView text = (TextView) view.findViewById(R.id.text);

View树中每个View的 ID 并不强制要求是唯一的,这样可以方便一些子View树重复利用(如ListView中每个item的布局),但是通过findViewById()查找时只会得到最先找到的View,因此建议在资源文件中定义的View使用唯一的ID。

创建了view树以后,还可能会根据实际场景对View树里进行添加或者删除View的操作,使用前面提到过的addView、removeView接口就可以,如:

LayoutInflater inflater = getLayoutInflater();
FrameLayout container = (FrameLayout) inflater.inflate(R.layout.main, null);

TextView text = (TextView) container.findViewById(R.id.text);
container.removeView(text);

Button button = new Button(this);
button.setId(button.hashCode());
container.addView(button);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值