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

转载地址:http://blog.csdn.net/dingyong12345/article/details/6444083;

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

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

关于在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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical" >

    <com.icer.snow.view.ClockView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        clockImageSrc="@drawable/clock"
        handCenterHeightScale="0.512"
        handCenterWidthScale="0.477"
        hourHandSize="40"
        minuteHandSize="54"
        scale="0.75" />

</LinearLayout>
关键在于 < com.icer.snow.view.ClockView的理解,其实这是一个 View ,等于 TextView 就是了,下面来实现这个 View. 主代码显示如下:

<span style="font-size:18px;">public class ClockView extends View implements Runnable {

	private int clockImageResouceId;
	private Bitmap bitmap;
	private float scale;

	private float handCenterWidthScale;
	private float handCenterHeightScale;
	private float minuteHandSize;
	private float hourHandSize;
	private Handler handler = new Handler();

	public ClockView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}

	public ClockView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		clockImageResouceId = attrs.getAttributeResourceValue(null,
				"clockImageSrc", 0);
		if (clockImageResouceId > 0) {
			bitmap = BitmapFactory.decodeResource(getResources(),
					clockImageResouceId);
			scale = attrs.getAttributeFloatValue(null, "scale", 1);
			handCenterWidthScale = attrs.getAttributeFloatValue(null,
					"handCenterWidthScale", bitmap.getWidth() / 2);
			handCenterHeightScale = attrs.getAttributeFloatValue(null,
					"handCenterHeightScale", bitmap.getHeight());

			// 读取分针和时针长度,将图像缩放比例进行缩放
			minuteHandSize = (int) (attrs.getAttributeIntValue(null,
					"minuteHandSize", 0) * scale);
			hourHandSize = (int) (attrs.getAttributeIntValue(null,
					"hourHandSize", 0) * scale);
			int currentSecound = Calendar.getInstance().get(Calendar.SECOND);
			// 当秒针12点方向时候执行run
			handler.postDelayed(this, (60 - currentSecound) * 1000);

		}
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		// 重绘
		invalidate();
		// 设置定时器,在60秒后调用run方法
		handler.postDelayed(this, 60 * 1000);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		Paint paint = new Paint();
		Rect target = new Rect();
		Rect src = new Rect();
		src.left = 0;
		src.top = 0;
		src.right = bitmap.getWidth();
		src.bottom = bitmap.getHeight();
		target.left = 0;
		target.top = 0;
		target.bottom = (int) (src.bottom * scale);
		target.right = (int) (src.right * scale);
		// 开始画表盘图像
		canvas.drawBitmap(bitmap, src, target, paint);
		// 计算中心点横坐标
		float centerX = bitmap.getWidth() * scale * handCenterWidthScale;
		// 开始计算中心点纵坐标
		float centerY = bitmap.getHeight() * scale * handCenterHeightScale;
		// 关键点:在表中心画一个半径为5的实心圆圈,时针,分针将该圆的中心作为起始点
		canvas.drawCircle(centerX, centerY, 5, paint);
		// 分针设置3个像素
		paint.setStrokeWidth(3);
		// 日历
		Calendar calnet = Calendar.getInstance();// 获得日历一个实例
		int minute = calnet.get(Calendar.MINUTE);// 获得分钟
		int Hour = calnet.get(Calendar.HOUR);// 获得小时
		// 计算分针和时针角度
		double minuteRadian = Math.toRadians((360 - ((minute * 6) - 90)) % 360);
		double hourRadian = Math.toRadians((360 - ((Hour * 30) - 90)) % 360
				- (30 * minute / 60));
		// 在盘中画分针
		canvas.drawLine(centerX, centerY, (int) (centerX + minuteHandSize
				* Math.cos(minuteRadian)), (int) (centerY - minuteHandSize
				* Math.sin(minuteRadian)), paint);
		paint.setStrokeWidth(4);
		// 画时针
		canvas.drawLine(centerX, centerY,
				(int) (centerX + hourHandSize * Math.cos(hourRadian)),
				(int) (centerY - hourHandSize * Math.sin(hourRadian)), paint);

	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// TODO Auto-generated method stub
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);

		// 根据图像大小等比例设置视图大小
		setMeasuredDimension((int) (bitmap.getWidth() * scale),
				(int) (bitmap.getHeight() * scale));
	}

	@Override
	protected void onDetachedFromWindow() {
		// TODO Auto-generated method stub
		super.onDetachedFromWindow();
		handler.removeCallbacks(this);
	}

}
</span>

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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值