二、Android应用的界面编程(一)界面编程与视图(View)组件

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>
 1 public class MixView extends Activity {
 2     // 定义一个访问图片的数组
 3     int[] images = new int[] { R.drawable.java, R.drawable.ee,
 4             R.drawable.classic, R.drawable.ajax, R.drawable.xml, };
 5     int currentImg = 0;
 6
 7     @Override
 8     public void onCreate(Bundle savedInstanceState) {
 9         super.onCreate(savedInstanceState);
10         setContentView(R.layout.main);
11         // 获取LinearLayout布局容器
12         LinearLayout main = (LinearLayout) findViewById(R.id.root);
13         // 程序创建ImageView组件
14         final ImageView image = new ImageView(this);
15         // 将ImageView组件添加到LinearLayout布局容器中
16         main.addView(image);
17         // 初始化时显示第一张图片
18         image.setImageResource(images[0]);
19         image.setOnClickListener(new OnClickListener() {
20             @Override
21             public void onClick(View v) {
22                 // 改变ImageView里显示的图片
23                 image.setImageResource(images[++currentImg % images.length]);
24             }
25         });
26     }
27 }

【开发自定义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);
    }
}
时间: 2024-08-08 13:44:11

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

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

UI组件--------------->android.widget.* View组件------------->android.view.* 视图(View)组件 所有UI组件都是建立在视图(View)组件.容器(ViewGroup)组件基础之上的. UI组件继承之View组件 ViewGroup----------->作为其他组件的容器使用. ViewGroup包含View组件即 (UI组件---->继承自View组件. ViewGroup组件---->继承自View组件

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

1.视图组件与容器组件 Android应用绝大部分UI组件都放在Android.widget包及其子包.android.view包及其子包中,其所有UI组件都继承了view类,view组件代表一个空白的矩形区域. View类还有一个重要的子类:ViewGroup,它通常作为其他组件的容器使用.ViewGroup除了包含普通view组件外,还可包含ViewGroup组件. 所有组件都提供了两种方式来控制组件的行为: a.在XML布局文件中通过XML属性进行控制. b.在JAVA程序代码中通过调用方

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

在Android开 发中,在Activity中关联视图View是一般使用setContentView方法,该方法一种参数是使用XML资源直接创 建:setContentView (int layoutResID),指定layout中的一个XML的ID即可,这种方法简单.另一个方法是 setContentView(android.view.View),参数是指定一个视图View对象,这种方法可以使用自定义的视图类. 在一些场合中,需要对View进行一些定制处理,比如获取到Canvas进行图像绘制,

Android异步处理二:使用AsyncTask异步更新UI界面

Android异步处理二:使用AsyncTask异步更新UI界面 - lzc的专栏 - 博客频道 - CSDN.NET 在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简洁的实现方式:使用AsyncTask异步更新UI界面. 概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的

Android研究之动态创建UI界面详解

 Android的基本UI界面一般都是在xml文件中定义好,然后通过activity的setContentView来显示在界面上,这是Android UI的最简单的构建方式.其实,为了实现更加复杂和更加灵活的UI界面,往往需要动态生成UI界面,甚至根据用户的点击或者配置,动态地改变UI,本文即介绍该技巧.对事件和进程的可能安卓设备实现触摸事件的监听,跨进程 假设Android工程的一个xml文件名为activity_main.xml,定义如下: 1 2 3 4 5 6 7 8 9 10 11

玩转Android Camera开发(四):预览界面四周暗中间亮,只拍摄矩形区域图片(附完整源码)

杂家前文曾写过一篇关于只拍摄特定区域图片的demo,只是比较简陋,在坐标的换算上不是很严谨,而且没有完成预览界面四周暗中间亮的效果,深以为憾,今天把这个补齐了. 在上代码之前首先交代下,这里面存在着换算的两种模式.第一种,是以屏幕上的矩形区域为基准进行换算.举个例子,屏幕中间一个 矩形框为100dip*100dip.这里一定要使用dip为单位,否则在不同的手机上屏幕呈现的矩形框大小不一样.先将这个dip换算成px,然后根据屏幕的宽和高的像素计算出矩形区域,传给Surfaceview上铺的一层Vi

《Android深入透析》之界面

前言: Android应用的UI是由层级的视图对象组成的.视图层次起始于一个布局容器.每个视图代表着屏幕上的一块组成.每个视图通过属性来设定自身在屏幕上显现的形态.可以说Android的视图就是由布局容器.容器中的子视图.视图的各种属性串联而成.今天在B哥的指导下 我们对组成视图的各个因素一 一加以探究. 1.Android中视图的表现形式:        Android使用XML布局与Java代码共同定义视图(用户界面).你可以使用Java代码来制定所有的视图布局.但在绝大多数情况下是使用XM

从零开始学android&lt;使用嵌套布局实现计算器界面.十七.&gt;

所谓的嵌套布局就是在一个文件中嵌套多个布局文件 <span style="font-size:18px;"> <LinearLayout android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical" > <FrameLayout android:layou

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

在android学习中,动作交互是软件中重要的一部分.当中的Scroller就是提供了拖动效果的类,在网上.比方说一些Launcher实现滑屏都能够通过这个类去实现.以下要说的就是上次Scroller类学习的后的实践了. 假设你还不了解Scroller类,那请先点击:Android 界面滑动实现---Scroller类 从源代码和开发文档中学习(让你的布局动起来) 了解之后再阅读下面内容.你会发现原来实现起来非常easy. 之前说到过.在广泛使用的側边滑动导航开源库 --SlidingLayer

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

现在开发中的功能需要直接跳转到拨号.联系人.短信界面等等,查找了很多资料,自己整理了一下.1.跳转到拨号界面,代码如下: 1)直接拨打 Intent intentPhone = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneNumber)); startActivity(intentPhone); 2)跳转到拨号界面 Intent intent = newIntent(Intent.ACTION_DIAL,Uri.pars