zoukankan      html  css  js  c++  java
  • 二、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);
        }
    }
  • 相关阅读:
    Ubuntu中的解压缩文件的方式 分类: Java 2014-07-20 22:33 1264人阅读 评论(0) 收藏
    Ubuntu下安装JDK图文解析 分类: Java 2014-07-20 21:28 4565人阅读 评论(3) 收藏
    数据结构和算法设计专题之---24点游戏(穷举法和递归法) 分类: Java 2014-07-18 21:26 789人阅读 评论(0) 收藏
    数据结构和算法设计专题之---单链表的逆序 分类: Java 2014-07-18 21:24 562人阅读 评论(1) 收藏
    Android中实现静态的默认安装和卸载应用 分类: Android 2014-07-02 22:43 5952人阅读 评论(19) 收藏
    Git的使用方法 分类: Java 2014-06-18 18:34 520人阅读 评论(0) 收藏
    J2EE学习篇之--JQuery技术详解 分类: JavaWeb 2014-06-18 11:35 1958人阅读 评论(1) 收藏
    MyEclipse6.0中使用aptana插件,添加jquery提示功能 分类: JavaWeb 2014-06-04 15:35 648人阅读 评论(0) 收藏
    Android中如何搭建一个WebServer 分类: Android 2014-06-01 14:44 8708人阅读 评论(3) 收藏
    J2EE学习篇之--Spring技术详解 分类: JavaWeb 2014-05-28 10:15 1109人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/androidsj/p/4597470.html
Copyright © 2011-2022 走看看