精华内容
下载资源
问答
  • 文章目录零、学习目标一、网格布局1、布局特点2、继承关系图3、常用属性(1)针对布局的属性(2)针对子控件的属性二、教学案例 —— 计算器界面(一)运行效果(二)涉及知识点(三)实现步骤1、创建安卓应用...

    零、学习目标

    1. 能说出网格布局常用的属性
    2. 能利用网格布局实现简单的界面设计

    一、网格布局概述

    1、布局特点

    GridLayout布局使用虚细线将布局划分为行、列和单元格,也支持一个控件在行、列上都有交错排列。

    2、继承关系图

    在这里插入图片描述

    3、常用属性

    (1)针对布局的属性

    • rowCount:行数
    • columnCount:列数

    (2)针对子控件的属性

    • layout_row:子控件在布局的行数
    • layout_column:子控件在布局的列数
    • layout_rowSpan:跨行数
    • layout_columnSpan:跨列数

    二、案例演示——计算器界面

    (一)运行效果

    在这里插入图片描述

    (二)涉及知识点

    1、网格布局(GridLayout)
    2、线性布局(LinearLayout)
    3、文本视图(TextView)
    4、按钮(Button)

    (三)实现步骤

    1、创建安卓应用【GridLayoutCalculator】

    在这里插入图片描述
    在这里插入图片描述

    2、将一张背景图片拷贝到drawable目录里

    在这里插入图片描述

    3、主布局资源文件activity_main.xml

    在这里插入图片描述

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/background"
        android:orientation="vertical"
        android:padding="15dp"
        android:gravity="center_horizontal"
        tools:context="net.hw.calculator.MainActivity">
    
        <GridLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:columnCount="5"
            android:rowCount="7">
    
            <TextView
                android:layout_width="320dp"
                android:layout_height="50dp"
                android:layout_row="0"
                android:layout_column="0"
                android:layout_columnSpan="5"
                android:gravity="right"
                android:background="@drawable/custom_border"
                android:paddingRight="10dp"
                android:text="0123456789"
                android:textColor="#0000ff"
                android:textSize="25sp"
                android:layout_marginBottom="30dp"/>
    
            <Button
                android:layout_width="65dp"
                android:layout_row="1"
                android:layout_column="0"
                android:text="MC" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="1"
                android:layout_column="1"
                android:text="MR" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="1"
                android:layout_column="2"
                android:text="MS" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="1"
                android:layout_column="3"
                android:text="M+" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="1"
                android:layout_column="4"
                android:text="M-" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="2"
                android:layout_column="0"
                android:text="" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="2"
                android:layout_column="1"
                android:text="CE" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="2"
                android:layout_column="2"
                android:text="C" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="2"
                android:layout_column="3"
                android:text="±" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="2"
                android:layout_column="4"
                android:text="" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="3"
                android:layout_column="0"
                android:text="7" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="3"
                android:layout_column="1"
                android:text="8" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="3"
                android:layout_column="2"
                android:text="9" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="3"
                android:layout_column="3"
                android:text="/" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="3"
                android:layout_column="4"
                android:text="%" />
    
    
            <Button
                android:layout_width="65dp"
                android:layout_row="4"
                android:layout_column="0"
                android:text="4" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="4"
                android:layout_column="1"
                android:text="5" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="4"
                android:layout_column="2"
                android:text="6" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="4"
                android:layout_column="3"
                android:text="*" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="4"
                android:layout_column="4"
                android:text="1/x" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="5"
                android:layout_column="0"
                android:text="1" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="5"
                android:layout_column="1"
                android:text="2" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="5"
                android:layout_column="2"
                android:text="3" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="5"
                android:layout_column="3"
                android:text="-" />
    
            <Button
                android:layout_width="65dp"
                android:layout_height="95dp"
                android:layout_row="5"
                android:layout_rowSpan="2"
                android:layout_column="4"
                android:text="=" />
    
            <Button
                android:layout_width="130dp"
                android:layout_row="6"
                android:layout_column="0"
                android:layout_columnSpan="2"
                android:text="0" />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="6"
                android:layout_column="2"
                android:text="." />
    
            <Button
                android:layout_width="65dp"
                android:layout_row="6"
                android:layout_column="3"
                android:text="+" />
        </GridLayout>
    </LinearLayout>
    

    4、在drawable目录里添加custom_border.xml

    在这里插入图片描述

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    
        <corners android:radius="5dp" />
        <solid android:color="#eeeeee" />
        <stroke
            android:width="1dp"
            android:color="#555555" />
    
        <padding
            android:bottom="10dp"
            android:left="10dp"
            android:right="10dp"
            android:top="10dp" />
    
        <gradient
            android:endColor="#eeeeee"
            android:startColor="#aaaaaa" />
    </shape>
    

    5、启动应用,查看效果

    在这里插入图片描述

    三、课后作业

    1、网格布局练习1

    在这里插入图片描述

    2、网格布局练习2

    在这里插入图片描述

    • 图片配文字
      在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 学习目标 网格视图 什么是网格视图 GridView网格视图是按照行列分布的方式来显示多个组件通常用于显示图片或是图标等 在XML布局文件中添加网格视图的基本语法如下 网格视图 属性列表 > </GridView> 网格视图 XML属性...
  • 【前端】CSS布局问题之网格布局

    千次阅读 2018-11-20 20:47:59
    对于一个偶尔需要谢谢前端界面的我来说,今天了解到了HTML前端可以用网格布局之后,整个人都轻松起来了。在基于C#做手持设备开发和安卓应用程序里,都常用网格来进行布局。而在网页前端,我几乎都是用用Bootstrap...

    对于一个偶尔需要写写前端界面的我来说,今天了解到了HTML前端可以用网格布局之后,整个人都轻松起来了。在基于C#做手持设备开发和安卓应用程序里,都常用网格来进行布局。而在网页前端,我几乎都是用用Bootstrap这种框架来设定布局,对于基础的CSS控制样式还能搞定,但是涉及到布局,就一头雾水。

    比如最近用到float:left这种布局,碰到元素之间崩塌的情况,就是元素位置根本不按照设想的来,看了一些书和文章,提到了这个问题。大家将CSS归结为艺术,不是科学。哈哈哈。

    对于网格布局我还不是特别熟悉,下面先放一个测试案例:

    <!DOCTYPE html>
    <html>
    <head>
    	<title>CSS Grids</title>
    	<style type="text/css">
    
    		h1 {
    			text-align: center;
    		}
    		/*核心*/
    		.wrapper {
    			display: grid;
    			grid-template-columns: 30% 30% 30%;
    		}
    		.wrapper > div {
    			background: #eee;
    			padding: 1em;
    		}
    		.wrapper >div:nth-child(odd) {
    			background: #ddd;
    		}
    	</style>
    </head>
    <body>
    	<header>
    		<h1>Hello World</h1>
    	</header>
    	<div class="wrapper">
    		
    
    		<div>
    			Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    			tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, 
    			quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    			consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    			cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    			proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    			tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    			quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    			consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    			cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    			proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    			tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    			quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    			consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    			cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    			proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    		</div>
    	</div>
    </body>
    </html>
    

    非常简单的,将容器设置为:

    /*核心*/
    .wrapper {
    	display: grid;
    	grid-template-columns: 30% 30% 30%;
    }
    

    然后里面的元素就按照百分比来排列了~~非常方便。

    grid-template-columns的用法详解

    注意,这里面grid-template-columns推荐使用的是fr作为单位,当然用什么单位都是随意的,比如px等。

    .wrapper {
    	display: grid;
    	grid-template-columns: 1fr 2fr 1fr;
    }
    

    会自动按照数字的比例进行分割。

    repeat法

    .wrapper {
    	display: grid;
    	/*grid-template-columns: 1fr 2fr 1fr;*/
    	grid-template-columns: repeat(4, 1fr 2fr);
    }
    

    显示效果如下:

    在这里插入图片描述

    会按照1fr 2fr的占比分配空间,重复四次,自动计算空间分配。棒极了!

    行列间隙设置

    .wrapper {
    	display: grid;
    	/*grid-template-columns: 1fr 2fr 1fr;*/
    	grid-template-columns: repeat(4, 1fr 2fr);
    	/*列之间留白*/
    	grid-column-gap: 1em; 
    	/*行与行间留白*/
    	grid-row-gap: 1em; 
    	/*综合上面两个效果*/
    	grid-gap: 1em;
    }
    

    在这里插入图片描述

    真的是让人省心的操作。
    另外需要注意到,这里文字会按照最多的设定区域大小,其他文字较少的也一样要拉到和最多的文字区块一样大。

    grid-auto-rows: 100px;
    

    设置了固定大小,会导致如下问题:

    在这里插入图片描述

    文字会超出这个框。

    比较好的设置方式是:

    grid-auto-rows: minmax(100px, auto);
    

    设置最小最大的范围即可得出让人满意的效果了。

    在这里插入图片描述

    嵌套格式

    <!DOCTYPE html>
    <html>
    <head>
    	<title>CSS Grid</title>
    	<style type="text/css">
    
    		.wrapper {
    			display: grid;
    			/*grid-template-columns: 1fr 2fr 1fr;*/
    			grid-template-columns: repeat(4, 1fr 2fr);
    			grid-gap: 1em;
    			/*grid-auto-rows: 100px;*/
    			grid-auto-rows: minmax(100px, auto);
    		}
    		/*设置基本显示效果*/
    		.wrapper > div {
    			background: #eee;
    			padding: 1em;
    		}
    
    		.wrapper > div:nth-child(odd) {
    			background: #ddd;
    		}
    
    		.nested {
    			display: grid;
    			grid-template-columns: repeat(3, 1fr);
    			grid-auto-rows: 70px;
    			grid-gap: 1em;
    		}
    
    		.nested > div {
    			border: #333 1px solid;
    			padding: 1em;
    			text-align: center;
    		}
    	</style>
    </head>
    <body> 
    	<div class="wrapper">
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div class="nested">
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    			<div>Lorem</div>
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    			tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    			quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    			consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    			cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    			proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    			<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    		<div>
    			Lorem ipsum dolor sit amet.
    		</div>
    	</div>
    </body>
    </html>
    

    重点是:

    .nested {
    	display: grid;
    	grid-template-columns: repeat(3, 1fr);
    	grid-auto-rows: 70px;
    	grid-gap: 1em;
    }
    

    显示效果:

    在这里插入图片描述

    这就是我一直寻找的效果。

    更强大的属性

    再讲几个:

    • justify-items
      • :start
      • center
      • :end
      • stretch

    先看justify-items

    <!DOCTYPE html>
    <html>
    <head>
    	<title>CSS Grid</title>
    	<style type="text/css">
    
    		.wrapper {
    			display: grid;
    			/*grid-template-columns: 1fr 2fr 1fr;*/
    			grid-template-columns: 1fr 2fr 1fr;
    			grid-gap: 1em;
    			/*grid-auto-rows: 100px;*/
    			grid-auto-rows: minmax(100px, auto);
    			justify-items:start;
    		}
    		/*设置基本显示效果*/
    		.wrapper > div {
    			background: #eee;
    			padding: 1em;
    		}
    
    		.wrapper > div:nth-child(odd) {
    			background: #ddd;
    		}
    
    	</style>
    </head>
    <body> 
    	<div class="wrapper">
    		<div class="box box1">Box 1</div>
    		<div class="box box2">Box 2</div>
    		<div class="box box3">Box 3</div>
    		<div class="box box4">Box 4</div>
    	</div>
    </body>
    </html>
    

    将Box的显示都弄成靠左排列的效果:

    justify-items:start;
    

    在这里插入图片描述

    靠中间显示:

    justify-items:center;
    

    在这里插入图片描述

    靠右边显示:

    justify-items:end;
    

    在这里插入图片描述

    展开显示,占据该部分全部空间:

    justify-items:stretch;
    

    在这里插入图片描述

    所以可以看出默认就是stretch显示的。

    上面这种设定好像只是有左右效果,为了有上下效果,我们用的是align-items,下面一一展开来看。

    /*align-items: start;*/
    /*align-items: center;*/
    /*align-items: end;*/
    align-items: stretch;
    

    上,中,下,展开。

    上面这是对.wrapper容器进行设定,那么容器内的元素自我设定是如何做的呢?

    答案就是两条:

    • align-self: start/center/end/stretch;
    • justify-self:start/center/end/stretch;

    具体的参数与上面相同,只是这个是针对元素进行设置,上面是容器内的所有元素都服从分配。

    现在来思考,如何实现网格布局的跨格子操作。

    在这里插入图片描述

    按照线条从1开始计数:

    跨越多列:

    .box2 {
    	grid-column: 1/3;
    }
    

    在这里插入图片描述

    跨越多行:

    .box2 {
    	grid-column: 1/3;
    	grid-row: 1/3;
    }
    

    在这里插入图片描述

    注意看,这里还把Box1赶跑了。如果强行指定Box1,且和Box2有重叠,则可以实现overlapping的效果。

    更完整的操作可以学习:https://css-tricks.com/snippets/css/complete-guide-grid/

    考虑到之前CSS布局的头大,现在这种方式简洁到想哭啊,这和微软的Metro布局设计几乎一致,前端设计者的福音~~~

    注:前端大佬随便拍砖。

    END.

    参考:

    https://www.youtube.com/watch?v=jV8B24rSN5o&t=358s

    展开全文
  • 七大布局分别为:线性布局(LInearLayout)、相对布局(RelativeLayout)、帧布局(FrameLayout)、表格布局(TableLayout)、绝对布局(absoluteLayout)、网格布局(GridLayout)、约束布局(Constrain.

    应用市场截图

    图中展示的华为应用市场的主页面,安卓形形色色的百万级应用,界面也是各有不同,但总的来说还是,还是脱离不了七大布局,软件工程师将组件通过不同的布局组合,进行一系列的加工,最后成为我们手机现在使用的应用。

    【安卓】

    安卓的七大布局又是什么呢?

    七大布局分别为:线性布局(LInearLayout)、相对布局(RelativeLayout)、帧布局(FrameLayout)、表格布局(TableLayout)、绝对布局(absoluteLayout)、网格布局(GridLayout)、约束布局(ConstraintLayout)

    这么多的布局也并非一开始就有,比如约束布局(ConstraintLayout)是Android Studio 2.2推出的新布局,并从Android Studio 2.3开始成为默认布局;网格布局(GridLayout)是Android4.0(API Level 14)新引入的等等。

    不同的布局适用于不同的场景,下面详细介绍七大布局的特点及使用:(布局属性具体见附录)

    安卓七大布局

    【鸿蒙】

    鸿蒙包含2种常用布局:

    定向布局(DirectionalLayout)、从属布局(DependentLayout)

    对比结论:以目前的常用布局能够满足应用开发的大部分需求,但相较于安卓的帧布局(FrameLayout),如加载自定义视图时提供容器,需要额外考虑实现方式。其中定向布局(DirectionalLayout)可与安卓的线性布局(LinearLayout)做横向比较,从属布局(DependentLayout)可与安卓的相对布局(RelativeLayout)做横向比较,两者是相似的。

    后续是否有更多的布局种类加入,可以拭目以待,下面详细介绍2种布局的特点及使用:

    鸿蒙两大布局

    附录:(后面内容较长)

    【安卓】

    线性布局(LinearLayout)属性列表:

    线性布局(LinearLayout)属性列表

    相对布局(RelativeLayout)属性列表:

    相对布局属性列表1

    相对布局属性列表2

    绝对布局(AbsoluteLayout)属性列表:

    绝对布局属性列表

    表格布局(TableLayout)属性列表:

    表格布局属性列表

    帧布局(FrameLayout)属性列表:

    帧布局属性列表

    网格布局(GridLayout)属性列表:

    网格布局属性列表

    约束布局(ConstraintLayout)属性列表:

    约束布局属性列表1

    约束布局属性列表2

    约束布局属性列表3

    【鸿蒙】

    定向布局(DirectionalLayout)属性列表:

    定向布局属性列表

    从属布局(DependentLayout)属性列表:

    从属布局属性列表

    本文由GZH程序员小小叶发布!

    展开全文
  • 安卓基础学习_应用的界面编程

    千次阅读 2013-11-22 20:47:14
    1、布局管理器 线性布局:LinerLayout ...网格布局:GridLayout(android 4.0新增) 1.线性布局 线性布局不会自动换行,当组件会一个一个的排列到头后,剩下的组件将不会被显示出来。 注:纵向vertical
    一、Android应用的界面编程
    1、布局管理器
    线性布局:LinerLayout
    表格布局:TableLayout
    相对布局:RelativeLayout
    绝对布局:AbsoluteLayout
    帧布局:FrameLayout
    网格布局:GridLayout(android 4.0新增)
    
    1.线性布局
    线性布局不会自动换行,当组件会一个一个的排列到头后,剩下的组件将不会被显示出来。
    注:纵向vertical或横向horizontal
    
    2.表格布局(注册界面)
    TableLayout属于行和列形式的管理控件,每行为一个TableRow对象,也可以是一个View对象。在TableRow中还可以继续添加其他的控件,每添加一个子控件就成为一列。TableLayout不会生成边框。
    Android:collapseColumns  设置指定的列为collapse,如果一列被标示为collapse,该列会被隐藏
    Android:shrinkColumns    设置指定的列为shrinkable,如果一列被标示为shrinkable,列的宽度进行收缩,自适应父容器的大小
    Android:stretchColumns   设置指定的列为stretchable,如果一列被标示为stretchable ,该列会被拉伸,填充满表格的空白区域
    e.g.
    android:shrinkColumns="1"   //第2列允许收缩
    android:stretchColumns="2"   //第3列允许拉伸
    android:collapseColumns="1"   //第2列被隐藏
    
    3.相对布局
    相对布局中的视图组件是按相互之间的相对位置来确定的,并不是线性布局中的必须按行或按列单个显示。
    
    4.帧布局(视频播放暂停画面)
    帧布局中的每一个组件都代表一个画面,默认以屏幕左上角作为(0,0)坐标,按组件定义的先后顺序依次逐屏显示,后面出现的会覆盖前面的画面。用该布局可以实现动画效果。
    
    5.绝对布局(登陆界面)
    注:绝对定位AbsoluteLayout,又可以叫做坐标布局,可以直接指定子元素的绝对位置,这种布局简单直接,直观性强,但是由于手机屏幕尺寸差别比较大,使用绝对定位的适应性会比较差。
    在绝对定位中,如果子元素不设置layout_x和layout_y,那么它们的默认值是0,也就是说它会像在FrameLayout一样这个元素会出现在左上角。
    
    6.网格布局(计算器)
    网格布局的作用类似于HTML中的table标签,它把整个容器分成raws x columns个网格,每个网格放一个组件,除此之外也可以设置一个组件横跨多少列,一个组件横跨多少行。
    e.g.
    android:rowCount="6"  //6行
    android:columnCount="4"  //4列
    android:layout_columnSpan="4"  //横跨4列
    
    Android长度单位详解(dp、sp、px、in、pt、mm、dip)
    android中定义的dimension单位有以下这些:
    1、px(Pixels ,像素):对应屏幕上的实际像素点。例如,320*480的屏幕在横向有320个象素,在纵向有480个象素。
    2、in(Inches ,英寸):屏幕物理长度单位。每英寸等于2.54厘米。例如,形容手机屏幕大小,经常说,3.2(英)寸、3.5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是3.2英寸,表示手机的屏幕(可视区域)对角线长度是3.2*2.54 = 8.128厘米。读者可以去量一量自己的手机屏幕,看和实际的尺寸是否一致。
    3、mm(Millimeters ,毫米):屏幕物理长度单位。
    4、pt(Points ,磅):屏幕物理长度单位, 表示一个点,是屏幕的物理尺寸。大小为1英寸的1/72。
    5、dp(与密度无关的像素):逻辑长度单位,在 160 dpi 屏幕上,1dp=1px=1/160英寸。随着密度变化,对应的像素数量也变化,但并没有直接的变化比例。
    dip:与dp相同,多用于Google示例中。
    sp(与密度和字体缩放度无关的像素):与dp类似,但是可以根据用户的字体大小首选项进行缩放。尽量使用dp作为空间大小单位,sp作为和文字相关大小单位。
    
    
    
    
    二、UI组件
    1.TextView及其子类
    <!--滚动显示文本内容-->
    android:ellipsize="marquee"
    android:singleLine="true" 
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:scrollHorizontally="true"
    android:marqueeRepeatLimit="marquee_forever"
    <!-- 设置文字阴影 -->
    android:shadowDx="10.0" //阴影水平偏移量
    android:shadowDy="8.0"  //阴影垂直偏移量
    android:shadowRadius="3.0"  //阴影半径
    <!--对邮件、电话增加链接-->
    android:autoLink="email|phone" 
    <!--密码输入-->
    android:password="true" 
    <!--通过checkMark设置该文本框的勾选图标-->
    android:checkMark="@drawable/ok"
    <!-- 通过android:background指定背景 -->
    android:background="@drawable/bg_border" //红色边框,bg_border.xml如下
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 设置背景色为透明色 -->
    	<solid android:color="#0000"/>
    	<!-- 设置红色边框 -->
    	<stroke android:width="4px" android:color="#f00" />
    </shape>
    <!-- 通过android:drawableLeft绘制一张图片 -->
    android:background="@drawable/bg_border2" //圆角边框,渐变背景
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
    <!-- 指定圆角矩形的4个圆角的半径 -->
    	<corners 
    	    android:topLeftRadius="20px"
    	android:topRightRadius="5px"
    	android:bottomRightRadius="20px"
    	android:bottomLeftRadius="5px"/>
    	<!-- 指定边框线条的宽度和颜色 -->
    	<stroke android:width="4px" android:color="#f0f" />
    	<!-- 指定使用渐变背景色,使用sweep类型的渐变
    	颜色从红色→绿色→蓝色 -->
    	<gradient 
    	    android:startColor="#f00"
    	    android:centerColor="#0f0"
    	    android:endColor="#00f"
    	    android:type="sweep"/>
    </shape>
    <!--文本框默认提示 -->
    android:hint="请填写登录帐号"
    <!--只能接收数字密码 -->
    android:inputType="numberPassword"
    <!-- 数值输入框 -->
    android:inputType="number"
    <!-- 日期输入框 -->
    android:inputType="date"
    <!-- 电话号码的输入框 -->
    android:inputType="phone"
    <!-- 文字带阴影的按钮 -->
    android:shadowColor="#aa5"
    android:shadowRadius="1"
    android:shadowDx="5"
    android:shadowDy="5"
    <!-- 带文字的图片按钮-->
    android:background="@drawable/button_selector"//button_selector.xml如下所示
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    	<!-- 指定按钮按钮下时的图片 -->
    	<item 
    	    android:state_pressed="true"
    		android:drawable="@drawable/red"
    	/>
    	<!-- 指定按钮松开时的图片 -->	
    	<item 
    	    android:state_pressed="false"
    		android:drawable="@drawable/purple"
    	/>
    </selector>
    <!--单选框 -->
    <RadioGroup android:id="@+id/rg"
    	android:orientation="horizontal"
    	android:layout_gravity="center_horizontal">
    	<!-- 定义两个单选框 -->
    	<RadioButton 
    	    android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:id="@+id/male"
    		android:text="男"
    		android:checked="true" />
    	<RadioButton 
    	    android:layout_width="wrap_content"
    		android:layout_height="wrap_content"
    		android:id="@+id/female"
    		android:text="女" />
    </RadioGroup>
    <!--复选框 -->
    <CheckBox 
        android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:text="红色"
    	android:checked="true"/>
    <CheckBox 
        android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:text="蓝色"/>
    <CheckBox 
        android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:text="绿色" />
    <!-- ToggleButton状态开关按钮 -->
    <ToggleButton 
    android:id="@+id/toggle"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:textOff="横向排列"
    	android:textOn="纵向排列"
    	android:checked="true" />
    <!-- Switch开关按钮 -->
    <Switch android:id="@+id/switcher"
        android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:textOff="横向排列"
    	android:textOn="纵向排列"
    	android:thumb="@drawable/check"
    	android:checked="true"/>
    <!-- 模拟时钟 -->
    <AnalogClock  
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content" />
    <!-- 数字时钟 -->
    <DigitalClock
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content" 
    	android:textSize="14pt"
    	android:textColor="#f0f"
    	android:drawableRight="@drawable/ic_launcher" />
    <!-- 模拟时钟,并使用自定义表盘、时针图片 -->
    <AnalogClock  
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content" 
    	android:dial="@drawable/watch"
    	android:hand_minute="@drawable/hand"/>
    <!-- Chronometer计时器 -->
    <Chronometer
    	android:id="@+id/test"  
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content" 
    	android:textSize="12pt"
    	android:textColor="#ffff0000" />
    
    2.ImageView及其子类
    <!-- ZoomButton计缩放按钮 -->
    <ZoomButton
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    	android:id="@+id/btn_zoom_down"
    	android:src="@android:drawable/btn_minus" />
    <!-- ZoomControls缩放组件 -->
    <ZoomControls 
        android:id="@+id/zoomControls1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"/>
    <!-- QuickContactBadge关联联系人 -->
    <QuickContactBadge
    	android:id="@+id/badge"
    	android:layout_height="wrap_content"
    	android:layout_width="wrap_content"
    	android:src="@drawable/ic_launcher"/>
    QuickContactBadge badge = (QuickContactBadge) findViewById(R.id.badge);
    // 将QuickContactBadge组件与特定电话号码对应的联系人建立关联
    badge.assignContactFromPhone("15828560682", false);
    
    3. AdapterView及其子类
    AdapterView派生了三个子类:AbsListView , AbsSpinner ,和AdapterViewAnimator
    3.1、列表视图(ListView)和ListActivity
    创建ListView有如下两种方式:
    (1)、直接使用ListView创建
    (2)、让Activity继承ListActivity(相当于该Activity显示的组件为ListView)
    
    ListView、GridView、Spinner、Gallery等AdapterView都只是容器,而Adapter负责提供每个列表项组件,AdapterView则采用合适的方式显示这些表项。
    ListView的功能与用法:
    (1)、直接指定ListView的数组资源
    <ListView  
    	android:entries="@array/books" // 数组资源
    	android:divider="#f00" //红色分割线
    	android:dividerHeight="2px" //分割线宽度
    	android:headerDividersEnabled="false" //不会在页眉视图前画分隔符
    />
    
    Adapter常见的实现类如下:
    <1>.ArrayAdapter:简单、易用,通常用于数组或List集合的多个值包装成的列表项
    <2>.SimpleAdapter:不简单、功能强大,可用于将List集合的多个对象包装成列表项
    <3>.SimpleCursorAdapter:与SimpleAdapter基本相似,用于包装Cursor提供的数据
    <4>.BaseAdapter:通常用于扩展,可以对列表项进行最大限制的定制
    
    (2)、使用ArrayAdapter创建ListView
    // 定义一个数组
    String[] arr2 = { "Java", "Hibernate", "Spring" , "Android" };
    // 将数组包装ArrayAdapter
    ArrayAdapter<String> adapter2 = new 
    ArrayAdapter<String>(this, R.layout.checked_item, arr2);
    // 为ListView设置Adapter
    list2.setAdapter(adapter2);
    
    (3)、基于ListActivity实现列表
    String[] arr = { "孙悟空", "猪八戒", "唐僧" };
    // 创建ArrayAdapter对象
    ArrayAdapter<String> adapter = new ArrayAdapter<String>
    (this,android.R.layout.simple_list_item_multiple_choice, arr);
    // 设置该窗口显示列表
    setListAdapter(adapter);
    //界面布局文件中应该包含id为"@+id/android:list"的ListView
    <ListView 
    	android:id="@+id/android:list" 
    	...
    />
    
    (4)、使用SimpleAdapter创建ListView
    public class SimpleAdapterTest extends Activity
    {
    	private String[] names = new String[]
    		{ "虎头", "弄玉", "李清照", "李白"};
    	private String[] descs = new String[]
    		{ "可爱的小孩", "擅长音乐的女孩", "擅长文学的女性", "浪漫主义诗人"};
    	private int[] imageIds = new int[]
    		{ R.drawable.tiger , R.drawable.nongyu
    		, R.drawable.qingzhao , R.drawable.libai};
    	public void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		// 创建一个List集合,List集合的元素是Map
    		List<Map<String, Object>> listItems = 
    				new ArrayList<Map<String, Object>>();
    		for (int i = 0; i < names.length; i++)
    		{
    			Map<String, Object> listItem = new HashMap<String, Object>();
    			listItem.put("header", imageIds[i]);
    			listItem.put("personName", names[i]);
    			listItem.put("desc", descs[i]);
    			listItems.add(listItem);
    		}
    		// 创建一个SimpleAdapter
    		SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems,
    			R.layout.simple_item, 
    			new String[] { "personName", "header" , "desc"},
    			new int[] { R.id.name, R.id.header , R.id.desc });
    		ListView list = (ListView) findViewById(R.id.mylist);
    		// 为ListView设置Adapter
    		list.setAdapter(simpleAdapter);
    		// 为ListView的列表项单击事件绑定事件监听器
    		list.setOnItemClickListener(new OnItemClickListener()
    		{
    			// 第position项被单击时激发该方法。
    			public void onItemClick(AdapterView<?> parent, View view,int position, long id)
    			{
    				System.out.println(names[position]+ "被单击了");
    			}
    		});
    	}
    }
    
    (5)、扩展BaseAdapter实现不存储列表项的ListView
    public class BaseAdapterTest extends Activity
    {
    	ListView myList;
    	public void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		myList = (ListView) findViewById(R.id.myList);
    		BaseAdapter adapter = new BaseAdapter()
    		{
    			public int getCount()
    			{
    				// 指定一共包含40个选项
    				return 40;
    			}
    			public Object getItem(int position)
    			{
    				return null;
    			}
    			// 重写该方法,该方法的返回值将作为列表项的ID
    			public long getItemId(int position)
    			{
    				return position;
    			}
    			// 重写该方法,该方法返回的View将作为列表框
    			public View getView(int position, View convertView , ViewGroup parent)
    			{
    				// 创建一个LinearLayout,并向其中添加2个组件
    				LinearLayout line = new LinearLayout(BaseAdapterTest.this);
    				line.setOrientation(0);
    				ImageView image = new ImageView(BaseAdapterTest.this);
    				image.setImageResource(R.drawable.ic_launcher);
    				TextView text = new TextView(BaseAdapterTest.this);
    				text.setText("第" + (position +1 ) + "个列表项");
    				text.setTextSize(20);
    				text.setTextColor(Color.RED);
    				line.addView(image);
    				line.addView(text);
    				// 返回LinearLayout实例
    				return line;
    			}
    		};
    		myList.setAdapter(adapter);
    	}
    }
    
    以上方法完全适用于AdapterView的其他类:GridView、Spinner、Gallery、AdapterViewFlipper等。
    
    自动完成文本框(AutoCompleteTextView)的功能和用法
    <!-- 定义一个自动完成文本框,指定输入一个字符后进行提示 -->
    <AutoCompleteTextView
    	android:id="@+id/auto"
    	android:layout_width="fill_parent" 
    	android:layout_height="wrap_content" 
    	android:completionHint="请选择您喜欢的图书:"
    	android:dropDownHorizontalOffset="10dp"
    	android:completionThreshold="1"/>
    <!-- 定义一个MultiAutoCompleteTextView组件 -->
    <MultiAutoCompleteTextView
        android:id="@+id/mauto"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    	android:completionThreshold="1"/>
    
    网格视图(GridView)功能与用法
    <GridView  
    	android:horizontalSpacing="1pt"
    	android:verticalSpacing="1pt"
    	android:numColumns="4"
    	android:gravity="center"
    	……
    />
    
    // 创建一个List对象,List对象的元素是Map
    List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
    for (int i = 0; i < imageIds.length; i++)
    {
    	Map<String, Object> listItem = new HashMap<String, Object>();
    	listItem.put("image", imageIds[i]);
    	listItems.add(listItem);
    }
    // 创建一个SimpleAdapter
    SimpleAdapter simpleAdapter = new SimpleAdapter(this,listItems, R.layout.cell, new String[] { "image" },new int[] { R.id.image1 });
    // 使用/layout/cell.xml文件作为界面布局
    // 为GridView设置Adapter
    grid.setAdapter(simpleAdapter);
    
    可展开的列表组件(ExpandableListView)
    <ExpandableListView
    	android:id="@+id/list"
    	android:layout_width="fill_parent" 
    	android:layout_height="wrap_content" 
    	android:childIndicator="@drawable/ic_launcher"
    />
    public class ExpandableListViewTest extends Activity
    {
    	public void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		//创建一个BaseExpandableListAdapter对象
    		ExpandableListAdapter adapter = new BaseExpandableListAdapter()
    		{
    			int[] logos = new int[]
    			{
    				R.drawable.p,
    				R.drawable.z,
    				R.drawable.t
    			};
    			private String[] armTypes = new String[]
    				{ "神族兵种", "虫族兵种", "人族兵种"};
    			private String[][] arms = new String[][]
    			{
    				{ "狂战士", "龙骑士", "黑暗圣堂", "电兵" },
    				{ "小狗", "刺蛇", "飞龙", "自爆飞机" },
    				{ "机枪兵", "护士MM" , "幽灵" }
    			};
    			// 获取指定组位置、指定子列表项处的子列表项数据
    			public Object getChild(int groupPosition, int childPosition)
    			{
    				return arms[groupPosition][childPosition];
    			}
    			public long getChildId(int groupPosition, int childPosition)
    			{
    				return childPosition;
    			}
    			public int getChildrenCount(int groupPosition)
    			{
    				return arms[groupPosition].length;
    			}
    			private TextView getTextView()
    			{
    				AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
    						ViewGroup.LayoutParams.MATCH_PARENT, 64);
    				TextView textView = new TextView(ExpandableListViewTest.this);
    				textView.setLayoutParams(lp);
    				textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
    				textView.setPadding(36, 0, 0, 0);
    				textView.setTextSize(20);
    				return textView;
    			}
    			// 该方法决定每个子选项的外观
    			public View getChildView(int groupPosition, int childPosition,
    					boolean isLastChild, View convertView, ViewGroup parent)
    			{
    				TextView textView = getTextView();
    				textView.setText(getChild(groupPosition, childPosition).toString());
    				return textView;
    			}
    			// 获取指定组位置处的组数据
    			public Object getGroup(int groupPosition)
    			{
    				return armTypes[groupPosition];
    			}
    			public int getGroupCount()
    			{
    				return armTypes.length;
    			}
    			public long getGroupId(int groupPosition)
    			{
    				return groupPosition;
    			}
    			// 该方法决定每个组选项的外观
    			public View getGroupView(int groupPosition, boolean isExpanded,
    					View convertView, ViewGroup parent)
    			{
    				LinearLayout ll = new LinearLayout(ExpandableListViewTest.this);
    				ll.setOrientation(0);
    				ImageView logo = new ImageView(ExpandableListViewTest.this);
    				logo.setImageResource(logos[groupPosition]);
    				ll.addView(logo);
    				TextView textView = getTextView();
    				textView.setText(getGroup(groupPosition).toString());
    				ll.addView(textView);
    				return ll;
    			}
    			public boolean isChildSelectable(int groupPosition,
    					int childPosition)
    			{
    				return true;
    			}
    			public boolean hasStableIds()
    			{
    				return true;
    			}
    		};
    		ExpandableListView expandListView = (ExpandableListView) findViewById(R.id.list);
    		expandListView.setAdapter(adapter);
    	}
    }
    
    列表选择框(Spinner)的功能和用法
    <!-- 定义了一个Spinner组件,指定该显示该Spinner组件的数组 -->
    <Spinner
    	……
    	android:entries="@array/books" 
    	android:prompt="@string/tip"
    />
    
    <Spinner
    	android:id="@+id/spinner"
    	android:prompt="@string/tip"
    	......
    />
    String[] arr = { "孙悟空", "猪八戒", "唐僧" };
    // 创建ArrayAdapter对象
    ArrayAdapter<String> adapter = new ArrayAdapter<String>
    (this,android.R.layout.simple_list_item_multiple_choice, arr);
    // 为Spinner设置Adapter
    spinner.setAdapter(adapter);
    
    画廊视图(Gallery)的功能和用法(已经过时,用ViewPager和HorizontalScrollView代替,新平台上尽量少用Gallery组件)
    <!-- 定义一个Gallery组件 -->
    <Gallery 
    	android:id="@+id/gallery"
    	android:layout_marginTop="2dp" 
    	android:unselectedAlpha="0.6" //未被选中时的透明度
    	android:spacing="2pt"
    	......
    />
    BaseAdapter adapter = new BaseAdapter()
    {
    	public int getCount()
    	{
    		return imageIds.length;
    	}
    	public Object getItem(int position)
    	{
    		return position;
    	}
    	public long getItemId(int position)
    	{
    		return position;
    	}
    	// 该方法的返回的View就是代表了每个列表项
    	public View getView(int position, View convertView, ViewGroup parent)
    	{
    		// 创建一个ImageView
    		ImageView imageView = new ImageView(GallaryTest.this);
    		imageView.setImageResource(imageIds[position]);
    		// 设置ImageView的缩放类型
    		imageView.setScaleType(ImageView.ScaleType.FIT_XY);
    		// 为imageView设置布局参数
    		imageView.setLayoutParams(new Gallery.LayoutParams(75, 100));
    		TypedArray typedArray = obtainStyledAttributes(R.styleable.Gallery);
    	imageView.setBackgroundResource(typedArray.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0));
    		return imageView;
    	}
    };
    gallery.setAdapter(adapter);
    
    AdapterViewFlipper的功能与用法
    AdapterViewFlipper继承了AdapterViewAnimator,它也会显示Adapter提供的多个View组件,但它每次只能显示一个View组件,程序可通过showPrevious()和showNext()方法控制该组件显示上一个、下一个组件,还可以调用startFlipping()控制它“自动播放”下一个View组件。
    ----自动播放的图片库----
    <AdapterViewFlipper
    	android:id="@+id/flipper"
    	android:layout_width="match_parent"
    	android:layout_height="match_parent"
    	android:flipInterval="5000" //每个五秒自动切换
    	android:layout_alignParentTop="true"
    />
    
    BaseAdapter adapter = new BaseAdapter()
    {
    	public int getCount()
    	{
    		return imageIds.length;
    	}
    	public Object getItem(int position)
    	{
    		return position;
    	}
    	public long getItemId(int position)
    	{
    		return position;
    	}
    	// 该方法的返回的View就是代表了每个列表项
    	public View getView(int position, View convertView, ViewGroup parent)
    	{
    		// 创建一个ImageView
    		ImageView imageView = new ImageView(AdapterViewFlipperTest.this);
    		imageView.setImageResource(imageIds[position]);
    		// 设置ImageView的缩放类型
    		imageView.setScaleType(ImageView.ScaleType.FIT_XY);
    		// 为imageView设置布局参数
    		imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
    		return imageView;
    	}
    };
    flipper.setAdapter(adapter);
    
    // 显示上一个组件
    flipper.showPrevious();
    // 显示下一个组件
    flipper.showNext();
    // 开始自动播放
    flipper.startFlipping();
    // 停止自动播放
    flipper.stopFlipping();
    
    StackView的功能与用法
    StackView也是AdapterViewAnimator的子类,它也用于显示Adapter提供的系列View。StackView将会以”堆叠”的方式来显示多个列表项。程序可通过showPrevious()和showNext()方法控制该组件显示上一个、下一个组件。
    为了控制StackView显示的View,StackView提供了两种控制方式:
    1>.拖走StackView中处于顶端的View,下一个View将会显示出来
    2>.将上一个View拖进StackView,将使之显示出来
    <StackView
    	android:id="@+id/mStackView"
    	android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    	android:loopViews="true" //循环
    />
    
    stackView = (StackView) findViewById(R.id.mStackView);
    // 创建一个List对象,List对象的元素是Map
    List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
    for (int i = 0; i < imageIds.length; i++)
    {
    	Map<String, Object> listItem = new HashMap<String, Object>();
    	listItem.put("image", imageIds[i]);
    	listItems.add(listItem);
    }
    // 创建一个SimpleAdapter
    SimpleAdapter simpleAdapter = new SimpleAdapter(this,listItems, R.layout.cell, new String[] { "image" },new int[] { R.id.image1 });
    // 使用/layout/cell.xml文件作为界面布局		
    stackView.setAdapter(simpleAdapter);
    
    // 显示上一个组件
    stackView.showPrevious();
    // 显示下一个组件
    stackView.showNext();
    
    4. ProgressBar及其子类
    ProgressBar的用法
    <!-- 定义一个大环形进度条 -->
    <ProgressBar
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content"
    	style="@android:style/Widget.ProgressBar.Large"
    />
    <!-- 定义一个中等大小的环形进度条 -->
    <ProgressBar
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content"
    />
    <!-- 定义一个小环形进度条 -->
    <ProgressBar
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content"
    	style="@android:style/Widget.ProgressBar.Small"
    />
    <!-- 定义一个水平进度条 -->
    <ProgressBar
    	android:id="@+id/bar"
    	android:layout_width="fill_parent" 
    	android:layout_height="wrap_content"
    	android:max="100"
    	style="@android:style/Widget.ProgressBar.Horizontal"
    />
    <!-- 定义一个水平进度条,并改变轨道外观 -->
    <ProgressBar
    	android:id="@+id/bar2"
    	android:layout_width="fill_parent" 
    	android:layout_height="wrap_content"
    	android:max="100"
    	android:progressDrawable="@drawable/my_bar"
    	style="@android:style/Widget.ProgressBar.Horizontal"
    />
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    	<!-- 定义轨道的背景 -->
    	<item 
    	    android:id="@android:id/background"
    		android:drawable="@drawable/no" 
    	/>
    	<!-- 定义轨道上已完成部分的样式 -->
    	<item 
    	    android:id="@android:id/progress"
    		android:drawable="@drawable/ok" 
    	/>
    </layer-list>
    
    显示在标题上的进度条
    //设置窗口特征:启用显示进度的进度条
    requestWindowFeature(Window.FEATURE_PROGRESS);  //①
    //显示带进度的进度条。
    setProgressBarVisibility(true);
    //设置进度条的进度
    setProgress(4500);
    //隐藏带进度的进度条。
    setProgressBarVisibility(false);
    
    //设置窗口特征:启用不显示进度的进度条
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); //②
    //显示不带进度的进度条。
    setProgressBarIndeterminateVisibility(true);
    //隐藏不带进度的进度条。
    setProgressBarIndeterminateVisibility(false);
    
    拖动条(SeekBar)的功能和用法
    <!-- 定义一个拖动条,并改变它的滑块外观 -->
    <SeekBar
    	android:id="@+id/seekbar"
    	android:layout_width="fill_parent" 
    	android:layout_height="wrap_content" 
    	android:max="255"
    	android:progress="255"
    	android:thumb="@drawable/ic_launcher" //拖动条上的滑块
    />
    
    星级评分条(RatingBar)
    <!-- 定义一个星级评分条 -->	
    <RatingBar 
    	android:id="@+id/rating"
    	android:layout_width="wrap_content" 
    	android:layout_height="wrap_content" 
    	android:numStars="5" //5颗星
    	android:max="255"
    	android:progress="255"
    	android:stepSize="0.5" //最小值0.5
    />
    
    5.ViewAnimator及其子类
    ViewAnimator是一个基类,它继承了FrameLayout,因此它表现出了FrameLayout的特征,可以将多个View组件”叠”在一起。
    ViewSwitcher的功能与用法
    ViewSwitcher代表了视图切换组件,它本身继承了FrameLayout,因此可以将多个View层叠在一起,每次只显示一个组件,当程序控制从一个View切换到另一个View时,ViewSwitcher支持指定动画效果。
    为了给ViewSwitcher添加多个组件,一般通过调用ViewSwitcher的setFactory(ViewSwitcher.ViewFactory)方法为之设置ViewFactory,并由该ViewFactory为之创建View即可。
    
    <!-- 定义一个ViewSwitcher组件 -->
    <ViewSwitcher
    	android:id="@+id/viewSwitcher"
    	android:layout_width="fill_parent"
    	android:layout_height="fill_parent" 
    />
    switcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
    switcher.setFactory(new ViewFactory()
    {
    	// 实际上就是返回一个GridView组件
    	public View makeView()
    	{
    		// 加载R.layout.slidelistview组件,实际上就是一个GridView组件。
    		return inflater.inflate(R.layout.slidelistview, null);
    	}
    });
    
    ImageSwitcher的用法
    1>.为ImageSwitcher提供一个ViewFactory,该Factory生成的View组件必须是ImageView
    2>.需要切换图片时,只需要调用ImageSwitcher的setImageDrawable(Drawable drawable)、setImageResource(int resid)和setImageURI(Uri uri)
    
    <!-- 定义一个ImageSwitcher组件 -->
    <ImageSwitcher android:id="@+id/switcher"
    	android:layout_width="300dp"
    	android:layout_height="300dp"
    	android:layout_gravity="center_horizontal"
    	android:inAnimation="@android:anim/fade_in"
    	android:outAnimation="@android:anim/fade_out"
    />
    // 获取显示图片的ImageSwitcher
    switcher = (ImageSwitcher)findViewById(R.id.switcher);
    // 为ImageSwitcher设置图片切换的动画效果
    switcher.setFactory(new ViewFactory()
    {
    	public View makeView()
    	{
    		// 创建ImageView对象
    		ImageView imageView = new ImageView(Main.this);
    		imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
    		imageView.setLayoutParams(new ImageSwitcher.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    		// 返回ImageView对象
    		return imageView;
    	}
    });
    
    TextSwitcher的用法
    1>.TextSwitcher需要设置一个ViewFactory,该Factory生成的View组件必须是TextView
    2>.需要切换文本时,只需要调用TextSwitcher的setText();方法修改即可
    <!-- 定义一个TextSwitcher,并指定了文本切换时的动画效果 -->
    <TextSwitcher
        android:id="@+id/textSwitcher"
    	android:layout_width="match_parent"
    	android:layout_height="wrap_content"
    	android:inAnimation="@android:anim/slide_in_left"
    	android:outAnimation="@android:anim/slide_out_right"
    	android:onClick="next"
    />
    textSwitcher = (TextSwitcher) findViewById(R.id.textSwitcher);
    textSwitcher.setFactory(new ViewSwitcher.ViewFactory()
    {
    	public View makeView()
    	{
    		TextView tv = new TextView(TextSwitcherTest.this);
    		tv.setTextSize(40);
    		tv.setTextColor(Color.MAGENTA);
    		return tv;
    	}
    });
    // 调用next方法显示下一个字符串
    next(null);
    // 事件处理函数,控制显示下一个字符串
    public void next(View source)
    {
    	textSwitcher.setText(strs[curStr++ % strs.length]); 
    }
    
    ViewFlipper的功能与用法
    	ViewFlipper是继承了ViewAnimator,它调用了addView(View v)添加多个组件,一旦向ViewFlipper中添加了多个组件后,ViewFlipper可以使用动画控制多个组件切换的效果。
    	ViewFlipper与AdapterViewFlipper有较大的相似性,他们的区别是:ViewFlipper需要开发者通过addView(View v)添加多个组件,而AdapterViewFlipper则只要传入一个Adapter,Adapter将会负责提供多个View。
    
    <ViewFlipper
    	android:id="@+id/details"
    	android:layout_width="match_parent"
    	android:layout_height="match_parent"
    	android:persistentDrawingCache="animation"
    	android:flipInterval="1000" >
    	
    	<ImageView
    		android:src="@drawable/ee"
    		android:layout_width="fill_parent"
    		android:layout_height="wrap_content">
    	</ImageView>
    	......添加组件......
    	<ImageView
    		android:src="@drawable/ee"
    		android:layout_width="fill_parent"
    		android:layout_height="wrap_content">
    	</ImageView>
    </ViewFlipper>
    
    6.其他杂项组件
    <1>.Toast
    Toast具有如下两个特点:
    ☆.Toast提示信息不会获得焦点
    ☆.Toast提示信息过一段时间会自动消失
    
    <-----创建一个简单的Toast提示信息----->
    Toast toast = Toast.makeText(Main.this, "简单的提示信息", Toast.LENGTH_SHORT);
    toast.show();
    
    <-----创建一个带图片的Toast提示信息----->
    Toast toast = new Toast(Main.this);
    // 设置Toast的显示位置
    toast.setGravity(Gravity.CENTER, 0, 0);
    // 创建一个ImageView
    ImageView image = new ImageView(Main.this);
    image.setImageResource(R.drawable.tools);
    // 创建一个LinearLayout容器
    LinearLayout ll = new LinearLayout(Main.this);
    ll.setBackgroundColor(Color.BLACK);
    // 向LinearLayout中添加图片、原有的View
    ll.addView(image);
    // 创建一个ImageView
    TextView textView = new TextView(Main.this);
    textView.setText("带图片的提示信息");
    // 设置文本框内字体的大小和颜色
    textView.setTextSize(30);
    textView.setTextColor(Color.MAGENTA);
    ll.addView(textView);
    // 设置Toast显示自定义View				
    toast.setView(ll);
    // 设置Toast的显示时间
    toast.setDuration(Toast.LENGTH_LONG);
    toast.show();
    
    
    <2>.CalendarView
    <!--CalendarView-->
    <CalendarView
    	android:layout_width="400dp"
    	android:layout_height="500dp"
    	android:firstDayOfWeek="2" //以星期一作为每周第一天
    	android:shownWeekCount="6" //该组件总共显示6个星期
    	android:selectedWeekBackgroundColor="#ffffcc" //被选中周的背景色
    	android:focusedMonthDateColor="#cc0066" //获得焦点月份的日期颜色
    	android:weekSeparatorLineColor="#000033"
    	android:unfocusedMonthDateColor="#c0c0c0" //没有焦点的日期文字的颜色
    	android:id="@+id/calendarView" 
    />
    cv = (CalendarView)findViewById(R.id.calendarView);
    // 为CalendarView组件的日期改变事件添加事件监听器
    cv.setOnDateChangeListener(new OnDateChangeListener()
    {
    	public void onSelectedDayChange(CalendarView view, int year,int month, int dayOfMonth)
    	{
    		// 使用Toast显示用户选择的日期
    		Toast.makeText(CalendarViewTest.this,"你生日是" + year + "年" + month + "月" + dayOfMonth + "日" ,Toast.LENGTH_SHORT).show();
    	}
    });
    
    <3>.DatePicker/TimePicker、NumberPicker
    <!-- 定义一个DatePicker组件 -->
    <DatePicker 
    	android:id="@+id/datePicker"
    	android:layout_width="wrap_content" 
    	android:layout_height="200dp"
    	android:layout_gravity="center_horizontal"
    	android:startYear="2000"
    	android:endYear="2012"
    	android:calendarViewShown="true"
    	android:spinnersShown="true"
    />
    <!-- 定义一个TimePicker组件 -->
    <TimePicker 
    	android:id="@+id/timePicker"
    	android:layout_width="wrap_content" 
    	android:layout_height="100dp"
    	android:layout_gravity="center_horizontal"
    />
    
    // 获取当前的年、月、日、小时、分钟
    Calendar c = Calendar.getInstance();
    year = c.get(Calendar.YEAR);
    month = c.get(Calendar.MONTH);
    day = c.get(Calendar.DAY_OF_MONTH);
    hour = c.get(Calendar.HOUR);
    minute = c.get(Calendar.MINUTE);
    // 初始化DatePicker组件,初始化时指定监听器
    datePicker.init(year, month, day, new OnDateChangedListener()
    {
    	public void onDateChanged(DatePicker arg0, int year, int month, int day)
    	{
    		ChooseDate.this.year = year;
    		ChooseDate.this.month = month;
    		ChooseDate.this.day = day;
    		// 显示当前日期、时间
    		showDate(year, month, day, hour, minute);// 在EditText中显示当前日期、时间的方法
    	}
    });
    // 为TimePicker指定监听器
    timePicker.setOnTimeChangedListener(new OnTimeChangedListener()
    {
    	public void onTimeChanged(TimePicker view, int hourOfDay, int minute)
    	{
    		ChooseDate.this.hour = hourOfDay;
    		ChooseDate.this.minute = minute;
    		// 显示当前日期、时间
    		showDate(year, month, day, hour, minute); // 在EditText中显示当前日期、时间的方法
    	}
    });
    
    <!-- 定义一个NumberPicker组件 -->
    <NumberPicker
    	android:id="@+id/np1"
    	android:layout_width="match_parent"
    	android:layout_height="80dp"
    	android:focusable="true"
    	android:focusableInTouchMode="true" 
    />
    // 设置np1的最小值和最大值
    np1.setMinValue(10);
    np1.setMaxValue(50);
    // 设置np1的当前值
    np1.setValue(25);
    
    <4>.SearchView
    <!-- 定义一个SearchView -->
    <SearchView
    	android:id="@+id/sv"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    />
    public class Main implements SearchView.OnQueryTextListener extends Activity
    {
    	// 设置该SearchView默认是否自动缩小为图标
    	sv.setIconifiedByDefault(true);
    	// 为该SearchView组件设置事件监听器
    	sv.setOnQueryTextListener(this);
    	// 设置该SearchView显示搜索按钮
    	sv.setSubmitButtonEnabled(true);
    	// 设置该SearchView内默认显示的提示文本
    	sv.setQueryHint("查找");
    
    
    	// 用户输入字符时激发该方法
    	@Override
    	public boolean onQueryTextChange(String newText)
    	{
    		if (TextUtils.isEmpty(newText))
    		{
    			// 清除ListView的过滤
    			lv.clearTextFilter();
    		}
    		else
    		{
    			// 使用用户输入的内容对ListView的列表项进行过滤
    			lv.setFilterText(newText);
    		}
    		return true;
    	}
    
    
    	// 单击搜索按钮时激发该方法
    	@Override
    	public boolean onQueryTextSubmit(String query)
    	{
    		// 实际应用中应该在该方法内执行实际查询
    		// 此处仅使用Toast显示用户输入的查询内容
    		Toast.makeText(this, "您的选择是:" + query
    				, Toast.LENGTH_SHORT).show();
    		return false;
    	}
    }
    
    <5>.TabHost(标签页)
    <?xml version="1.0" encoding="utf-8"?>
    <TabHost xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/tabhost"
    >
    	<LinearLayout
    	android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical"
    	>
    		<TabWidget
    		android:layout_width="fill_parent"
    	android:layout_height="wrap_content"
    	android:id="@android:id/tabs"
    		/>
    		<FrameLayout
    		android:layout_width="fill_parent"
    	android:layout_height="fill_parent"
    	android:id="@android:id/tabcontent"
    		>
    			<LinearLayout
    			android:layout_width="fill_parent"
    		android:layout_height="fill_parent"
    		android:id="@+id/page1"
    			>
    			<TextView
    							   />
    			</LinearLayout>
    		
    		<LinearLayout
    			android:layout_width="fill_parent"
    		android:layout_height="fill_parent"
    		android:id="@+id/page2"
    			>
    			<TextView
    							   />
    			</LinearLayout>
    			
    		<LinearLayout
    			android:layout_width="fill_parent"
    		android:layout_height="fill_parent"
    		android:id="@+id/page3"
    			>
    			<TextView
    							   />
    			</LinearLayout>
    		</FrameLayout>
    	</LinearLayout>
    </TabHost>
    
    tabHost.setup();
    TabSpec tabSpec = tabHost.newTabSpec("page1");
    //tabSpec.setIndicator("首页", getResources().getDrawable(R.drawable.i1));
    tabSpec.setIndicator(createTabView("首页"));// createTabView()创建标题View
    tabSpec.setContent(R.id.page1);
    tabHost.addTab(tabSpec);
    
    <6>.ScrollView
    <!-- 定义ScrollView,为里面的组件添加垂直滚动条 -->
    <!-- ScrollView里最多只能包含一个组件 -->
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    	android:layout_width="match_parent"
    	android:layout_height="match_parent" >
    <!-- 定义HorizontalScrollView,为里面的组件添加水平滚动条 -->	
    <HorizontalScrollView
    	android:layout_width="fill_parent" 
    	android:layout_height="wrap_content" >
    	<LinearLayout 
    		android:orientation="vertical"
    		android:layout_width="match_parent"
    		android:layout_height="fill_parent" 
    	>
    		<TextView 
    		...... 
    		/>
    	</LinearLayout>
    </HorizontalScrollView>
    </ScrollView>
    
    <7>.Notification
    // 获取系统的NotificationManager服务
    NotificationManager nm = 
    (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
    Notification notify = new Notification.Builder(this)
    // 设置打开该通知,该通知自动消失
    .setAutoCancel(true)
    // 设置显示在状态栏的通知提示信息
    .setTicker("有新消息")
    // 设置通知的图标
    .setSmallIcon(R.drawable.notify)
    // 设置通知内容的标题
    .setContentTitle("一条新通知")
    // 设置通知内容
    .setContentText("恭喜你,您加薪了,工资增加20%!")
    // 设置使用系统默认的声音、默认LED灯
    //.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS)
    // 设置通知的自定义声音
    .setSound(Uri.parse("android.resource://org.crazyit.ui/"+ R.raw.msg))
    .setWhen(System.currentTimeMillis())
    // 设改通知将要启动程序的Intent
    .setContentIntent(pi).build();
    // 发送通知
    nm.notify(NOTIFICATION_ID, notify);
    
    
    三、对话框
    Android提供了4种常用的对话框:
    1.AlertDialog:功能最丰富、实际应用最广的对话框
    2.ProgressDialog:进度对话框,这个对话框只是对简单进度条的封装
    3.DatePickerDialog:日期选择对话框,这个对话框只是对DatePicker的包装
    4.TimePickerDialog:时间选择对话框,这个对话框只是对TimePicker的包装
    
    < ---AlertDialog--- >
    AlertDialog生成的对话框可分为4个区域:
    1>.图标区
    2>.标题区
    3>.内容区
    4>.按钮区
    
    创建对话框步骤:
    1>.使用创建AlertDialog.Builder对象
    2>.调用AlertDialog.Builder的setTitle()或setCustomTitle方法设置标题
    3>.调用AlertDialog.Builder的setIcon方法设置标题
    4>.调用AlertDialog.Builder的相关方法设置对话框内容
    5>.调用AlertDialog.Builder的setPositiviteButton、setNegativiteButton或setNeutralButton方法添加多个按钮
    6>.调用AlertDialog.Builder的create()方法创建AlertDialog对象,再调用AlertDialog对象的show()方法将对话框显示出来
    
    AlertDialog提供了6种方法来指定对话框的内容
    1>.setMessage():设置对话框内容为简单文本
    2>.setItems():设置对话框内容为简单列表项
    3>.setSingleChoiceItems():设置对话框内容为单选列表项
    4>.setMultiChoiceItems():设置对话框内容为多选列表项
    5>.setAdapter():设置对话框内容为自定义列表项
    6>.setView():设置对话框内容为自定义View
    
    AlertDialog.Builder builder = new AlertDialog.Builder(this);//创建对象
    builder.setTitle("对话框");// 设置对话框标题
    builder.setIcon(R.drawable.tools);// 设置对话框的图标
    
    builder.setMessage("对话框的测试内容\n第二行内容"); //设置简单内容
    builder.setItems(items, new OnClickListener()
    			{
    				@Override
    				public void onClick(DialogInterface dialog, int which)
    				{
    					show.setText("你选中了《" + items[which] + "》");
    				}
    			});// 设置简单的列表项内容
    builder.setSingleChoiceItems(items, 1, new OnClickListener()
    			{
    				@Override
    				public void onClick(DialogInterface dialog, int which)
    				{
    					show.setText("你选中了《" + items[which] + "》");
    				}
    			});// 设置单选列表项,默认选中第二项(索引为1)
    builder.builder.setMultiChoiceItems(items, 
    new boolean[]{false , true ,false ,true}, null);
    // 设置多选列表项,设置勾选第2项、第4项
    builder.setAdapter(new ArrayAdapter<String>(this , R.layout.array_item , items), null);// 设置自定义列表项
    builder.setView(loginForm);// 设置对话框显示的View对象
    
    setPositiveButton(builder);// 添加【确定】按钮
    setNegativeButton(builder);//添加【取消】按钮
    builder.create().show();//创建,显示对话框
    
    builder.setPositiveButton("登录" , new OnClickListener()
    {
    	@Override
    	public void onClick(DialogInterface dialog,int which)
    	{
    		// 此处可执行登录处理
    	}
    });
    
    private AlertDialog.Builder setPositiveButton(AlertDialog.Builder builder)
    {
    	// 调用setPositiveButton方法添加确定按钮
    	return builder.setPositiveButton("确定", new OnClickListener()
    	{
    		@Override
    		public void onClick(DialogInterface dialog, int which)
    		{
    			show.setText("单击了【确定】按钮!");
    		}
    	});
    }
    
    < ---对话框风格窗口--- >
    android:theme="@android:style/Theme.Dialog"//以对话框形式显示activity
    
    < ---使用PopupWindow--- >
    // 装载R.layout.popup对应的界面布局
    View root = this.getLayoutInflater().inflate(R.layout.popup, null);
    // 创建PopupWindow对象
    final PopupWindow popup = new PopupWindow(root, 280, 360);
    //popup.showAsDropDown(v);// 以下拉方式显示。
    //将PopupWindow显示在指定位置
    popup.showAtLocation(findViewById(R.id.bn), Gravity.CENTER, 20,20);
    
    < ---使用DatePickerDialog/TimePickerDialog--- >
    Calendar c = Calendar.getInstance();
    // 直接创建一个DatePickerDialog对话框实例,并将它显示出来
    new DatePickerDialog(DateDialogTest.this,
    	// 绑定监听器
    	new DatePickerDialog.OnDateSetListener()
    	{
    		@Override
    		public void onDateSet(DatePicker dp, int year,int month, int dayOfMonth)
    		{
    			EditText show = (EditText) findViewById(R.id.show);
    			show.setText("您选择了:" + year + "年" + (month + 1)+ "月" + dayOfMonth + "日");
    		}
    	}
    	//设置初始日期
    	, c.get(Calendar.YEAR)
    	, c.get(Calendar.MONTH)
    	, c.get(Calendar.DAY_OF_MONTH)).show();
    
    Calendar c = Calendar.getInstance();
    // 创建一个TimePickerDialog实例,并把它显示出来。
    new TimePickerDialog(DateDialogTest.this,
    	// 绑定监听器
    	new TimePickerDialog.OnTimeSetListener()
    	{
    		@Override
    		public void onTimeSet(TimePicker tp, int hourOfDay,int minute)
    		{
    			EditText show = (EditText) findViewById(R.id.show);
    			show.setText("您选择了:" + hourOfDay + "时" + minute+ "分");
    		}
    	}
    	//设置初始时间
    	, c.get(Calendar.HOUR_OF_DAY)
    	, c.get(Calendar.MINUTE)
    	//true表示采用24小时制
    	, true).show();
    
    < ---使用ProgressDialog创建进度对话框 --- >
    // 调用静态方法显示环形进度条
    ProgressDialog.show(this, "任务执行中", "任务执行中,请等待", false, true); //①环形进度对话框
    
    ProgressDialog pd1 = new ProgressDialog(ProgressDialogTest.this);
    // 设置对话框的标题
    pd1.setTitle("任务正在执行中");
    // 设置对话框显示的内容
    pd1.setMessage("任务正在执行中,敬请等待...");
    // 设置对话框能用“取消”按钮关闭
    pd1.setCancelable(true);
    // 设置对话框的进度条风格
    pd1.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    // 设置对话框的进度条是否显示进度
    pd1.setIndeterminate(true);
    pd1.show(); //②不显示进度的进度条对话框
    
    // 将进度条的完成进度重设为0
    progressStatus = 0;
    // 重新开始填充数组。
    hasData = 0;
    ProgressDialog  pd2 = new ProgressDialog(ProgressDialogTest.this);
    pd2.setMax(MAX_PROGRESS);
    // 设置对话框的标题
    pd2.setTitle("任务完成百分比");
    // 设置对话框 显示的内容
    pd2.setMessage("耗时任务的完成百分比");
    // 设置对话框不能用“取消”按钮关闭
    pd2.setCancelable(false);
    // 设置对话框的进度条风格
    pd2.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    // 设置对话框的进度条是否显示进度
    pd2.setIndeterminate(false);
    pd2.show(); //③显示进度条的进度对话框
    
    
    四、菜单
    < ------------选项菜单和子菜单----------- >
    // 当用户单击MENU键时触发该方法
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
    	// -------------向menu中添加字体大小的子菜单-------------
    	SubMenu fontMenu = menu.addSubMenu("字体大小");
    	// 设置菜单的图标
    	fontMenu.setIcon(R.drawable.font);
    	// 设置菜单头的图标
    	fontMenu.setHeaderIcon(R.drawable.font);
    	// 设置菜单头的标题
    	fontMenu.setHeaderTitle("选择字体大小");
    	fontMenu.add(0, FONT_10, 0, "10号字体");
    	fontMenu.add(0, FONT_12, 0, "12号字体");
    	// -------------向menu中添加普通菜单项-------------
    	menu.add(0, PLAIN_ITEM, 0, "普通菜单项");
    	// -------------向menu中添加文字颜色的子菜单-------------
    	SubMenu colorMenu = menu.addSubMenu("字体颜色");
    	colorMenu.setIcon(R.drawable.color);
    	// 设置菜单头的图标
    	colorMenu.setHeaderIcon(R.drawable.color);
    	// 设置菜单头的标题
    	colorMenu.setHeaderTitle("选择文字颜色");
    	colorMenu.add(0, FONT_RED, 0, "红色");
    	colorMenu.add(0, FONT_GREEN, 0, "绿色");
    	return super.onCreateOptionsMenu(menu);
    }
    
    @Override
    // 选项菜单的菜单项被单击后的回调方法
    public boolean onOptionsItemSelected(MenuItem mi)
    {
    	//判断单击的是哪个菜单项,并针对性的作出响应。
    	switch (mi.getItemId())
    	{
    	case FONT_10:
    		edit.setTextSize(10 * 2);
    		break;
    	case FONT_12:
    		edit.setTextSize(12 * 2);
    		break;
    	case FONT_RED:
    		edit.setTextColor(Color.RED);
    		break;
    	case FONT_GREEN:
    		edit.setTextColor(Color.GREEN);
    		break;
    	case PLAIN_ITEM:
    		Toast toast = Toast.makeText(MenuTest.this, "您单击了普通菜单项" , Toast.LENGTH_SHORT).show();
    		break;
    	}
    	return true;
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
    	// -------------向menu中添加子菜单-------------
    	SubMenu prog = menu.addSubMenu("启动程序");
    	// 设置菜单头的图标
    	prog.setHeaderIcon(R.drawable.tools);
    	// 设置菜单头的标题
    	prog.setHeaderTitle("选择您要启动的程序");
    	// 添加菜单项
    	MenuItem item = prog.add("查看经典Java EE");
    	//为菜单项设置关联的Activity
    	item.setIntent(new Intent(this , OtherActivity.class));
    	return super.onCreateOptionsMenu(menu);
    }
    
    < ------------上下文菜单----------- >
    // 为文本框注册上下文菜单
    registerForContextMenu(txt);
    // 创建上下文菜单时触发该方法
    @Override
    public void onCreateContextMenu(ContextMenu menu, View source,
    ContextMenu.ContextMenuInfo menuInfo)
    {
    	menu.add(0, MENU1, 0, "红色");
    	menu.add(0, MENU2, 0, "绿色");
    	// 将三个菜单项设为单选菜单项
    	menu.setGroupCheckable(0, true, true); //第三个参数为true则为单选
    	//设置上下文菜单的标题、图标
    	menu.setHeaderIcon(R.drawable.tools);
    	menu.setHeaderTitle("选择背景色");
    }
    
    // 上下菜单的菜单项被单击时触发该方法。
    @Override
    public boolean onContextItemSelected(MenuItem mi)
    {
    	switch (mi.getItemId())
    	{
    		case MENU1:
    			mi.setChecked(true);
    			txt.setBackgroundColor(Color.RED);
    			break;
    		case MENU2:
    			mi.setChecked(true);
    			txt.setBackgroundColor(Color.GREEN);
    			break;
    	}
    	return true;
    }
    
    < ------------使用XML资源文件定义菜单----------- >
    //当用户单击MENU键时触发该方法
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
    MenuInflater inflator = new MenuInflater(this);
    	// 状态R.menu.context对应的菜单,并添加到menu中
    	inflator.inflate(R.menu.my_menu, menu);
    	return super.onCreateOptionsMenu(menu);
    }
    menu/my_menu.xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    	<item android:title="@string/font_size"
    	      android:icon="@drawable/font">
    		<menu>
    			<!-- 定义一组单选菜单项 -->
    			<group android:checkableBehavior="single">
    				<!-- 定义多个菜单项 -->
    				<item
    					android:id="@+id/font_10"
    					android:title="@string/font_10"/>
    				<item
    					android:id="@+id/font_12"
    					android:title="@string/font_12"/>
    			</group>
    		</menu>
    	</item>
    	<!-- 定义一个普通菜单项 -->
    	<item android:id="@+id/plain_item"
    		android:title="@string/plain_item">
    	</item>
    	<item android:title="@string/font_color"
    		android:icon="@drawable/color">
    		<menu>
    			<!-- 定义一组允许复选的菜单项 -->
    			<group>
    				<!-- 定义3个菜单项 -->
    				<item
    					android:id="@+id/red_font"
    					android:title="@string/red_title"/>
    				<item
    					android:id="@+id/green_font"
    					android:title="@string/green_title"/>					
    			</group>
    		</menu>
    	</item>
    </menu>
    @Override
    // 选项菜单的菜单项被单击后的回调方法
    public boolean onOptionsItemSelected(MenuItem mi)
    {
    	if(mi.isCheckable())
    	{
    		mi.setChecked(true);  //②
    	}
    	// 判断单击的是哪个菜单项,并针对性的作出响应。
    	switch (mi.getItemId())
    	{
    		case R.id.font_10:
    			txt.setTextSize(10 * 2);
    			break;
    		......
    	}
    	return true;
    }
    
    // 为文本框注册上下文菜单
    registerForContextMenu(txt);
    // 创建上下文菜单时触发该方法
    @Override
    public void onCreateContextMenu(ContextMenu menu, View source,
    		ContextMenu.ContextMenuInfo menuInfo)
    {
    	MenuInflater inflator = new MenuInflater(this);
    	// 状态R.menu.context对应的菜单,并添加到menu中
    	inflator.inflate(R.menu.context, menu);
    	menu.setHeaderIcon(R.drawable.tools);
    	menu.setHeaderTitle("请选择背景色");
    }
    menu/context.xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    	<!-- 定义一组单选菜单项目 -->
    	<group android:checkableBehavior="single">
    		<!-- 定义2个菜单项 -->
    		<item
    			android:id="@+id/red"
    			android:title="@string/red_title"
    			android:alphabeticShortcut="r"/>
    		<item
    			android:id="@+id/green"
    			android:title="@string/green_title"
    			android:alphabeticShortcut="g"/>					
    	</group>
    </menu>
    // 上下文菜单中菜单项被单击时触发该方法。
    @Override
    public boolean onContextItemSelected(MenuItem mi)
    {
    	mi.setChecked(true);  //①
    	switch (mi.getItemId())
    	{
    		case R.id.red:
    			mi.setChecked(true);
    			txt.setBackgroundColor(Color.RED);
    			break;
    		......
    	}
    	return true;
    }
    
    
    < ------------使用PopupMenu创建弹出式菜单----------- >
    // 创建PopupMenu对象
    PopupMenu popup = = new PopupMenu(this, button);
    // 将R.menu.popup_menu菜单资源加载到popup菜单中
    getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
    // 为popup菜单的菜单项单击事件绑定事件监听器
    popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener()
    {
    	@Override
    	public boolean onMenuItemClick(MenuItem item)
    	{
    		switch (item.getItemId())
    		{
    			case R.id.exit:
    				// 隐藏该对话框
    				popup.dismiss();
    				break;
    			default:
    				// 使用Toast显示用户点击的菜单项
    				Toast.makeText(PopupMenuTest.this,"您单击了【" + item.getTitle() + "】菜单项", Toast.LENGTH_SHORT).show();
    		}
    		return true;
    	}
    });
    popup.show();
    menu/popup_menu.xml
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    	<item
    		android:id="@+id/search"
    		android:icon="@android:drawable/ic_menu_search"
    		android:title="查找" />
    	<item
    		android:id="@+id/add"
    		android:icon="@android:drawable/ic_menu_add"
    		android:title="添加" />
    	<item
    		android:id="@+id/edit"
    		android:icon="@android:drawable/ic_menu_edit"
    		android:title="编辑">
    		<menu>
    			<item
    				android:id="@+id/copy"
    				android:title="复制" />
    			<item
    				android:id="@+id/cut"
    				android:title="剪切" />			
    			<item
    				android:id="@+id/paste"
    				android:title="粘贴" />			
    		</menu>
    	</item>
    	<item
    		android:id="@+id/exit"
    		android:title="隐藏菜单" />
    </menu>
    
    
    五、活动条ActionBar(安卓 3.0)
    活动条ActionBar位于传统标题栏的位置,也就是显示的屏幕的顶部。ActionBar可显示应用的图标和Activity标题,还可以显示活动项(Action Item).
    活动条ActionBar提供了如下功能:
    1.显示选项菜单的菜单项(将菜单项显示成Action Item)
    2.使用程序图标作为返回Home主屏或向上的导航操作
    3.提供交互式View作为Action View
    4.提供基于Tab的导航方式,可以切换多个Fragment
    5.提供基于下拉的导航
    
    android:theme="@android:style/Theme.Holo.NoActionBar" //关闭ActionBar
    < --- 启动ActionBar --- >
    // 获取该Activity的ActionBar,
    // 只有当应用主题没有关闭ActionBar时,该代码才能返回ActionBar
    ActionBar actionBar = getActionBar();
    // 显示ActionBar
    actionBar.show();
    // 隐藏ActionBar
    actionBar.hide();
    
    < ------使用ActionBar显示选项菜单------ >
    手机如果没有Menu键,可以将选项菜单显示成ActionItem
    项目中推荐使用XML来定义菜单
    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    	<item 
    	    android:title="@string/font_size"
    	    android:showAsAction="always|withText"
    /***  android:showAsAction这个属性可接受的值有:
    1、always:这个值会使菜单项一直显示在Action Bar上。
    2、ifRoom:如果有足够的空间,这个值会使菜单项显示在Action Bar上。
    3、never:这个值使菜单项永远都不出现在Action Bar上。
    4、withText:这个值使菜单项和它的图标,菜单文本一起显示。
    5.collapseActionView:折叠成普通菜单项
    ***/
    		android:icon="@drawable/font">
    		<menu>
    			<!-- 定义一组单选菜单项 -->
    			<group android:checkableBehavior="single">
    				<!-- 定义多个菜单项 -->
    				<item
    					android:id="@+id/font_10"
    					android:title="@string/font_10"/>
    				<item
    					android:id="@+id/font_12"
    					android:title="@string/font_12"/>		
    			</group>
    		</menu>
    	</item>
    </menu>
    
    ActionBar actionBar = getActionBar();
    // 设置是否显示应用程序图标
    actionBar.setDisplayShowHomeEnabled(true);
    // 将应用程序图标设置为可点击的按钮
    actionBar.setHomeButtonEnabled(true);
    // 将应用程序图标设置为可点击的按钮,并在图标上添加向左箭头
    actionBar.setDisplayHomeAsUpEnabled(true);
    
    android.R.id.home:点击应用图标时响应
    
    < ------添加Action View -------- >
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
    	android:id="@+id/search"
    	android:title="@string/menu_settings"
    	android:orderInCategory="100"
    	android:showAsAction="always"
    	android:actionViewClass="android.widget.SearchView"/> //添加搜索框
    <item
    	android:id="@+id/progress"
    	android:title="@string/menu_settings"
    	android:orderInCategory="100"
    	android:showAsAction="always"
    	android:actionLayout="@layout/clock"/> //添加模拟时钟(自定义View)
    </menu>
    
    clock.xml:
    <AnalogClock
        xmlns:android="http://schemas.android.com/apk/res/android"
    	android:layout_width="wrap_content"
    	android:layout_height="wrap_content"
    />
    
    < ---------使用ActionBar实现Tab导航---------- >
    public class ActionBar_TabNav extends Activity implementsActionBar.TabListener
    {
    	private static final String SELECTED_ITEM = "selected_item";
    	@Override
    	public void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		final ActionBar actionBar = getActionBar();
    		// 设置ActionBar的导航方式:Tab导航
    		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    		// 依次添加3个Tab页,并为3个Tab标签添加事件监听器
    		actionBar.addTab(actionBar.newTab().setText("第一页")
    			.setTabListener(this));
    		actionBar.addTab(actionBar.newTab().setText("第二页")
    			.setTabListener(this));
    		actionBar.addTab(actionBar.newTab().setText("第三页")
    			.setTabListener(this));
    	}
    	@Override
    	public void onRestoreInstanceState(Bundle savedInstanceState)
    	{
    		if (savedInstanceState.containsKey(SELECTED_ITEM))
    		{
    			// 选中前面保存的索引对应的Fragment页
    			getActionBar().setSelectedNavigationItem(
    				savedInstanceState.getInt(SELECTED_ITEM));
    		}
    	}
    	@Override
    	public void onSaveInstanceState(Bundle outState)
    	{
    		// 将当前选中的Fragment页的索引保存到Bundle中
    		outState.putInt(SELECTED_ITEM, 
    			getActionBar().getSelectedNavigationIndex());
    	}
    	@Override
    	public void onTabUnselected(ActionBar.Tab tab,
    		FragmentTransaction fragmentTransaction)
    	{
    	}
    	// 当指定Tab被选中时激发该方法
    	@Override
    	public void onTabSelected(ActionBar.Tab tab,
    			FragmentTransaction fragmentTransaction)
    	{
    		// 创建一个新的Fragment对象
    		Fragment fragment = new DummyFragment();
    		// 创建一个Bundle对象,用于向Fragment传入参数
    		Bundle args = new Bundle();
    		args.putInt(DummyFragment.ARG_SECTION_NUMBER,
    				tab.getPosition() + 1);
    		// 向fragment传入参数
    		fragment.setArguments(args);
    		// 获取FragmentTransaction对象
    		FragmentTransaction ft = getFragmentManager().beginTransaction();
    		// 使用fragment代替该Activity中的container组件
    		ft.replace(R.id.container, fragment);
    		// 提交事务
    		ft.commit();
    	}
    	@Override
    	public void onTabReselected(ActionBar.Tab tab,
    			FragmentTransaction fragmentTransaction)
    	{
    	}
    }
    
    public class DummyFragment extends Fragment
    {
    	public static final String ARG_SECTION_NUMBER = "section_number";
    	// 该方法的返回值就是该Fragment显示的View组件
    	@Override
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    			Bundle savedInstanceState)
    	{
    		TextView textView = new TextView(getActivity());
    		textView.setGravity(Gravity.CENTER_HORIZONTAL);
    		// 获取创建该Fragment时传入的参数Bundle
    		Bundle args = getArguments();
    		// 设置TextView显示的文本
    		textView.setText(args.getInt(ARG_SECTION_NUMBER) + "");
    		textView.setTextSize(30);
    		// 返回该TextView
    		return textView;
    	}
    }
    
    < ---------使用ActionBar实现TabSwipe导航---------- >
    public class ActionBar_TabSwipeNav extends FragmentActivity
    	implements ActionBar.TabListener
    {
    	ViewPager viewPager;
    	ActionBar actionBar;
    	@Override
    	public void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		// 获取ActionBar对象
    		actionBar = getActionBar();
    		// 获取ViewPager
    		viewPager = (ViewPager) findViewById(R.id.pager);
    		// 创建一个FragmentPagerAdapter对象,该对象负责为ViewPager提供多个Fragment
    		FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(
    				getSupportFragmentManager())
    		{
    			// 获取第position位置的Fragment
    			@Override
    			public Fragment getItem(int position)
    			{
    				Fragment fragment = new DummyFragment();
    				Bundle args = new Bundle();
    				args.putInt(DummyFragment.ARG_SECTION_NUMBER, position + 1);
    				fragment.setArguments(args);
    				return fragment;
    			}
    			// 该方法的返回值i表明该Adapter总共包括多少个Fragment
    			@Override
    			public int getCount()
    			{
    				return 3;
    			}
    			// 该方法的返回值决定每个Fragment的标题
    			@Override
    			public CharSequence getPageTitle(int position)
    			{
    				switch (position)
    				{
    					case 0:
    						return "第一页";
    					case 1:
    						return "第二页";
    					case 2:
    						return "第三页";
    				}
    				return null;
    			}
    		};
    		// 设置ActionBar使用Tab导航方式
    		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    		// 遍历pagerAdapter对象所包含的全部Fragment。
    		// 每个Fragment对应创建一个Tab标签
    		for (int i = 0; i < pagerAdapter.getCount(); i++)
    		{
    			actionBar.addTab(actionBar.newTab()
    				.setText(pagerAdapter.getPageTitle(i))
    				.setTabListener(this));
    		}
    		// 为ViewPager组件设置FragmentPagerAdapter
    		viewPager.setAdapter(pagerAdapter);  //①
    		// 为ViewPager组件绑定事件监听器
    		viewPager.setOnPageChangeListener(
    			new ViewPager.SimpleOnPageChangeListener()
    			{
    				// 当ViewPager显示的Fragment发生改变时激发该方法
    				@Override
    				public void onPageSelected(int position)
    				{
    					actionBar.setSelectedNavigationItem(position);
    				}
    			});
    	}
    	@Override
    	public void onTabUnselected(ActionBar.Tab tab,
    			FragmentTransaction fragmentTransaction)
    	{
    	}
    	// 当指定Tab被选中时激发该方法
    	@Override
    	public void onTabSelected(ActionBar.Tab tab,
    			FragmentTransaction fragmentTransaction)
    	{
    		viewPager.setCurrentItem(tab.getPosition());  //②
    	}
    	@Override
    	public void onTabReselected(ActionBar.Tab tab,
    			FragmentTransaction fragmentTransaction)
    	{
    	}
    }
    main.xml:
    <android.support.v4.view.ViewPager
    	xmlns:android="http://schemas.android.com/apk/res/android"
    	android:id="@+id/pager"
    	android:layout_width="match_parent"
    	android:layout_height="match_parent">
    	<!-- 定义导航状态条组件 -->
    	<android.support.v4.view.PagerTitleStrip 
    		android:layout_width="match_parent"
    		android:layout_height="wrap_content"
    		android:layout_gravity="top"
    		android:background="#33b5e5"
    		android:textColor="#fff"
    		android:paddingTop="4dp"
    		android:paddingBottom="4dp" />	
    </android.support.v4.view.ViewPager>
    
    < ---------使用ActionBar实现下拉式导航---------- >
    public class ActionBar_DropDownNav extends Activity implements
    		ActionBar.OnNavigationListener
    {
    	private static final String SELECTED_ITEM = "selected_item";
    	@Override
    	public void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		final ActionBar actionBar = getActionBar();
    		// 设置ActionBar是否显示标题
    		actionBar.setDisplayShowTitleEnabled(true);
    		// 设置导航模式,使用List导航
    		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    		// 为actionBar安装ArrayAdapter
    		actionBar.setListNavigationCallbacks(
    			new ArrayAdapter<String>(ActionBar_DropDownNav.this,
    				android.R.layout.simple_list_item_1,
    				android.R.id.text1, new String[]
    				{"第一页","第二页","第三页" }), this);
    	}
    	@Override
    	public void onRestoreInstanceState(Bundle savedInstanceState)
    	{
    		if (savedInstanceState.containsKey(SELECTED_ITEM))
    		{
    			// 选中前面保存的索引对应的Fragment页
    			getActionBar().setSelectedNavigationItem(
    				savedInstanceState.getInt(SELECTED_ITEM));
    		}
    	}
    	@Override
    	public void onSaveInstanceState(Bundle outState)
    	{
    		// 将当前选中的Fragment页的索引保存到Bundle中
    		outState.putInt(SELECTED_ITEM, 
    			getActionBar().getSelectedNavigationIndex());
    	}
    	// 当导航项被选中时激发该方法
    	@Override
    	public boolean onNavigationItemSelected(int position, long id)
    	{
    		// 创建一个新的Fragment对象
    		Fragment fragment = new DummyFragment();
    		// 创建一个Bundle对象,用于向Fragment传入参数
    		Bundle args = new Bundle();
    		args.putInt(DummyFragment.ARG_SECTION_NUMBER, position + 1);
    		// 向fragment传入参数
    		fragment.setArguments(args);
    		// 获取FragmentTransaction对象
    		FragmentTransaction ft = getFragmentManager().beginTransaction();
    		// 使用fragment代替该Activity中的container组件
    		ft.replace(R.id.container, fragment);
    		// 提交事务
    		ft.commit();
    		return true;
    	}
    }
    
    展开全文
  • 第一篇文章:写博客都是为了记录一些安卓开发过程中遇到的常见问题解决和功能实现。 废话不多说切入正题。我们都知道谷歌官方没有提供给我们加载更多的功能框架,recycleview在开发过程中应用频繁。它可以实现各种...
  • 2020年安卓学习笔记目录

    千次阅读 2020-10-24 08:54:41
    一、讲课笔记 安卓学习笔记01:安装集成开发环境Android Studio 安卓学习笔记02:测试安卓开发环境 ...安卓学习笔记11:网格布局 安卓学习笔记12:安卓按键事件 安卓学习笔记13:安卓触摸事件 安卓学习笔
  • 01安卓学习半期总结

    2020-11-13 11:50:59
    01安卓安卓学习半期总结一.知识点回顾二.反思优缺点三.学习方法四....网格布局 12.安卓按钮事件 13.安卓触摸事件 安卓案例:利用帧动画动态显示时间 安卓案例:利用帧动画实现游戏特效 14.安卓手势操作编
  • 这学期我们学习了安卓的下载,Activity相关知识,事件处理、窗口跳转和传递数据,常用布局(线性布局、帧式布局、相对布局、网格布局),安卓的按键、触摸事件,手势操作编程,应用程序资源,常用控件(标签、编辑框...
  • 文章目录Android布局管理器线性布局管理器(LinearLayout)常用操作表格布局(TableLayout)帧布局(FrameLayout)帧布局示例程序1帧布局示例程序2MianActivity.javacolors.xml相对布局(RelativeLayout)示例程序网格布局...
  • 5、 网格布局——完成计算机与图片表 (完成) 6、使用安卓资源—— 制作个人相册 (未完成) 7、 标签控件 ——优化水果选项框(未完成) 8、编辑框 ——设计一个乘法计算表完成基本计算功能 (完成) 9、按钮控件 ...
  • 安卓GridView使用实例

    2020-07-30 15:44:19
    安卓GridView使用实例 本文摘自:https://whatsblog.icu/index.php/Android/6.html . GridView与ListView的用法基本一致,不同的只是布局。当我们打开手机,应用会以宫格显示,那就是GridView。 以代码形式展示,...
  • 尽管Sketch提供了一些方法,通过使用Symbols将一些样式应用到元素中,但如果你想让布局更有适应性或者动态变化,它恐怕就很难完成了。 在过去的几次重布局项目当中,当我需要快速迭代时(例如重新设计Facebook“关于...
  • 前言安卓应用的用户界面是构建在View 和ViewGroup 这两个物件的层级之上的。 View 就是一般的UI组件,像按钮,输入框等。 viewGroup 是一些不可见的view的容器,用来定义子View 如何布局, 类似在一个网格或是一个...
  • Android应用开发揭秘--详细书签版

    热门讨论 2012-12-12 13:27:46
    4.2.17 网格视图(GridView) 86 4.2.18 卷轴视图(ScrollView) 87 4.2.19 进度条(ProgressBar ) 90 4.2.20 拖动条(SeekBar) 93 4.2.21 状态栏提示(Notification、NotificationManager) 95 4.2.22 ...
  • 文章目录零、学习目标一、网格视图(一)概述(二)继承关系图(三)常用属性二、图像切换器(一)概述(二)继承关系图三、案例演示 - 选择水果(一)运行效果(二)涉及知识点(三)实现步骤1、创建安卓应用...
  • Android View And Activity

    2021-01-02 15:56:57
    线性布局相对布局布局嵌套常用控件TextView 文本显示控件Button 按钮 和 ImageButtonImageView 图片显示控件GridView 网格视图监听器 Listener输出Log日志Toast 基本使用Intent 基本使用Activity生命周期Activity的...
  • 安卓 的iOS Tangram是用于动态构建本机页面的模块化UI解决方案,包括Android的Tangram,iOS的Tangram甚至后端CMS。 该项目在基于和Android上提供sdk。 产品特点 警告请不要使用tangram3包下的类! 七巧板3.0正在...
  • 可设置标题+目标分辨率+布局方案,启动立即应用。 可设置主背景颜色+面板颜色+十字线游标颜色。 可设置多条曲线颜色,没有设置颜色的情况下内置15套精美颜色随机应用。 可设置标题栏背景颜色+文字颜色。 可设置曲线...

空空如也

空空如也

1 2
收藏数 21
精华内容 8
关键字:

安卓网格布局应用