Android 自定义缩放球以及水纹效果

没事写着玩,效果图
这里写图片描述

这里写图片描述

在values中的attrs.xml 定义属性样式maxRadius为半径最大值

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="maxRadius" format="integer"></attr>

    <declare-styleable name="CanvasView">
        <attr name="maxRadius"/>
    </declare-styleable>
</resources>

Layout中使用,关键点在于xmlns:custom=”http://schemas.android.com/apk/res-auto”命名空间的添加以及自定义custom:maxRadius=”150”的使用。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="demo.cn.com.demo.MainActivity">

    <demo.cn.com.demo.view.CanvasView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        custom:maxRadius="150"
        />
</RelativeLayout>

缩放球效果的java Code

package demo.cn.com.demo.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import demo.cn.com.demo.R;

/**
 * Created by rander on 16-3-17.
 */
public class CanvasView extends View{
    public CanvasView(Context context) {
        this(context, null);
    }

    public CanvasView(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //解析自定义属性
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CanvasView, defStyleAttr, 0);
        final int count = typedArray.getIndexCount();
        for(int i=0 ;i < count;i++)
        {
            int attr = typedArray.getIndex(i);
            switch (attr)
            {
                case R.styleable.CanvasView_maxRadius:
                    maxRadius = typedArray.getInteger(attr,DEFAULT_RADIUS);
                    break;
            }
        }
        typedArray.recycle();
        init();
    }

    private Paint mPaint;
    /** 屏幕宽*/
    private int mScreenWith;
    /** 屏幕高*/
    private int mScreenHeight;
    /** 圆心x,y*/
    private int cx;
    private int cy;
    /** 半径,动态变化*/
    private int mRadius;
    /** 最大半径*/
    private int maxRadius;
    /** 用户没设的时候默认最大半径*/
    private static final int DEFAULT_RADIUS = 200;
    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(10);
        mPaint.setDither(true);
        mPaint.setAntiAlias(true);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mScreenWith = w;
        mScreenHeight = h;
        cx = mScreenWith/2;
        cy = mScreenHeight/2;
    }

    private static final int MSG = 0x7986;
    /** 是否需要递增*/
    private boolean isIncrease = true;
    Handler handler = new Handler()
    {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what)
            {
                case MSG:
                    /**是递增*/
                    if(isIncrease)
                    {
                        /**超过最大值就递减*/
                        if(mRadius > maxRadius)
                        {
                            isIncrease = false;
                        }
                        else
                        {
                            mRadius++;
                        }
                    }
                    else
                    {
                        /**小于0就递增*/
                        if(mRadius < 0)
                        {
                            isIncrease = true;
                        }
                        else
                        {
                            mRadius--;
                        }
                    }
                    invalidate();
                    break;
            }
        }
    };


    @Override
    protected void onDraw(Canvas canvas) {

        canvas.drawCircle(cx, cy, mRadius, mPaint);
        handler.sendEmptyMessage(MSG);
        super.onDraw(canvas);
    }
}

波浪纹的java Code

package rander.com.randerc.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LightingColorFilter;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.lang.ref.WeakReference;

import rander.com.randerc.R;

/**
 * Created by rander on 16-3-17.
 */
public class WaveView extends View{
    public WaveView(Context context) {
        this(context, null);
    }

    public WaveView(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //解析自定义属性
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CanvasView, defStyleAttr, 0);
        final int count = typedArray.getIndexCount();
        for(int i=0 ;i < count;i++)
        {
            int attr = typedArray.getIndex(i);
            switch (attr)
            {
                case R.styleable.CanvasView_maxRadius:
                    maxRadius = typedArray.getInteger(attr,DEFAULT_RADIUS);
                    break;
            }
        }
        typedArray.recycle();
        init();
    }

    private Paint mPaint;
    /** 屏幕宽*/
    private int mScreenWith;
    /** 屏幕高*/
    private int mScreenHeight;
    /** 圆心x,y*/
    private int cx;
    private int cy;
    /** 半径,动态变化*/
    private int mRadius;
    /** 最大半径*/
    private int maxRadius = DEFAULT_RADIUS;
    /** 用户没设的时候默认最大半径*/
    private static final int DEFAULT_RADIUS = 200;

    private Handler mHandler;
    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.RED);
        mPaint.setStrokeWidth(5);
        mPaint.setDither(true);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mHandler = new WaveHandler(this);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mScreenWith = w;
        mScreenHeight = h;
        cx = mScreenWith/2;
        cy = mScreenHeight/2;
    }

    private static final int MSG = 0x7986;
    /** 是否需要递增*/
    private boolean isIncrease = true;
    static class WaveHandler extends Handler
    {
        WeakReference<WaveView> wrf;

        public WaveHandler(WaveView waveView) {
            this.wrf = new WeakReference<WaveView>(waveView);
        }

        @Override
        public void handleMessage(Message msg) {
            WaveView waveView = wrf.get();
            if(waveView == null)
            {
                removeCallbacksAndMessages(null);
                return;
            }
            waveView.handleMessage(msg);
        }
    }

    private void handleMessage(Message msg)
    {
        switch (msg.what)
        {
            case MSG:
                /**是递增*/
                if(isIncrease)
                {
                    /**超过最大值就递减*/
                    if(mRadius > maxRadius)
                    {
                        isIncrease = false;
                    }
                    else
                    {
                        mRadius++;
                    }
                }
                else
                {
                    /**小于0就递增*/
                    if(mRadius < 0)
                    {
                        isIncrease = true;
                    }
                    else
                    {
                        mRadius--;
                    }
                }
                invalidate();
                break;
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if(mHandler != null)
        {
            mHandler.removeCallbacksAndMessages(null);
        }
    }

    /**波浪数量,可以在xml里面配置*/
    private final int WAVE_COUNT = 10;
    @Override
    protected void onDraw(Canvas canvas) {

        for(int i=0;i<WAVE_COUNT;i++)
        {
            canvas.drawCircle(cx, cy, mRadius - 20 * i, mPaint);
        }
        mHandler.sendEmptyMessage(MSG);
        super.onDraw(canvas);
    }
}

缩放球与水纹效果的实现区别如下:
1.画笔的不同Paint设置Paint.Style.STROKE样式可以画空心效果,不设置则是实心圆。
2.onDraw方法的实现不一样,缩放球只是画了一次,而水纹效果通过缩小半径画了好几个。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值