第二篇 基础篇—燃烧吧!我的雌雄双股剑! 第5回 二弟呀,面子工程很重要

三人被酒肆店家追了一条街,才好不容易甩掉了要钱的。

“吃……吃顿晚饭不……不容易啊”,张飞气喘嘘嘘的说。

关羽说:“咱们现在怎么办?官府肯定到处在找我们啊!”

张飞说:“哎,二哥也太胆小了,白吃个晚饭有什么打紧,店家不会小题大做报官吧!”

“三弟此言差矣!白吃个晚饭确实不打紧,白吃人家三十几盒泡面还是成问题的,唉哟,饭后就剧烈运动,我的阑尾在颤抖……”,刘备捂着肚子,瘫倒在地上,口吐白沫。

“现在咱们怎么办?唉,大哥,你就别演了,咱们还是赶紧想想办法吧!”,张飞踢了踢躺在地上的刘备。

刘备赶紧爬了起来,“啊,飞飞,你就是这么对你大哥的吗?我好伤心……二弟,你说今晚咱们去哪里过夜才是?”

“听人家说此处向东五十米外有一座卧龙岗,传说有一位技术狂人诸葛孔明在那里隐居,只要能请他出山,何愁大事不成?”,关羽一边捋着他的胡子一边说。

张飞说:“向东五十米?你是不是说错了,向东五十里吧?”

“不,就是向东五十米,你看,那不就是吗?”,关羽指了指不远处,借着月色,只见一棵大树树干上挂了块牌子,上面写着“woLongGang”。

刘备揉了揉眼睛,“真是亮瞎了我的双眼啊,名字都是用驼峰式命名法写的!二弟,快来给我翻译一下,这蛮文写的什么?”

不等关羽回答,张飞抢到:“大哥,那是拼音好不好,就是卧龙岗……”

刘备说:“那还等什么,我们还不快去!”

于是三人向东走了五十米,就到了卧龙岗。

卧龙岗其实就是个小山头,山头上有个草屋,两居室的,旁边栽了些花花草草。

三人二话不说直接闯进屋内,一进门张飞喊道:“诸葛孔明哪里滴干活!”

“三弟,你当你倭寇进村呢?还哪里滴干活,咱们不是抢劫好不好……”,刘备责怪道,“卧龙先生在吗?我刘关张三兄弟久闻先生大名,特来拜见!”

“厅内可是刘关张三兄弟?”,只听内屋一人说道。

“先生真乃神人!如何得知是我三人?”刘备惊到。

孔明说:“县衙满世界的发你们的通缉令啊,听说你们可能向我这个方向逃窜。别说,这通缉令纸质不错,我特意多要了点当擦屁股纸。”

刘备说:“先生可否出来一见,我等三人有很多问题想向先生请教。”

孔明说:“我在上厕所,茅房很小,你们都进来不是很方便,有什么问题在直说无妨。”

刘备说:“听闻先生乃一代大牛,Android方面想必也是登峰造极,还望先生指点一二!”

孔明说:“也好,我反正也是刚上厕所,闲来无事,你们听好了,这个Android开发首先要从界面讲起……”

 

1.1. 用户界面简介

应用界面是直接与用户接触的地方,界面的美观与否直接关系到一个产品生命周期的长短和用户量的多少,因此拥有一个漂亮的界面对于一款应用来说极其重要。

1.1.1.View和ViewGroup

Android的用户界面都是由视图组件和容器组件组成的。在深入学习之前,为了便于理解,我们可以将容器看作是用户界面上的一块矩形区域,而视图则是位于此矩形区域内部的一个组件,比如文本框,按钮等,容器称为位于此容器内部视图的父容器。在Android源码当中,有View类和ViewGroup类分别对应上述的视图组件和容器组件。

View类是AndroidAPI中定义的类,位于android.view包中。一个View类或者其子类的对象中存储有与该对象相关的矩形布局数据和内容属性等数据,并且可以实现处理包括测距、布局、绘图、焦点变换、滚动条以及屏幕区域内该对象的按键和手势在内的多种功能。View还为Android的Widget提供服务。Widget是Android的系统包,包含了一组View类的可实例化子类。这些子类可以用于绘制交互式屏幕元素,包括上面提到的文本框,按钮等,后面会详细介绍。使用Widget,我们可以快速的创建用户界面。

