Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義View——QQ音樂中圓形旋轉碟子

Android自定義View——QQ音樂中圓形旋轉碟子

編輯:關於Android編程

思路分析:

1、在onMeasure中測量整個View的寬和高後,設置寬高

2、獲取我們res的圖片資源後,在ondraw方法中進行繪制圓形圖片

3、通過Handler發送Runnable來啟動旋轉線程(如果只想做圓形頭像的話,這步可以去掉)

4、在布局中使用我們的View


效果圖:

\

 

貼出我們的變量信息:

 

    //view的寬和高
    int mHeight = 0;
    int mWidth = 0;
    //圓形圖片
    Bitmap bitmap = null;
    //圓形圖片的真實半徑
    int radius = 0;
    //旋轉動畫的矩形
    Matrix matrix = new Matrix();
    //旋轉動畫的角度
    int degrees = 0;

 

步驟一:測量整個View的寬和高後,設置寬高

 

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //測量整個View的寬和高
        mWidth = measuredWidth(widthMeasureSpec);
        mHeight= measuredHeight(heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
    }

    private int measuredWidth(int widthMeasureSpec) {
        int Mode = MeasureSpec.getMode(widthMeasureSpec);
        int Size = MeasureSpec.getSize(widthMeasureSpec);
        if (Mode == MeasureSpec.EXACTLY) {
            mWidth = Size;
        } else {
            //由圖片決定寬度
            int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth();
            if (Mode == MeasureSpec.AT_MOST) {
                //由圖片和Padding決定寬度,但是不能超過View的寬
                mWidth = Math.min(value, Size);
            }
        }
        return mWidth;
    }

    private int measuredHeight(int heightMeasureSpec) {
        int Mode = MeasureSpec.getMode(heightMeasureSpec);
        int Size = MeasureSpec.getSize(heightMeasureSpec);
        if (Mode == MeasureSpec.EXACTLY) {
            mHeight = Size;
        } else {
            //由圖片決定高度
            int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight();
            if (Mode == MeasureSpec.AT_MOST) {
                //由圖片和Padding決定高度,但是不能超過View的高
                mHeight = Math.min(value, Size);
            }
        }
        return mHeight;
    }

步驟二:獲取我們res的圖片資源後,在ondraw方法中進行繪制圓形圖片
        //獲取res的圖片資源
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.concat(matrix);
        //真實的半徑必須是View的寬高最小值
        radius = Math.min(mWidth, mHeight);
        //如果圖片本身寬高太大,進行相應的縮放
        bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);
        //畫圓形圖片
        canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null);
        matrix.reset();
    }

    private Bitmap createCircleImage(Bitmap source, int radius) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
        //產生一個同樣大小的畫布
        Canvas canvas = new Canvas(target);
        //首先繪制圓形
        canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);
        //使用SRC_IN模式顯示後畫圖的交集處
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //繪制圖片,從(0,0)畫
        canvas.drawBitmap(source, 0, 0, paint);
        return target;
    }

步驟三:通過Handler發送Runnable來啟動旋轉線程

 

 

        //開始旋轉
        mHandler.post(runnable);
    //-----------旋轉動畫-----------
    Handler mHandler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            matrix.postRotate(degrees++, radius / 2, radius / 2);
            //重繪
            invalidate();
            mHandler.postDelayed(runnable, 50);
        }
    };

步驟四:在布局中使用我們的View

 

 

    

 

下面是整個類的源碼

public class MyCycleView extends View {

    //view的寬和高
    int mHeight = 0;
    int mWidth = 0;
    //圓形圖片
    Bitmap bitmap = null;
    //圓形圖片的真實半徑
    int radius = 0;
    //旋轉動畫的矩形
    Matrix matrix = new Matrix();
    //旋轉動畫的角度
    int degrees = 0;

    //-----------旋轉動畫-----------
    Handler mHandler = new Handler();
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            matrix.postRotate(degrees++, radius / 2, radius / 2);
            //重繪
            invalidate();
            mHandler.postDelayed(runnable, 50);
        }
    };

    public MyCycleView(Context context) {
        super(context);
        initView();
    }

    public MyCycleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MyCycleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    public void initView() {
        //獲取res的圖片資源
        bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
        //開始旋轉
        mHandler.post(runnable);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //測量整個View的寬和高
        mWidth = measuredWidth(widthMeasureSpec);
        mHeight = measuredHeight(heightMeasureSpec);
        setMeasuredDimension(mWidth, mHeight);
    }

    private int measuredWidth(int widthMeasureSpec) {
        int Mode = MeasureSpec.getMode(widthMeasureSpec);
        int Size = MeasureSpec.getSize(widthMeasureSpec);
        if (Mode == MeasureSpec.EXACTLY) {
            mWidth = Size;
        } else {
            //由圖片決定寬度
            int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth();
            if (Mode == MeasureSpec.AT_MOST) {
                //由圖片和Padding決定寬度,但是不能超過View的寬
                mWidth = Math.min(value, Size);
            }
        }
        return mWidth;
    }

    private int measuredHeight(int heightMeasureSpec) {
        int Mode = MeasureSpec.getMode(heightMeasureSpec);
        int Size = MeasureSpec.getSize(heightMeasureSpec);
        if (Mode == MeasureSpec.EXACTLY) {
            mHeight = Size;
        } else {
            //由圖片決定高度
            int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight();
            if (Mode == MeasureSpec.AT_MOST) {
                //由圖片和Padding決定高度,但是不能超過View的高
                mHeight = Math.min(value, Size);
            }
        }
        return mHeight;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.concat(matrix);
        //真實的半徑必須是View的寬高最小值
        radius = Math.min(mWidth, mHeight);
        //如果圖片本身寬高太大,進行相應的縮放
        bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false);
        //畫圓形圖片
        canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null);
        matrix.reset();
    }

    private Bitmap createCircleImage(Bitmap source, int radius) {
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
        //產生一個同樣大小的畫布
        Canvas canvas = new Canvas(target);
        //首先繪制圓形
        canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);
        //使用SRC_IN模式顯示後畫圖的交集處
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        //繪制圖片,從(0,0)畫
        canvas.drawBitmap(source, 0, 0, paint);
        return target;
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved