Android 自定義控件之圓形擴散View(DiffuseView)


 

實現效果

這里寫圖片描述

使用

XML中:

<com.airsaid.diffuseview.widget.DiffuseView
    android:id="@+id/diffuseView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    app:diffuse_color="@color/colorAccent"
    app:diffuse_coreColor="@color/colorPrimaryDark"
    app:diffuse_coreImage="@android:drawable/ic_menu_search"
    app:diffuse_coreRadius="100"
    app:diffuse_maxWidth="300"
    app:diffuse_width="4"/>

代碼中:

DiffuseView mDiffuseView = (DiffuseView) findViewById(R.id.diffuseView);
mDiffuseView.start(); // 開始擴散
mDiffuseView.stop();// 停止擴散

屬性&方法

屬性名 java方法 作用
diffuse_color setColor(int colorId) 設置擴散圓顏色
diffuse_coreColor setCoreColor(int colorId) 設置中心圓顏色
diffuse_coreImage setCoreImage(int imageId) 設置中心圓圖片
diffuse_coreRadius setCoreRadius(int radius) 設置中心圓半徑
diffuse_maxWidth setMaxWidth(int maxWidth) 設置最大擴散寬度
diffuse_width setDiffuseWidth(int width) 設置擴散圓寬度,值越小越寬

代碼

/**
 * Created by zhouyou on 2016/9/27.
 * Class desc:
 *
 * 這是一個自定義圓圈擴散View
 */
public class DiffuseView extends View {

    /** 擴散圓圈顏色 */
    private int mColor = getResources().getColor(R.color.colorAccent);
    /** 圓圈中心顏色 */
    private int mCoreColor = getResources().getColor(R.color.colorPrimary);
    /** 圓圈中心圖片 */
    private Bitmap mBitmap;
    /** 中心圓半徑 */
    private float mCoreRadius = 150;
    /** 擴散圓寬度 */
    private int mDiffuseWidth = 3;
    /** 最大寬度 */
    private Integer mMaxWidth = 255;
    /** 是否正在擴散中 */
    private boolean mIsDiffuse = false;
    // 透明度集合
    private List<Integer> mAlphas = new ArrayList<>();
    // 擴散圓半徑集合
    private List<Integer> mWidths = new ArrayList<>();
    private Paint mPaint;

    public DiffuseView(Context context) {
        this(context, null);
    }

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

    public DiffuseView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

       TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DiffuseView, defStyleAttr, 0);
        mColor = a.getColor(R.styleable.DiffuseView_diffuse_color, mColor);
        mCoreColor = a.getColor(R.styleable.DiffuseView_diffuse_coreColor, mCoreColor);
        mCoreRadius = a.getFloat(R.styleable.DiffuseView_diffuse_coreRadius, mCoreRadius);
        mDiffuseWidth = a.getInt(R.styleable.DiffuseView_diffuse_width, mDiffuseWidth);
        mMaxWidth = a.getInt(R.styleable.DiffuseView_diffuse_maxWidth, mMaxWidth);
        int imageId = a.getResourceId(R.styleable.DiffuseView_diffuse_coreImage, -1);
        if(imageId != -1) mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
        a.recycle();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mAlphas.add(255);
        mWidths.add(0);
    }

    @Override
    public void invalidate() {
        if(hasWindowFocus()){
            super.invalidate();
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        // 繪制擴散圓
        mPaint.setColor(mColor);
        for (int i = 0; i < mAlphas.size(); i++) {
            // 設置透明度
            Integer alpha = mAlphas.get(i);
            mPaint.setAlpha(alpha);
            // 繪制擴散圓
            Integer width = mWidths.get(i);
            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius + width, mPaint);

            if(alpha > 0 && width < mMaxWidth){
                mAlphas.set(i, alpha - 1);
                mWidths.set(i, width + 1);
            }
        }
        // 判斷當擴散圓擴散到指定寬度時添加新擴散圓
        if (mWidths.get(mWidths.size() - 1) == mMaxWidth / mDiffuseWidth) {
            mAlphas.add(255);
            mWidths.add(0);
        }
        // 超過10個擴散圓,刪除最外層
        if(mWidths.size() >= 10){
            mWidths.remove(0);
            mAlphas.remove(0);
        }

        // 繪制中心圓及圖片
        mPaint.setAlpha(255);
        mPaint.setColor(mCoreColor);
        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mCoreRadius, mPaint);

        if(mBitmap != null){
            canvas.drawBitmap(mBitmap, getWidth() / 2 - mBitmap.getWidth() / 2
                    , getHeight() / 2 - mBitmap.getHeight() / 2, mPaint);
        }

        if(mIsDiffuse){
            invalidate();
        }
    }

    /**
     * 開始擴散
     */
    public void start() {
        mIsDiffuse = true;
        invalidate();
    }

    /**
     * 停止擴散
     */
    public void stop() {
        mIsDiffuse = false;
    }

    /**
     * 是否擴散中
     */
    public boolean isDiffuse(){
        return mIsDiffuse;
    }

    /**
     * 設置擴散圓顏色
     */
    public void setColor(int colorId){
        mColor = colorId;
    }

    /**
     * 設置中心圓顏色
     */
    public void setCoreColor(int colorId){
        mCoreColor = colorId;
    }

    /**
     * 設置中心圓圖片
     */
    public void setCoreImage(int imageId){
        mBitmap = BitmapFactory.decodeResource(getResources(), imageId);
    }

    /**
     * 設置中心圓半徑
     */
    public void setCoreRadius(int radius){
        mCoreRadius = radius;
    }

    /**
     * 設置擴散圓寬度(值越小寬度越大)
     */
    public void setDiffuseWidth(int width){
        mDiffuseWidth = width;
    }

    /**
     * 設置最大寬度
     */
    public void setMaxWidth(int maxWidth){
        mMaxWidth = maxWidth;
    }
}

源碼下載

GitHub:https://github.com/Airsaid/DiffuseView


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM