以布局文件设置View类自定属性的问题

来源:互联网 发布:探索性软件测试 编辑:程序博客网 时间:2024/05/22 12:26

接近十点了,总结一下就回去。

我不承认这是技术文章,但谦虚地说还是有点技术,觉得应该总结一下,很多东西学了就忘记了,我也不知道这是什么原因,鲜花少说,闲话……

关于在XML文件中布局自己定义的wiew的问题。目标设计是现实两个时钟,一般的方案是让setContentView函数中接受ImageView类即可,但是这里我用了View类来实现(因为View类是ImageView的父类嘛,这里实现的所有的资源都从布局文件中加载,所以又与传统的加载方法有点不同)。

默认启动的Activity上面显示两个按钮,分别用于启动另外两个Activity,分别显示不同的画面。代码较简单就不赘述了,下面介绍显示的Activity(只列举一个Activity即可)。

布局文件:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical" android:layout_width="fill_parent"

    android:layout_height="fill_parent" android:background="#FFF"

    android:gravity="center">

    <net.blogjava.mobile.widget.HandClock

       android:layout_width="wrap_content"

       android:layout_height="wrap_content"

       clockImageSrc="@drawable/clock1"

       scale="0.75"

       handCenterWidthScale="0.477"

       handCenterHeightScale="0.512"

       minuteHandSize="54"

       hourHandSize="40"/>

</LinearLayout>

关键在于<net.blogjava.mobile.widget.HandClock的理解,其实这是一个View,等于TextView就是了,下面来实现这个View.主代码显示如下:

package net.blogjava.mobile.widget;

 

import …

public class HandClock extends View implements Runnable{

       private int clockImageResourceId;

       private Bitmap bitmap;

       private float scale;

       private float handCenterWidthScale;

       private float handCenterHeightScale;

       private int minuteHandSize;

       private int hourHandSize;

       private Handler handler = new Handler();

 

       @Override

       public void run(){

              // 重新绘制View

              invalidate();

              // 重新设置定时器,在60秒后调用run方法

              handler.postDelayed(this, 60 * 1000);

       }

       @Override

       protected void onDraw(Canvas canvas){

       ……

       }

 

       public HandClock(Context context, AttributeSet attrs){

              super(context, attrs);

              // 读取相应的属性值

              clockImageResourceId = attrs.getAttributeResourceValue(null,

                            "clockImageSrc", 0);

              if (clockImageResourceId > 0)

                     bitmap = BitmapFactory.decodeResource(getResources(),

                                   clockImageResourceId);

              scale = attrs.getAttributeFloatValue(null, "scale", 1);

              handCenterWidthScale = attrs.getAttributeFloatValue(null,

                            "handCenterWidthScale", bitmap.getWidth() / 2);

              handCenterHeightScale = attrs.getAttributeFloatValue(null,

                            "handCenterHeightScale", bitmap.getHeight() / 2);

              //  在读取分针和时针长度后,将其值按图像的缩放比例进行缩放

              minuteHandSize = (int) (attrs.getAttributeIntValue(null,

                            "minuteHandSize", 0) * scale);

              hourHandSize = (int) (attrs.getAttributeIntValue(null, "hourHandSize",

                            0) * scale);

              int currentSecond = Calendar.getInstance().get(Calendar.SECOND);

              //  将定时器设在0分时执行run方法

              handler.postDelayed(this, (60 - currentSecond) * 1000);

       }

}

关键是上面的构造函数HandClock,函数attrs是从该类得属性中得到值(通过getAttribute…Value方法得到),getAttribute…Value函数中的第二个参数指出了从哪一个属性中获得值,该属性以字符串的形式传入。这里指出什么属性,布局文件中就必须指明属性的值,否则就按默认参数传入。比如上面的"clockImageSrc"属性在布局文件中就必须指出。主类实现了runnable接口,并将其抛入Handler运行,闲话就不多说了,其它函数需要重载的重载,就更不多少了,展示一下成果:

主界面:


图片

 时钟1界面:


图片

  Over,效果还是可以哈,基本实现bitmap的显示了。