Android应用的绝大部分UI组件都放在android.widget包及其子包、android.view包及其子包中,
Android应用的所有UI组件都继承了View类。它代表一个空白的矩形区域。
View类还有一个重要的子类:ViewGroup,但ViewGroup通常作为其他组件的容器使用。
Android的所有UI都是建立在View、ViewGroup基础之上的,因此ViewGroup也可以被当成View使用。
ViewGroup里除了可以包含普通View组件之外,还可以再次包含ViewGroup组件。

Android定义用户界面:
1)在XML布局文件中通过XML属性进行控制。
2)在Java程序代码中通过调用方法进行控制。

Drawable是Android提供的一个抽象类,它代表了“可以被绘制出来的某种东西”,
Drawable包括了大量子类,比如:
BitmapDrawable代表位图Drawable;
ColorDrawable代表颜色Drawable;
ShapeDrawable代表几何形状Drawable;
各种Drawable可以用于定制UI组件的背景等外观。

ViewGroup继承了View类,也可以当成普通View来使用。但ViewGroup主要还是当成容器类使用。但由ViewGroup
是一个抽象类,因此实际使用中通常总是使用ViewGroup的子类来作为容器,例如各种布局管理器。
ViewGroup容器控制其子组件的分布依赖于ViewGroup.LayoutParams、ViewGroup.MarginLayoutParams两个内部类。
这两个内部类中都提供了一些XML属性,ViewGroup容器中的子组件可以指定这些XML属性。

ViewGroup.LayoutParams所支持的两个XML属性。
android:layout_width 指定该子组件的布局高度。
android:layout_height 指定该子组件的布局宽度。
属性值:
fill_parent:指定子组件的高度、宽度与父容器组件的高度、宽度相同(实际上还要减去填充的空白距离)。
match_parent:与fill_parent相同,从Android2.2开始推荐使用这个属性来代替fill_parent。
wrap_content:指定子组件的大小恰好能包裹它的内容即可。

【ViewGroup.MarginLayoutParams支持的属性】
android:layout_marginBottom 指定该子组件下边的页边距。
android:layout_marginLeft 指定该子组件左边的页边距。
android:layout_marginRight 指定该子组件右边的页边距。
android:layout_marginTop 指定该子组件上边的页边距。
相关方法:setMargins(int,int,int,int)

实例:在代码中控制UI界面

public class CodeView extends Activity {
// 当第一次创建该Activity时回调该方法
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 创建一个线性布局管理器
LinearLayout layout = new LinearLayout(this);
// 设置该Activity显示layout
super.setContentView(layout);
layout.setOrientation(LinearLayout.VERTICAL);
// 创建一个TextView
final TextView show = new TextView(this);
// 创建一个按钮
Button bn = new Button(this);
bn.setText("单击我");
bn.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
// 向Layout容器中添加TextView
layout.addView(show);
// 向Layout容器中添加按钮
layout.addView(bn);
// 为按钮绑定一个事件监听器
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
show.setText("Hello , Android , " + new
java.util.Date());
}
});
}

}

从上面的代码看出,该程序中所用到的UI组件都是通过new关键字创建出来的。然后程序使用LinearLayout容器来“盛装”这些UI组件,这样就组成了图形用户界面。

从上面的程序代码中可以看出,无论创建哪种UI组件,都需要传入一个this参数,这是由于创建UI组件时传入一个
Context代表访问Android应用环境的全局信息的API。让UI组件持有一个Context参数,可让这些UI组件通过该Context
参数来获取Android应用环境的全局信息。
Context本身是一个抽象类,Android应用的Activity、Service都继承了Context,因此Activity、Service都可以直
接作为Context使用。

实例:使用XML布局文件和Java代码混合控制UI界面(简单图片浏览器)。
<?xml version="1.0" encoding="utf-8"?>
<!-- 定义一个线性布局容器 -->

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
</LinearLayout>
 public class MixView extends Activity {
// 定义一个访问图片的数组
int[] images = new int[] { R.drawable.java, R.drawable.ee,
R.drawable.classic, R.drawable.ajax, R.drawable.xml, };
int currentImg = 0; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取LinearLayout布局容器
LinearLayout main = (LinearLayout) findViewById(R.id.root);
// 程序创建ImageView组件
final ImageView image = new ImageView(this);
// 将ImageView组件添加到LinearLayout布局容器中
main.addView(image);
// 初始化时显示第一张图片
image.setImageResource(images[0]);
image.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 改变ImageView里显示的图片
image.setImageResource(images[++currentImg % images.length]);
}
});
}
}

