Android 雷达扫描效果

来源:互联网 发布:有办法屏蔽掉网络监控 编辑:程序博客网 时间:2024/04/28 07:08

    第一个实例 RadarView 用到了自定义属性,然后在构造方法里面读取相关属性值,用来确定绘制的参数 。RadarView 还提供了开始、停止扫描和释放资源的接口,具体实现看源码吧 。要注意的是 onDraw() 是频繁调用的方法,而且绘制过程比较耗时,所以尽量不要在这个方法里做初始化资源的操作,以确保自定义 View 的流畅体验 。同时,在 Activity 被销毁的时候,要停止 RadarView 里边的定时刷新线程,这一点不要漏掉了 。RadarView 源码

/** * Created by StormShadow on 2015/9/24:20:23. * Knowledge is power. */public class RadarView extends View {    private static final String LOG_TAG = RadarView.class.getName();    private boolean mIsShowText = true;//    private int mScreenWidth = 0;    private float mRectWidth = 0;    private float mRectHeight = 0;    private float mPadding = 0;    private float mCurAngle = 0; // 扇形当前的偏转角    private Boolean mScanFlag = true;    private Boolean mIsActivityDestoryed = false;    private Bitmap mBgBitmap;    private Rect mSrcRect;    private RectF mDesRectF;    private Paint mBgPaint;    private Paint mSectorPaint; // 画扇形的画笔    float mBigCircleRadius; // 大圆半径    float mCircleX; // 圆心 X 坐标    float mCircleY; // 圆心 Y 坐标    public RadarView(Context context) {        this(context, null);    }    public RadarView(Context context, AttributeSet attrs){        super(context, attrs);        TypedArray array = context.getTheme().obtainStyledAttributes(                attrs,                R.styleable.RadarView,                0, 0);        try {            mIsShowText = array.getBoolean(R.styleable.RadarView_isShowText, true); // 是否显示文字信息            mPadding = array.getDimension(R.styleable.RadarView_labelPadding, 20.0f); // 边距            mRectWidth = array.getDimension(R.styleable.RadarView_labelWidth, 720.0f); // 背景矩形宽度//            mRectHeight = array.getDimension(R.styleable.RadarView_labelHeight, 0.0f); // 为了防止变形,这里强制使高宽相等            mRectHeight = mRectWidth;        } finally {            array.recycle();        }        setBackgroundColor(0xff2a73b1);        init();    }    private void init() {//        mHandler = new Handler();        mBgPaint = new Paint();        mBgBitmap = BitmapFactory.decodeResource(this.getContext().getResources(), R.mipmap.act_radar_bg);        mBigCircleRadius = (mRectWidth - mPadding * 2) / 2; // 大圆半径        mCircleX = mRectWidth / 2; // 圆心 X 坐标        mCircleY = mRectHeight / 2; // 圆心 Y 坐标        mSrcRect = new Rect(                0,                0,                mBgBitmap.getWidth(),                mBgBitmap.getHeight()        );        mDesRectF = new RectF(                mCircleX - mBigCircleRadius,                mCircleY - mBigCircleRadius,                mCircleX + mBigCircleRadius,                mCircleY + mBigCircleRadius        );        mSectorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mSectorPaint.setStyle(Paint.Style.FILL);        mSectorPaint.setColor(0x7f99cc99); // 半透明,所以设置为7f 99cc99        Shader mShader = new LinearGradient(0, 0, 100, 100,                new int[] { Color.GREEN, Color.GREEN },                null,                Shader.TileMode.REPEAT); // 一个材质,打造出一个线性梯度沿著一条线。        mSectorPaint.setShader(mShader);        ScanThread scanThread = new ScanThread();        scanThread.start();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawBitmap(mBgBitmap, mSrcRect, mDesRectF, mBgPaint);        canvas.drawArc(mDesRectF, mCurAngle, 45, true, mSectorPaint);    }    public void startScanning() {        if(!mScanFlag) {            mScanFlag = true;        }    }    public void stopScanning() {        if(mScanFlag) {            Thread.interrupted();            mScanFlag = false;        }    }    protected class ScanThread extends Thread {        @Override        public void run() {            while(!mIsActivityDestoryed) {                if (mScanFlag) {                    try {                        Thread.sleep(10);                        mCurAngle = (mCurAngle + 1) % 360;                        postInvalidate();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }    }    public void setIsShowText(boolean showText) {        mIsShowText = showText;        invalidate();    }    public Boolean getIsShowText() {        return mIsShowText;    }    public Boolean isScanning() {        return mScanFlag;    }    public void realseResource() {        Thread.interrupted();        mIsActivityDestoryed = true;    }}

有图有真相


    第二个实例没有自定义属性,而且扫描扇形的旋转操作借助了 Matrix,要注意的是这个实例并没有处理好所有细节 。所以如果要使用它,请参照上面的例子来进行调整 。
这个例子非常简单,只有一个 View 类,继承了 FrameLayout,代码如下
/** * Created by StormShadow on 2015/9/24:21:35. * Knowledge is power. */public class RadarView extends FrameLayout {     private int mViewSize = 500;    private Paint mPaintLine;    private Paint mPaintSector;    private boolean mIsStarted = false;    private ScanThread mThread;    private int mCurAngle = 0; private Shader mShader; private Matrix mMatrix;     private final int paintWidth = 2;     public RadarView(Context context) {        super(context);        init();    }     public RadarView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }     private void init() {        initPaint();        mThread = new ScanThread();        setBackgroundColor(Color.TRANSPARENT);        mMatrix = new Matrix();        mShader = new SweepGradient(   mViewSize >> 1,   mViewSize >> 1,   new int[] {     Color.LTGRAY,     Color.GREEN,     },   null);    }     private void initPaint() {        mPaintLine = new Paint();        mPaintLine.setStrokeWidth(paintWidth);        mPaintLine.setAntiAlias(true);        mPaintLine.setStyle(Style.STROKE);        mPaintLine.setColor(0xffff0000);         mPaintSector = new Paint();        mPaintSector.setColor(0x9D00ff00);        mPaintSector.setAntiAlias(true);    }    @Override      protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        setMeasuredDimension(mViewSize, mViewSize);    }     public void startScanning() {        mThread.start();        mIsStarted = true;    }     public void stopScanning() {        if (mIsStarted) {            Thread.interrupted();            mIsStarted = false;        }    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int halfRadaSize = mViewSize >> 1;        canvas.drawCircle(halfRadaSize, halfRadaSize, halfRadaSize >> 1, mPaintLine);        canvas.drawCircle(halfRadaSize, halfRadaSize, halfRadaSize - (paintWidth >> 1), mPaintLine);        canvas.drawLine(halfRadaSize, 0, halfRadaSize, mViewSize, mPaintLine);        canvas.drawLine(0, halfRadaSize, mViewSize, halfRadaSize, mPaintLine);               mPaintSector.setShader(mShader);        canvas.concat(mMatrix);        canvas.drawCircle(halfRadaSize, halfRadaSize, halfRadaSize - paintWidth, mPaintSector);    }     protected class ScanThread extends Thread {         int halfRadaSize = mViewSize >> 1;                 @Override        public void run() {            while (mIsStarted) {                mCurAngle = (mCurAngle + 2) % 360;                mMatrix.reset();                mMatrix.postRotate(mCurAngle, halfRadaSize, halfRadaSize);                postInvalidate();                try {                    Thread.sleep(10);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        }    }}


效果图如下



下载源码


0 0