自定义view:一个大写加粗带下划线的烧饼

首先是效果图:

自定义view:一个大写加粗带下划线的烧饼_第1张图片

然后分析一下我写的代码:

通过阅读郭神的博客了解到自定义view大体包含3种:自绘控件,组合控件,和继承控件。

我用的是第一种,自绘控件。自绘控件继承自view,重写ondraw方法,绘制自己需要的视图。

上图的实现,用了两个自绘的view,那个圆环是一个,那个圆球是一个。

那个圆环的实现比较简单,来看一下代码:

/**
 * Created by J on 2016/3/25.
 */
public class CircleView extends View {
    Paint mPaint1, mPaint2;
    int r ;
    int r0 = 5;
    public void setR(int r) {
        this.r = r;
    }

    public CircleView(Context context) {
        super(context);
    }

    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    private void initPaint() {
        mPaint1 = new Paint();
        mPaint1.setColor(getResources().getColor(R.color.color_6c6c6c));
        mPaint1.setAntiAlias(true);
        mPaint2 = new Paint();
        mPaint2.setColor(getResources().getColor(R.color.color_2ea9ff));
        mPaint2.setAntiAlias(true);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, r + r0, mPaint2);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, r, mPaint1);
    }

    public void changSize(int w) {
        r = w;
        invalidate();
    }

}

我取了个名字叫CircleView,继承自View,需要重写一下他的构造方法,有四个构造方法,一般重写两个就够了,其中第一个构造方法

 public CircleView(Context context) {
        super(context);
 }

这个构造方法,是用来new的,比如CircleView circle = new CircleView(this),就会调用这个构造方法,而第二个:

  public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
 }


这个构造方法是在加载xml布局文件时调用的,你定义的属性也在这里调用,当然我没有定义,只是单纯的在xml里用了这个控件:

<com.xzj.TouchCircle
    android:id="@+id/TouchCircle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

在加载控件的时候可以看到构造方法里实例化了paint,画笔,看一下方法:

private void initPaint() {
        mPaint1 = new Paint();
        mPaint1.setColor(getResources().getColor(R.color.color_6c6c6c));
        mPaint1.setAntiAlias(true);
        mPaint2 = new Paint();
        mPaint2.setColor(getResources().getColor(R.color.color_2ea9ff));
        mPaint2.setAntiAlias(true);

    }

在这里边实例化了两个不同的画笔,当然在ondraw方法里也画了两个圆:

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, r + r0, mPaint2);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, r, mPaint1);
    }

圆环其实是这样实现的:一个大圆套一个小圆,小圆与背景色一样,这样就形成了圆环。它为什么会变大变小的,因为我写了一个方法:

public void changSize(int w) {
        r = w;
        invalidate();
    }

给方法传参,改变半径,并且调用invalid()方法重绘视图。圆环讲完了,再来看一下移动的圆:

/**
 * Created by J on 2016/3/24.
 */
public class TouchCircle extends View {
    private Paint mPaint;
    private CircleView Circle;
    int tmpcy = 0;
    int tmpcx = 0;
    int r;
    int type = 0;
    int cy;
    int cx;
    int cr;

    public void setCr(int cr) {
        this.cr = cr;
    }

    public void setR(int r) {
        this.r = r;
    }

    public void setListener(TouchCircleListener listener) {
        this.listener = listener;
    }

    TouchCircleListener listener;

    public TouchCircle(Context context) {
        super(context);
    }


    public TouchCircle(Context context, AttributeSet attrs) {
        super(context, attrs);
        iniPaint();
    }

    private void iniPaint() {
        mPaint = new Paint();
        mPaint.setColor(getResources().getColor(R.color.color_cb6854));
        mPaint.setAntiAlias(true);
    }

    public void setView(CircleView circle) {
        this.Circle = circle;
    }

    public void setCy(int cy) {
        this.cy = cy;
    }