【开发自定义View】
首先定义一个继承View基类的子类,然后重写View类的一个或多个方法,通常可以被用户重写的方法如下:
构造器:重写构造器是定制View的最基本方式,当Java代码创建一个View实例,或根据XML布局文件加载并构建界面
时将需要调用该构造器。
# onFinishInflate():这是一个回调方法,当应用从XML布局文件加载该组件并利用它来构建界面之后,该方法将会被回调。
# onMeasure(int,int):调用该方法来检测View组件及它所包含的所有子组件的大小。

# onLayout(boolean,int,int,int,int):当该组件需要分配其子组件的位置、大小时,该方法就会被回调。

# onSizeChanged(int,int,int,int):当该组件的大小被改变时回调该方法。

# onDraw(Canvas):当该组件将要绘制它的内容时回调该方法进行绘制。

# onKeyDown(int,KeyEvent):当某个键被按下时触发该方法。

# onKeyUp(int,KeyEvent):当松开某个键时触发该方法。

# onTrackballEvent(MotionEvent):当发生轨迹球事件时触发该方法。

# onTouchEvent(MotionEvent):当发生触摸屏幕事件时触发该方法。

# onWindowFocusChanged(boolean):当该组件得到、失去焦点时触发该方法。

# onAttachedToWindow():当把该组件放入某个窗口时触发该方法。

# onDetachedFromWindow():当把该组件从某个窗口上分离时触发该方法。

# onWindowVisibilltyChanged(int):当包含该组件的窗口的可见性发生改变时触发该方法。

当需要开发自定义View时,开发者并不需要重写上面列出的所有方法,而是可以根据业务需要重写上面的部分方法,
例如下面的示例程序就只重写onDraw(Canvas)方法。

实例:跟随手指的小球(可任意拖动)
这个UI组件将会在指定位置绘制一个小球,这个位置可以动态改变。当用户通过手指在屏幕上拖动时,程序监听
到这个手势动作,并把手指动作的位置传入自定义UI组件,并通知该组件绘制即可。

public class DrawView extends View {
public float currentX = 40;
public float currentY = 50;
// 定义、并创建画笔
Paint p = new Paint(); public DrawView(Context context) {
super(context);
}
public DrawView(Context context, AttributeSet set) {
super(context, set);
} @Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 设置画笔的颜色
p.setColor(Color.RED);
// 绘制一个小圆(作为小球)
canvas.drawCircle(currentX, currentY, 15, p);
} // 为该组件的触碰事件重写事件处理方法
@Override
public boolean onTouchEvent(MotionEvent event) {
// 修改currentX、currentY两个属性
currentX = event.getX();
currentY = event.getY();
// 通知当前组件重绘自己
invalidate();
// 返回true表明该处理方法已经处理该事件
return true;
}
}

上面的DrawView组件继承了View基类,并重写了onDraw方法---该方法负责在该组件的指定位置绘制一个小球,除此

之外,该组件还重写了onTouchEvent(MotionEvent),该方法用于处理该组件的触碰事件,当用户手指触碰该组件时
将会激发该方法。当手指在触摸屏上移动时,将会不断地触发触摸屏事件,事件监听器中负责触发事件的坐标将被
传入DrawView组件,并通过该组件重绘---这样就可保证DrawView上小球跟随手指移动而移动。

接下来可以通过Java代码把该组件添加到指定的容器中,这样就可以看到该组件的运行结果了。

public class CustomView extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取布局文件中的LinearLayout容器
LinearLayout root = (LinearLayout) findViewById(R.id.root);
// 创建DrawView组件
final DrawView draw = new DrawView(this);
// 设置自定义组件的最大宽度、高度
draw.setMinimumWidth(300);
draw.setMinimumHeight(500
);
root.addView(draw);

}
}

