Android自定义控件初学

这篇博客介绍了Android自定义控件的基础知识,包括控件代码编写、注意事项,如在构造函数中初始化Paint和相关类,避免在onDraw()中创建对象。作者强调在onTouchEvent()中处理触摸事件,并调用invalidate()来刷新视图。此外,还提到了onMeasure()方法的重要性,用于确定控件的正确大小。博客还讨论了如何处理按下和松开时的颜色变化。

Android自定义控件初学

花了半个小时学了下自定义控件

自定义控件参考 http://blog.youkuaiyun.com/cym492224103/article/details/38438727 不再赘述
Paint属性参考 http://blog.youkuaiyun.com/xanxus46/article/details/7883554

控件代码

package com.example.customwidget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class MyVolumeWidget extends View{

    private static final String TAG = "MyVolumeWidget";
    private Paint mPaint;
    private float strokeWidth=5;
    private RectF rect;

     // 控件宽高  
    private int w;  
    private int h;


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

    public MyVolumeWidget(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
        initView();
    }

    public MyVolumeWidget(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        initView();
    }


    private void initView() {
        // TODO Auto-generated method stub
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(strokeWidth);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStyle(Paint.Style.STROKE);
        rect = new RectF(0,0,100,100);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        Log.d(TAG,"onDraw(Canvas canvas)");
        canvas.drawRect(rect, mPaint);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        w = resolveSize(100, widthMeasureSpec);  
        h = resolveSize(100, heightMeasureSpec); 
        setMeasuredDimension(w, h);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        Log.d(TAG,"onTouchEvent=>" + event.getAction());
        switch(event.getAction()){
        case MotionEvent.ACTION_DOWN:
            mPaint.setColor(Color.BLUE);
            break;
        case MotionEvent.ACTION_UP:
            mPaint.setColor(Color.GRAY);
            break;

        }
        invalidate();
        return true;
    }



}

注意点

系统默认调用两个形参的构造函数View(Context context, AttributeSet attrs)

最好在每个构造函数里调用初始化函数,本文是initView()函数。在这里面建好Panit和需要的类,不要在onDraw()里面调用。因为onDraw()函数会频繁调用,在里面新建类开销大。

onTouchEvent(MotionEvent event)里面写上触摸后动作。如果需要改变外观,需要在最后调用invalidate();函数。它会自动调用onDraw()函数,否则外观不刷新。

经测试当此函数返回值是return super.onTouchEvent(event);时,在一次触摸中只能识别第一个动作,即MotionEvent.ACTION_DOWN ,之后的滑动以及MotionEvent.ACTION_UP 无法检测。需要把返回改为return true;

onMeasure(int widthMeasureSpec, int heightMeasureSpec)方法里面需要调用resolveSize()方法来获得正确的大小,不太懂。

按下的颜色
按下的颜色

松开的颜色
松开的颜色

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值