    public void setCx(int cx) {
        this.cx = cx;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(cx, cy, r, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                tmpcx = (int) event.getX();
                tmpcy = (int) event.getY();
                int Lx = tmpcx - cx;
                int Ly = tmpcy - cy;
                if ((Lx > -r && Lx < r) && (Ly > -r && Ly < r)) {
                    return true;
                }
                return false;
            case MotionEvent.ACTION_MOVE:
                cx = (int) event.getX();
                cy = (int) event.getY();
                break;
            case MotionEvent.ACTION_UP:
                //抬起
                if (inCircle()) {
                    r = 0;
                    type++;
                    listener.onTouchCircle(type);
                }
                break;
        }
        if (inCircle() && r != 0) {
            Circle.changSize(cr+30);
        } else {
            Circle.changSize(cr);
        }
        invalidate();
        return super.onTouchEvent(event);
    }

    private boolean inCircle() {
        int R = 80;
        int r1 = getWidth() / 2 > cx ? getWidth() / 2 - cx : cx - getWidth() / 2;
        int r2 = getHeight() / 2 > cy ? getHeight() / 2 - cy : cy - getHeight() / 2;
        if (r1 * r1 < R * R && r2 * r2 < R * R && r1 < R - 50 / 2 && r2 < R - 50 / 2) {
            return true;
        }
        return false;
    }
}

实例化了一个画笔,画了一个圆,之所以能够移动是因为重写了onTouch方法:

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                tmpcx = (int) event.getX();
                tmpcy = (int) event.getY();
                int Lx = tmpcx - cx;
                int Ly = tmpcy - cy;
                if ((Lx > -r && Lx < r) && (Ly > -r && Ly < r)) {
                    return true;
                }
                return false;
            case MotionEvent.ACTION_MOVE:
                cx = (int) event.getX();
                cy = (int) event.getY();
                break;
            case MotionEvent.ACTION_UP:
                //抬起
                if (inCircle()) {
                    r = 0;
                    type++;
                    listener.onTouchCircle(type);
                }
                break;
        }
        if (inCircle() && r != 0) {
            Circle.changSize(cr+30);
        } else {
            Circle.changSize(cr);
        }
        invalidate();
        return super.onTouchEvent(event);
    }

把触摸的坐标当作圆心的坐标,重绘视图,看起来就像是在移动,

 case MotionEvent.ACTION_DOWN:
                tmpcx = (int) event.getX();
                tmpcy = (int) event.getY();
                int Lx = tmpcx - cx;
                int Ly = tmpcy - cy;
                if ((Lx > -50 && Lx < 50) && (Ly > -50 && Ly < 50)) {
                    return true;
                }
                return false;

这一部分很重要,限定了点下的位置,只有点到圆的时候才可以移动

 private boolean inCircle() {
        int R = 80;
        int r1 = getWidth() / 2 > cx ? getWidth() / 2 - cx : cx - getWidth() / 2;
        int r2 = getHeight() / 2 > cy ? getHeight() / 2 - cy : cy - getHeight() / 2;
        if (r1 * r1 < R * R && r2 * r2 < R * R && r1 < R - 50 / 2 && r2 < R - 50 / 2) {
            return true;
        }
        return false;
    }

这个方法判断了是否在圆环范围之内,当圆球在圆环的范围内,不抬起时,圆环变大,抬起时,圆环变为原来的大小,圆球的半径变为0,看起来圆环把圆球吞了。

圆环吞圆球的时候还包含了activity的跳转,在View里边是不能直接跳的,所以定义了一个监听:

/**
 * Created by J on 2016/3/29.
 */
public interface TouchCircleListener {

    void onTouchCircle(int touch);
}

在Activity里给View设置监听:

touchCircle.setListener(new TouchCircleListener() {
    @Override
    public void onTouchCircle(int touch) {
        if (touch == 1) {
            startActivity(new Intent(MainActivity.this, SecondActivity.class));
            finish();
        }
    }
});

满足条件就跳转,两个圆的时候怎么监听呢? 给两个圆球都设置监听:

touchCircle1.setListener(new TouchCircleListener() {
        @Override
        public void onTouchCircle(int touch) {
            if (touch == 1) {
                type++;
                jump();
            }
        }
    });
    touchCircle2.setListener(new TouchCircleListener() {
        @Override
        public void onTouchCircle(int touch) {
            if (touch == 1) {
                type++;
                jump();
            }
        }
    });

}

private void jump() {
    if (type == 2) {
        startActivity(new Intent(SecondActivity.this, ThirdActivity.class));
        finish();
    }
}

这样当两个球都被吞的时候就会跳第三个Activity。

Over




你可能感兴趣的:(自定义view:一个大写加粗带下划线的烧饼)