雷達擴散效果的實現

    相信大家都看像搜索附近、周邊人或事物的雷達擴散效果吧,那這個效果是這樣實現的呢,怎樣以一種高效的方式來實現呢?好了,先看看效果吧

實現思路

    雷達擴散效果我們可以把它看成是一組同心圓,並且隨着半徑的不斷增大,圓的填充色逐漸變成透明;並且發現兩個相鄰的同心圓的間距是相等的,這樣我們就可以只要最外邊緣的半徑值,就可以退出其他圓的半徑,從而用一個定時任務去實現這種漸變效果。

代碼部分

自定義一個RadarView

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
 *@date 2019/5/14
 *@desc 雷達擴散view
 *
 */

public class RadarView extends View {
    private int mWidth;
    private int mHeigth;
    private int mRadius;
    private int mCenterX;
    private int mCenterY;
    private int mColor;
    private int mAlpha;
    private boolean mIsAlpha;//是否需要漸變
    private int mSpace;//兩個環之間的間距
    private int mSpeed;//速度
    private Paint mPaint;
    private int mNum=1;
    private int mCurrMaxRadius;//當前顯示的最大半徑
    private boolean mIsStart;
    private int mDelayMillis=60;
    private Bitmap mCenterBitmap;//中心圖片

    private Runnable mRunnable=new Runnable() {
        @Override
        public void run() {
            if(mIsStart){
                invalidate();
                postDelayed(mRunnable,mDelayMillis);
            }
        }
    };



    public RadarView(Context context) {
        super(context);
        init();
    }

    public RadarView(Context context, @Nullable AttributeSet attrs) {
        this(context,attrs,0);
    }

    public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.radar_view, defStyleAttr, 0);
        mSpace=attributes.getInteger( R.styleable.radar_view_radar_view_space,150);
        mColor=attributes.getColor( R.styleable.radar_view_radar_view_color,0x80FF00FF);
        mSpeed=attributes.getInteger( R.styleable.radar_view_radar_view_speed,10);
        mIsAlpha=attributes.getBoolean(R.styleable.radar_view_radar_view_is_alpha,true);
        int imageId=attributes.getResourceId(R.styleable.radar_view_radar_view_center_image,0);
        if(imageId>0){
            mCenterBitmap= BitmapFactory.decodeResource(getResources(), imageId);
        }
        attributes.recycle();
        init();
    }

    private void init(){
        mPaint=new Paint();
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mAlpha=(mColor>>24)&0xFF;
    }

    public void setColor(int color){
        mColor=color;
        mPaint.setColor(mColor);
        mAlpha=(mColor>>24)&0xFF;
    }

    public void startSearch(){
        removeCallbacks(mRunnable);
        mIsStart=true;
        postDelayed(mRunnable,mDelayMillis);
    }

    public void stopSearch(){
        mIsStart=false;
        removeCallbacks(mRunnable);
    }




    @Override
    protected void onDraw(Canvas canvas) {
        if(mCurrMaxRadius>mRadius){
            mCurrMaxRadius-=mSpace;
        }
        mCurrMaxRadius+=mSpeed;
        int minRadius=0;
        if(mCenterBitmap!=null){
            minRadius=mCenterBitmap.getWidth()/2;
        }
        if(mIsAlpha) {
            for (int i = 0; i < mNum; i++) {
                int radius = mCurrMaxRadius - i * mSpace;
                if(radius>minRadius){
                    int colorGradient = mAlpha;
                    if (radius < mRadius) {
                        colorGradient = mAlpha * radius / mRadius;
                    }
                    colorGradient <<= 24;
                    mPaint.setColor(mColor - colorGradient);
                Log.d("RadarView","i="+i+" mAlpha="+Integer.toHexString(mAlpha).toUpperCase()+" radius="+radius+" colorGradient="+Integer.toHexString(colorGradient).toUpperCase()+" color="+Integer.toHexString(mColor - colorGradient).toUpperCase());
                    canvas.drawCircle(mCenterX, mCenterY, radius, mPaint);
                }
            }
        }else{
            for (int i = 0; i < mNum; i++) {
                int radius = mCurrMaxRadius - i * mSpace;
                if(radius>minRadius){
                    canvas.drawCircle(mCenterX, mCenterY, radius, mPaint);
                }
            }
        }
        if(minRadius>0){
            canvas.drawBitmap(mCenterBitmap,mCenterX-mCenterBitmap.getWidth()/2,mCenterY-mCenterBitmap.getHeight()/2,mPaint);
        }
    }






    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mWidth=measureValue(widthMeasureSpec);
        mHeigth=measureValue(heightMeasureSpec);
        mRadius=Math.max(mWidth,mHeigth)/2;
        setMeasuredDimension(mWidth,mHeigth);
        mNum=mRadius/mSpace;
        mRadius=mNum*mSpace;
        mCenterX=mWidth/2;
        mCenterY=mHeigth/2;
    }

    private int measureValue(int value){
        int specMode=MeasureSpec.getMode(value);
        int specSize=MeasureSpec.getSize(value);
        int result=0;
        switch (specMode){
            case MeasureSpec.EXACTLY:
                result=specSize;
                break;
            case MeasureSpec.AT_MOST:
                result=specSize;
                break;
            case MeasureSpec.UNSPECIFIED:
                result=200;
                break;
        }
        return result;
    }
}

添加自定義屬性

 <declare-styleable name="radar_view">
        <attr name="radar_view_space" format="integer"/><!--兩個環之間的間距-->
        <attr name="radar_view_color" format="color"/><!--圓環的顏色-->
        <attr name="radar_view_speed" format="integer"/><!--擴散的速度-->
        <attr name="radar_view_is_alpha" format="boolean"/><!--擴散是否需要漸變-->
        <attr name="radar_view_center_image" format="reference"/><!--中心圖片-->
    </declare-styleable>

接下來在自己的代碼中使用起來就可以了。如果想要demo的源碼,可以到這裏下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章