嗯。。再差1篇就可以获得持之以恒徽章了,今天带大家画一个比较简单的view。

    转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50477108

    废话不多说,看效果图:

    手把手带你画一个动态错误提示 Android自定义view - 图1

    首先 构造函数 测量… 这里就一笔带过了。

    1. public ErrorView(Context context) {
    2. this(context, null);
    3. }
    4. public ErrorView(Context context, AttributeSet attrs) {
    5. this(context, attrs, 0);
    6. }
    7. public ErrorView(Context context, AttributeSet attrs, int defStyleAttr) {
    8. super(context, attrs, defStyleAttr);
    9. }
    10. @Override
    11. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    12. int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    13. int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    14. int heightSize = MeasureSpec.getSize(heightMeasureSpec);
    15. int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    16. if (widthMode == MeasureSpec.EXACTLY) {
    17. mWidth = widthSize;
    18. } else {
    19. mWidth = 200;
    20. }
    21. if (heightMode == MeasureSpec.EXACTLY) {
    22. mHeight = heightSize;
    23. } else {
    24. mHeight = 200;
    25. }
    26. setMeasuredDimension(mWidth, mHeight);
    27. }

    如果你看不懂上面这些,翻翻我的这一篇博客,有一些补充的知识点。圆形百分比view

    接下来draw,如果让你绘制一个静态的这个突然,你一定闭着眼也能画出来。。那么怎么才能实现动态的效果呢。。

    其实就是模仿手绘的过程,我们是一点一点画出来的,一条线的逐渐延迟。 那我们就来模仿这个自然的过程。

    首先画一个圆形。

    1. Paint p = new Paint();
    2. p.setStrokeWidth(10);
    3. p.setAntiAlias(true);
    4. p.setColor(Color.RED);
    5. p.setStyle(Paint.Style.STROKE);
    6. RectF rectF = new RectF(0 + 10, 0 + 10, mWidth - 10, mHeight - 10);
    7. canvas.drawArc(rectF, 180, 360 * mProgress / 100, false, p);
    8. mProgress+=5;

    可以看到drawArc的第三个参数 是变化的 , 其中mProgress的初值是零,这里让他自增,也就是说,每次调用onDraw方法,他就会增加。所以每次的弧都会比原来长一点点,直到最后画完。 所以在程序的最后 一定有 postInvalidateDelayed(10); 方法。

    接下来来绘制两条线,这里的坐标我直接取半径的4分之一啦,唯一注意一点就是,只有在progress大于100的时候 我们才绘制两条线,两条线段也是根据一个变量自增的,原理同上。 这里mLineOneX等参数均表示画线的时候两点的坐标。 当mLineOneX = mWidth * 0.5的时候 mWidth /4 + mLineOneX 就等于我们要画线段的最终点。

    手把手带你画一个动态错误提示 Android自定义view - 图2

    1. if (mProgress > 100) {
    2. //画左边的线
    3. if (mLineOneX < mWidth * 0.5) {
    4. mLineOneX+=20;
    5. mLineOneY+=20;
    6. }
    7. canvas.drawLine(mWidth / 4, mHeight / 4, mWidth / 4 + mLineOneX, mHeight / 4 + mLineOneY, p);
    8. if (mLineOneX == mWidth * 0.5) {
    9. if (mLineTwoX < mWidth * 0.5) {
    10. mLineTwoX+=20;
    11. mLineTwoY+=20;
    12. }else {
    13. //判断全部绘制完成
    14. isLineDrawDone = true;
    15. }
    16. canvas.drawLine(mWidth / 4, (float) (mHeight * 0.75), mWidth / 4 + mLineTwoX, (float) (mHeight * 0.75) - mLineTwoY, p);
    17. }
    18. }

    之后 添加一个标记位 isLineDrawDone 判断一下 如果没有画完 则 :

    1. if(isLineDrawDone){
    2. Log.e("wing","draw done");
    3. }else{
    4. postInvalidateDelayed(10);
    5. }

    现在 基本上完成了绘制, 别急 还没加震动,震动效果是怎么实现的呢,大家还记得吗,如果忘了,可以看看我这篇博客:自定义动画 实现抖一抖效果

    所以我们要写一个接口,来回调onStop

    1. public interface OnStopListener{
    2. void onStop(View v);
    3. }

    把最后的绘制完成完善,继续增加一个标志位,代表全部绘制完成

    1. if(isLineDrawDone){
    2. Log.e("wing","draw done");
    3. if(!isDrawDone) {
    4. if (mOnStopListener != null) {
    5. mOnStopListener.onStop(this);
    6. }
    7. isDrawDone = true;
    8. }
    9. }else{
    10. postInvalidateDelayed(10);
    11. }

    提供一个reset()方法 让用户可以手动控制重绘

    1. public void reset() {
    2. mProgress = 0;
    3. mLineOneX = 0;
    4. mLineOneY = 0;
    5. mLineTwoX = 0;
    6. mLineTwoY = 0;
    7. isLineDrawDone = false;
    8. isDrawDone = false;
    9. invalidate();
    10. }

    在提供一个添加监听器的方法

    1. public void setOnStopListener(OnStopListener onStopListener){
    2. mOnStopListener = onStopListener;
    3. }

    最后 在Activity中 为这个View添加 震动效果

    1. protected void onCreate(Bundle savedInstanceState) {
    2. super.onCreate(savedInstanceState);
    3. setContentView(R.layout.activity_main);
    4. mErrorView = (ErrorView) findViewById(R.id.errorView);
    5. mErrorView.setOnStopListener(new ErrorView.OnStopListener() {
    6. @Override
    7. public void onStop(View v) {
    8. ShakeAnimation sa = new ShakeAnimation();
    9. sa.setDuration(1000);
    10. v.startAnimation(sa);
    11. }
    12. });
    13. mErrorView.setOnClickListener(new View.OnClickListener() {
    14. @Override
    15. public void onClick(View v) {
    16. mErrorView.reset();
    17. }
    18. });

    嘿嘿嘿。。。这样就骗到了持之以恒勋章。

    源码地址:http://download.csdn.net/detail/wingichoy/9394685