VeiwGroup类也是AndroidAPI中的类,位于android.view包中。值得一提的是,ViewGroup虽然是View的子类,但是与View类有着完全不同的任务和功能。ViewGroup,顾名思义,它的对象是一组View类对象的集合。实际上,ViewGroup的功能也确实是这样的,它负责装载和管理一组View,包括View类的对象和ViewGroup本身。ViewGroup可以为界面设计增加结构,将复杂的屏幕元素集合成一个独立的实体。下面讲到View树的时候,我们将更深刻地体会到这一点。ViewGroup的一个重要子类是Layout(布局)。Layout可以为一组View构建一个结构。

在实际的编程当中,我们常用的是上述提到的两个类的子类或者间接子类。到这里,细心的读者可能会问,只有视图组件不也可以构建一个界面吗,为什么还需要容器组件呢?现在我们知道,视图组件是有实际的大小和显示内容的,而容器组件的主要作用是来管理其内部的视图组件的,比如声明位于其内部的视图组件的排列方式。当整个界面只有一个组件,比如一个文本框的时候,那么这个文本框可以充满整个屏幕放置,但是当屏幕上存在两个视图组件的时候,问题产生了,第二个组件和第一个组件在位置上是什么关系呢?是横排还是竖排?这时候,容器组件的出现很巧妙地解决了这个问题。我们把组件放到一个容器内,然后在容器的属性里指定位于其内部的视图组件的排列方式,系统就知道该如何显示容器内的组件了。

综上所述,Android界面的组成元素是View和ViewGroup的子类和间接子类。视图组件的作用是显示,而容器组件的作用是管理。

 

1.1.2. Android界面的基本架构

在Android中,界面是由一棵View树来定义的。View树的叶子结点是视图组件,而其他非叶子结点则是容器组件。View树的示例如5-1所示:

ViewGroup

容器组件

ViewGroup

容器组件

ViewGroup

容器组件

View

视图组件

View

视图组件

View

视图组件

View

视图组件

View

视图组件

图5-1 View树示例

孔明:你们知道吗?View树的这种树形结构也为组件的事件管理,如触摸屏、键盘点击事件,提供了很大的便利。可以说组件的事件传递机制就是沿着树,从高层向底层传递的。

 

 

 

 


从上图5-1可以看出,一个ViewGroup组件可以包含多个View组件,也可以包含多个ViewGroup组件。Android这种非常灵活的View层次结构可以形成非常复杂的布局,开发者可以据此设计出非常精致的界面。

当我们调用Activity的setContentView()方法时,我们可以将一棵树的根结点或者其子树的根结点,甚至叶子结点作为参数传入此方法,这样系统就获得了该结点的参数,并将该结点作为根结点来测距和绘制,最终将以该结点为根结点的整棵树都绘制到界面上。绘制过程中,父结点负责请求它的子结点去绘制他们自己,如果子结点是ViewGroup结点,则该子结点继续请求下一层的结点来绘制他们自己,子结点可能会请求获得他们在父结点中的大小和位置,但是父结点对每个子结点的大小和位置有最终的决定权。

1.1.3.xml布局文件控制UI界面

在这小节,我们介绍使用xml布局文件的方式来定义View树。这也是Android里面布局最常用的一种方式。先来看一个具体的例子,我们新建一个AndroidProject,并将其中的layout文件夹下的main.xml文件修改如下:

main.xml代码清单5-1:

<?xml version="1.0" encoding="utf-8"?>

<!-- LinearLayout 是根节点 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

<!-- 下面两个TextView 是这个Layout叶子节点 -->

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"/>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"/>

</LinearLayout>

我们将main.xml称为布局文件。一般情况下,一个Activity对应一个布局文件。在main.xml中,我们将整个TextView标签的内容复制一次,粘贴到下面。这样,一个LinearLayout里面就有了两个TextView。通过前面的学习,我们知道,LinearLayout对应的是容器组件,而TextView对应的是视图组件。也就是说,在此例中,我们在一个容器组件里面放置了两个视图组件。根结点为LinearLayout,两个叶结点为TextView。

Activity的OnCreate()方法里面调用setContentView(R.layout.main)方法,该方法指明了本工程的该Activity将使用mian.xml文件定义的布局。然后,我们运行程序,截图如5-2所示:

图5-2 xml布局文件效果

