自定义控件开关,绘制图片。

来源:互联网 发布:云计算的未来发展趋势 编辑:程序博客网 时间:2024/06/02 23:36

资源来源黑马培训机构教学视频

前段时间,学习了自定义控件,后来绝的用处很大,所以来和大家分享一下,自定义布局控件的使用,自定义控件,自己绘制控件。

步骤和另外一个一样,就不写步骤顺序那些麻烦的东西了。

主要的操作就是:
要自己写 onMeasure(…)方法。该方法 测量尺寸时的回调方法。
onDraw() 方法,该方法绘制
invalidate();该方法用于刷新,调用该方法后系统会自动调用onDraw();方法。

public class MyToggleButton extends View implements View.OnClickListener {    //滑动图片的资源id    private int slideBtnId;    //背景图的资源id    private int backgroundId;    private Paint paint;    private Bitmap backgroudBitmap;    private Bitmap slideBtn;    /**     * 滑动按钮的左边接     */    private float slideBtn_left = 0;    //在代码里面创建对象的时候创建,使用该够着方法    public MyToggleButton(Context context) {        super(context);    }    /**     * 在布局文件中声明 的 view 创建时系统自动调用     */    public MyToggleButton(Context context, AttributeSet attrs) {        super(context, attrs);        //获得自定义的属性        TypedArray ta = context.obtainStyledAttributes(                attrs, R.styleable.MyToggleBtn);        int n = ta.getIndexCount();        for (int i = 0; i < n; i++) {            /*获取某个属性的id值*/            int itemId = ta.getIndex(i);            switch (itemId) {                case R.styleable.MyToggleBtn_curr_state:                    currState = ta.getBoolean(itemId, false);                    break;                case R.styleable.MyToggleBtn_my_background:                    backgroundId = ta.getResourceId(itemId, -1);                    if (backgroundId == -1) {                        throw new RuntimeException("请设置背景图片");                    }                    backgroudBitmap = BitmapFactory.decodeResource(                            getResources(), backgroundId);                    break;                case R.styleable.MyToggleBtn_my_slide_btn:                    slideBtnId = ta.getResourceId(itemId, -1);                    if (slideBtnId == -1) {                        throw new RuntimeException("请设置资源图片");                    }                    slideBtn = BitmapFactory.decodeResource(                            getResources(), slideBtnId                    );                    break;            }        }        initView();    }    private void initView() {//        backgroudBitmap = BitmapFactory.//                decodeResource(getResources(), R.drawable.switch_background);//        slideBtn = BitmapFactory.decodeResource(getResources(),//                R.drawable.slide_button);        //初始化画逼        paint = new Paint();        paint.setAntiAlias(true);//打开抗锯齿        //添加onclick的监听        setOnClickListener(this);        flushState();    }    /**'     * view 对象显示的屏幕上,有几个步骤     * 1.构造方法的创建     * 2,测量view的大小     * 3,确定view的位置,view自身的一些建议权,决定权在父view手中的     * 4,绘制view的内容,     *     */    /**     * 测量尺寸时的回调方法。     *     * @param widthMeasureSpec     * @param heightMeasureSpec     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        /**         * 设置当前view的         * 宽度,高度, --> 单位像素值。         */        setMeasuredDimension(backgroudBitmap.getWidth(), backgroudBitmap.getHeight());    }    /*        确定位置的时候调用该方法        对自定义view的时候自定义不大。     *///    @Override//    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {//        super.onLayout(changed, left, top, right, bottom);//    }    /**     * 当前开关的状态,默认 开     */    private boolean currState = false;    @Override    protected void onDraw(Canvas canvas) {//        super.onDraw(canvas);        //绘制背景,paint绘制图片要使用的画笔        canvas.drawBitmap(backgroudBitmap, 0, 0, paint);        //绘制课滑动的按钮        canvas.drawBitmap(slideBtn, slideBtn_left, 0, paint);    }    /**     * 判断是否发送拖动了,就不相应onclick时间     */    private boolean isDrag = false;    /**     * onclick事件在View.onTouchEvent 中被解析,     * 系统对事件的解析,过于简陋,只有有down事件和up事件,     * 系统便认为发生了onclick     *     * @param v     */    @Override    public void onClick(View v) {        if (!isDrag) {  //如果没有拖动,            currState = !currState;            flushState();        }    }    /**     * down 事件的x值     */    private int firstX;    /**     * touch事件的上一个X值     */    private int lastX;    @Override    public boolean onTouchEvent(MotionEvent event) {        super.onTouchEvent(event);        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                firstX = lastX = (int) event.getX();                isDrag = false;                break;            case MotionEvent.ACTION_MOVE:                //判断是否发生拖动,                if (Math.abs(event.getX() - firstX) > 5) {                    isDrag = true;                }                int dis = (int) (event.getX() - lastX);                //将本次的位置,设置给lastX                lastX = (int) event.getX();                //根据手指移动的距离,改变slideBtn_left的值                slideBtn_left = slideBtn_left + dis;                break;            case MotionEvent.ACTION_UP:                //在发生拖动的情况下,根据最后的位置判断当前开关的额状态                if (isDrag) {                    int maxLeft = backgroudBitmap.getWidth() -                            slideBtn.getWidth();                    //根据slideBtn——left判段,当前应该是上面状态                    if (slideBtn_left > maxLeft / 2) {                        currState = true;                    } else {                        currState = false;                    }                    flushState();                }                break;        }        flushView();        return true;//返回false将不处理函数    }    /**     * 刷新当前视图     */    private void flushView() {        //要对 slideBtn_left的值进行判断,保证合理的位置        int maxLeft = backgroudBitmap.getWidth() -                slideBtn.getWidth();        slideBtn_left = (slideBtn_left > 0) ? slideBtn_left : 0;        slideBtn_left = (slideBtn_left < maxLeft) ? slideBtn_left : maxLeft;        invalidate();//刷新当前视图,调用onDraw();    }    /**     * 刷新当前状态     */    private void flushState() {        if (currState) {            slideBtn_left = backgroudBitmap.getWidth()                    - slideBtn.getWidth();        } else {            slideBtn_left = 0;        }        flushView();    }}

“`

注意,如果测试,一定要导入图片,这是绘制图片的自定义方法

0 0