二、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程序代码中通过调用方法进行控制。

二、Android应用的界面编程(一)界面编程与视图(View)组件_第1张图片

 

二、Android应用的界面编程(一)界面编程与视图(View)组件_第2张图片

二、Android应用的界面编程(一)界面编程与视图(View)组件_第3张图片

二、Android应用的界面编程(一)界面编程与视图(View)组件_第4张图片

 

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); } }

 

你可能感兴趣的:(android)