我们还可以增加更多的元素到main.xml里面去,为LinearLayout增加更多的子结点,将main.xml修改如下:

<?xml version="1.0" encoding="utf-8"?>

<!-- LinearLayout 是根节点 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

<!-- 下面两个TextView 是这个Layout叶子节点 -->

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"/>

<TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"/>

<!-- 下面是新增加的Layout -->

<LinearLayout

android:orientation="horizontal"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

<!-- 两个Button作为新增加的Layout的叶子节点 -->

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Button1"/>

<Button

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Button2"/>

</LinearLayout>

</LinearLayout>

再次运行程序的截图如5-3所下:

图5-3 修改xml布局文件后的效果

我们发现在原先的两行TextView下面出现了横向分布的两个按钮,这两个按钮正是我们在main.xml文件里定义的。

在当前页面下,查看Eclipse里的OutLine(大纲),我们发现几个组件组成了一个View树,如5-4图所示:

图5-4 Eclipse里面的OutLine视图

孔明:你们看上图中的Eclipse里的大纲是不是和View树相互对应呢,ViewGroup是LinearLayout,View是TextView和Button。当需要更复杂,包含更多元素的界面只需要在xml布局文件里边增加相应的元素即可,是不是很简单呢?

 

 

 

 

 


1.1.4.常见xml属性解析

没有接触过xml文件的读者可能被上面的xml文件搞得有些头晕,这一小节我们来讲讲常见的xml属性。

xml是可扩展标记语言的简称。每一个布局文件的第一行是:

<?xml version="1.0" encoding="utf-8"?>

这一行的作用是声明了xml的版本以及编码方式。

xml文件里的元素都以<xxx>开始,以</xxx>或/>结束。其中xxx是具体的元素的名字,比如在main.xml文件里的TextView、Button等等。xml文件规定,一个xml文件必须有且只有一个根元素,根元素里面可以有子元素,子元素可以有子子元素。xml文件里的注释要写在<!--  -->里面。xml文件当中,元素的属性都要写在<xxx>或者<xxx/>中,而不能写在其他地方。

xmlns:android="http://schemas.android.com/apk/res/android"定义了Android布局文件的命名空间,之后出现的各种属性都是出自这个命名空间,如果没有包含这个命名空间,系统就会报错。

以android:开头的都是来定义组件属性的,需要说明的是不同的视图组件和容器组件会拥有不同的属性设置,下面我们把通用的属性列表说明如下:

属性名

属性值

android:layout_width

fill_parent:宽度填充父容器

wrap_content: 宽度包裹内容

match_parent:适应父容器中剩余的宽度,即除去父容器下的其他组件后剩下的宽度。

android:layout_height

同上

android:text

定义该View的Text内容,可以直接写一个字符串,也可以使用@string/来引用定义在string.xml文件中的字符串。

android:id

为组件指定相应的id,例如android:id=“@+id/ViewId”,ViewId就是该组件的id,如果要使用系统已经存在的id,则使用android:id=“@id/ViewId”进行指定。

android:gravity

设置此组件中的内容在组件中的位置。可选的值有:top、bottom、left、right、center_vertical、fill_vertical、center_horizontal、fill_horizontal、center、fill、clip_vertical可以多选,用“|”分开。

android:textSize

指定组件中字体的大小

android:background

指定组件所使用的背景颜色,使用RGB方式进行赋值,或者应用color.xml文件中定义的颜色。

android:width

指定组件的宽度

android:height

指定组件的高度

android:padding

指定组件的内边距,即组件中的内容与组件边缘的距离。

android:layout_margin

指定组件的外边距,即该组件与父容器边缘的距离。

android:singleLine

是否单行显示,如果设置为true,则该组件里的内容只显示一行。

android:visibility

有三个属性值,visible,invisible和gone,含义分别是显示,不显示但还是占有原先的空间,不显示且不占有空间。

 

孔明:实际上xml的属性非常复杂,而且每一个控件往往有属于自己的特有属性,额……这个,还是在后面遇到的时候再说吧。

 

 

 

 


1.1.5.硬编码控制UI界面

使用硬编码的方式来控制UI界面指的是直接在程序里面用编写代码的形式来控制界面。我们新建一个Android工程,编写Activity中代码如下:

Chapter05_15Activity.java代码清单5-2:

/**

 * 展示用硬编码的方法来控制UI界面

 * @author 孔明

 */