二、Android应用的界面编程(一)界面编程与视图(View)组件的更多相关文章

  1. 关于Android界面编程与视图(View)组件

    UI组件--------------->android.widget.* View组件------------->android.view.* 视图(View)组件 所有UI组件都是建立在 ...

  2. 界面编程与视图(View)组件

    1.视图组件与容器组件 Android应用绝大部分UI组件都放在Android.widget包及其子包.android.view包及其子包中,其所有UI组件都继承了view类,view组件代表一个空白 ...

  3. Android编程动态创建视图View的方法

    在Android开 发中,在Activity中关联视图View是一般使用setContentView方法,该方法一种参数是使用XML资源直接创 建:setContentView (int layout ...

  4. Android VLC播放器二次开发2——CPU类型检查+界面初始化

    上一篇讲了VLC整个程序的模块划分和界面主要使用的技术,今天分析一下VLC程序初始化过程,主要是初始化界面.加载解码库的操作.今天主要分析一下org.videolan.vlc.gui.MainActi ...

  5. [Android] Android 手机下 仿 微信 客户端 界面 -- 微聊

    Android 手机下 仿 微信 客户端 界面 -- 微聊 (包括聊天列表 + 聊天对话页 + 朋友圈列表页 + 我的/发现 列表页) 项目演示: 功能说明: 1)底部标签切换 (TabHost + ...

  6. Android 手机卫士--设置界面&功能列表界面跳转逻辑处理

    在<Android 手机卫士--md5加密过程>中已经实现了加密类,这里接着实现手机防盗功能 本文地址:http://www.cnblogs.com/wuyudong/p/5941959. ...

  7. Android学习系列(23)--App主界面实现

    在上篇文章<Android学习系列(22)--App主界面比较>中我们浅略的分析了几个主界面布局,选了一个最大众化的经典布局.今天我们就这个经典布局,用代码具体的实现它. 1.预览图先看下 ...

  8. Android开发之Intent跳转到系统应用中的拨号界面、联系人界面、短信界面

    现在开发中的功能需要直接跳转到拨号.联系人.短信界面等等,查找了很多资料,自己整理了一下. 1.跳转到拨号界面,代码如下: 1)直接拨打 Intent intentPhone = new Intent ...

  9. Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源码

    在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现.下面要说的就是上次Scroller ...

  10. Android开发(25)--framebyframe帧动画并实现启动界面到主界面的跳转

    Drawable animation可以加载Drawable资源实现帧动画.AnimationDrawable是实现Drawable animations的基本类.推荐用XML文件的方法实现Drawa ...

随机推荐

  1. JAVA常见算法题(二)

    package com.xiaowu.demo; /** * 判断101-2000之间有多少个素数,并输出所有素数. * 质数(prime number)又称素数,有无限个.质数定义为在大于1的自然数 ...

  2. Python命令行参数学习

    man python 查看python的帮助文件 命令行参数:       -B     Don't write .py[co] files on import.              See a ...

  3. MySQL不能启动 Can't start server : Bind on unix socket: Permission denied

    转载博客地址:http://www.linuxidc.com/Linux/2010-04/25709.htm MySQL服务器突然不能启动,查看最后的启动日志如下: 080825 09:38:04 m ...

  4. ES6方面重点摘要

    1.变量声明(1)内层变量覆盖外层变量(即后面的覆盖前面的)(2)循环变量的声明,i值在全局范围内有效,所以最后输出的都是最后一轮i的值(3)let.const的引入,为JS增加了块级作用域的概念(c ...

  5. Android之TextView的Span样式源代码剖析

    Android中的TextView是个显示文字的的UI类.在现实中的需求中,文字有各式各样的样式,TextView本身没有属性去设置实现.我们能够通过Android提供的 SpannableStrin ...

  6. [React] Use react-rewards to add microinteractions to React app to reward users for some actions

    It's important that our users enjoy using our application or website. One way we can make it happen ...

  7. perl学习笔记——输入与输出

    读取标准输入 用<STDIN>进行标准输入:chomp($line=<STDIN>); 如果读到文件尾,行输入操作符就会返回undef.便可利用这一性质跳出循环. while( ...

  8. 内核中bitmap的使用

    在编写应用层代码中使用位图,发现内核中已经有现成的实现便使用之.对位图的使用主要是几个 关键API. 第一:bitmap_zero函数用于初始化位图 源码如下: /* *@dst: 位图的起始地址 * ...

  9. RabbitMQ二----' helllo world '

    RabbitMQ实现了AMQP定义的消息队列.它实现的功能”非常简单“:从Producer接收数据然后传递到Consumer.它能保证多并发,数据安全传递,可扩展. 我们将会设计两个程序,一个发送He ...

  10. POJ 3687:Labeling Balls(优先队列+拓扑排序)

    id=3687">Labeling Balls Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10178 Acc ...