public class Chapter05_15Activity extendsActivity {

   @Override

    publicvoid onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

        // 创建一个线性布局对象

       LinearLayout linearLayout = new LinearLayout(this);

        // 创建两个TextView对象

       TextView textView01 = new TextView(this);

       TextView textView02 = new TextView(this);

        // 为两个TextView设置要显示的文本

       textView01.setText(R.string.hello);

       textView02.setText(R.string.hello);

        // 设置线性布局的排列为竖向排列方式

       linearLayout.setOrientation(LinearLayout.VERTICAL);

        // 将两个TextView加入到线性布局对象里面

// 这一步也是为线性布局对象增加叶子结点

       linearLayout.addView(textView01);

       linearLayout.addView(textView02);

        // 最后最重要的一步,将线性布局的对象传给setContentView方法

// 作为参数并执行。

       setContentView(linearLayout);

    }

}

上面的代码运行之后的截图如5-5所示:

图5-5 硬编码方式控制的界面视图

我们可以发现,上述代码的运行效果与5.1.3小节的运行效果是一样的,只不过这次我们是通过硬编码的方式来控制View。

比较5.1.3中的第一个例子和5.1.5中讲到的例子,我们发现使用xml布局文件来控制UI布局可以更加自由地控制应用的界面,还可以通过切换到Eclipse的GraphicalLayout标签来随时查看布局的效果,因此,Android提倡使用xml布局文件来控制UI界面,但是使用硬编码的方式来控制UI界面可以实现动态的控制组件显示的内容,这一点是xml布局文件做不到的,而且在交互性很强的应用中,这种用硬编码的形式来动态更新组件内容的方法很常用。下一小节,我们会讲到如何动态更新组件内容。

孔明:知道不?使用xml文件配置布局是MVC(模型Model-视图View-控制器Controller)思想的一种很好的体现!

 

 

 

 

 


1.1.6.硬编码与xml混合方式控制UI界面

上面两小节分别讲到了使用硬编码和xml布局文件的方式来控制UI界面,而在实际的应用当中,使用硬编码和xml混合方式来控制界面的方法更为常用。这一小节,我们来做一个简单的例子来讲解如何做到这一点。我们来新建一个Android工程,代码如下:

Chapter05_16Activity.java代码清单5-3:

/**

 * 硬编码和xml布局文件控制UI界面,该Activity实现了View类的OnClickListener接口。

 * @author 孔明

 */

public class Chapter05_16Activity extendsActivity implements OnClickListener {

// 计数器

private int count = 0;

// 保存Button的引用

private Button mButton = null;

   @Override

    publicvoid onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

        // 通过id找到xml布局文件中定义的button,并返回一个对象

       mButton = (Button) findViewById(R.id.Button);

        // 设置button的监听器为Activity本身

       mButton.setOnClickListener(this);

    }

// 当有按钮被点击时,onClick方法被调用,参数就是被点击的View的引用。

@Override

public void onClick(View v) {

// 本实例中只有一个View,所以,只可能是我们定义的button

// 因此,这里忽略对参数的检查。

            // 计数器增加

            count++;

            // 修改button的显示内容。

            mButton.setText("我被点击了" + count + "次");

}

}

该Activity使用的main.xml布局文件如下:

main.xml代码清单5-3:

<?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" >

<Button

       android:id="@+id/Button"

       android:layout_width="fill_parent"

       android:layout_height="wrap_content"

       android:text="@string/hello" />

</LinearLayout>

运行程序,我们可以发现,刚开始button的内容显示的是string.xml文件中定义的hello字符串,当我们点击button的时候,就会看到我们设置的button的内容显示出来了,运行截图如5-6所示:

图5-6 硬编码与xml混合方式控制的界面视图

我们通过在程序里边设置button的内容来实现组件的动态更新。细心的读者会发现,从5.1.3开始,我们讲解的例子都非常简单,实际开发中几乎用不到这么简单的东西,但是我们希望读者抓住本质,复杂的东西的原理跟这些简单的是一样的。实际上,不管是xml布局文件,还是硬编码更新组件,我们都还有很多内容要讲。在此,只希望读者能理解Android这种界面布局的特性,其他内容后面会有更加详细的介绍。

孔明:如果要动态更新组件,有时候就不得不使用硬编码的方式来更新,但是也不是说要完全放弃xml布局。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值