Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義View之圖形圖像(模仿360的刷新球自定義一個SeekBar)

Android自定義View之圖形圖像(模仿360的刷新球自定義一個SeekBar)

編輯:關於Android編程

概述:

360安全衛士的那個刷新球(姑且叫它刷新球,因為真的不知道叫什麼好,不是dota裡的刷新球!!),裡面像住了水一樣,生動可愛,看似簡單,寫起來不太簡單,本例程只是實現了它的部分功能而已,說實話,跟360的刷新球比起來差距還是很大,我這個長得有點挫。
本歷程需要用到的知識包括:android的自定義View,自定義canvas、path、Bitmap、Handler

先結果演示:
這裡寫圖片描述

Damo

public class MyPathView extends View {
    private int width;
    private int height;
    private int progress;
    private int maxProgress = 100;

    private Path mPath;
    private Paint mPaintCircle;
    private Paint mPaintWave;
    private Paint mPaintText;
    private Bitmap mBitmapBubble;
    private Canvas mCanvasBitmap;

    private int size = 0;//水波動幅度
    private int count;//水流動距離
    private boolean isAdd = true;
    private static final int START_WAVE = 0x21;

    public int getProgress() {
        return progress;
    }

    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }

    public int getMaxProgress() {
        return maxProgress;
    }

    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
    }

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case START_WAVE:
                    count += 30;
                    if (count >= 180) {
                        count = 0;
                    }
                    if (isAdd) {
                        size += 7;
                        if (size > 41) {
                            isAdd = false;
                        }
                    } else {
                        size -= 7;
                        if (size <= -41) {
                            isAdd = true;
                        }
                    }
                    invalidate();
                    sendEmptyMessageDelayed(START_WAVE, 100);
                    break;
            }
        }
    };

    public MyPathView(Context context) {
        super(context);
    }

    public MyPathView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mPaintCircle = new Paint();
        mPaintCircle.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaintCircle.setColor(Color.argb(0X4f, 0x4d, 0x4d, 0xff));

        mPaintText = new Paint();
        mPaintText.setColor(Color.WHITE);
        mPaintText.setTextSize(50);
        mPaintText.setTextAlign(Paint.Align.CENTER);

        mPaintWave = new Paint();
        mPaintWave.setColor(Color.argb(0xaa, 0xff, 0x7c, 0x00));
        mPaintWave.setStyle(Paint.Style.FILL);
        //不顯示非重疊部分,並且重疊部分顯示自己
        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP);
        mPaintWave.setXfermode(mode);

        mPath = new Path();
        handler.sendEmptyMessageDelayed(START_WAVE, 1000);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);

        mBitmapBubble = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mCanvasBitmap = new Canvas(mBitmapBubble);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPath.reset();
        //canvas.drawColor(Color.argb(0xaa, 0x88, 0x7e, 0x7f));//自定義顏色
        mCanvasBitmap.drawCircle(width / 2, height / 2, 200, mPaintCircle);
        mPath.reset();
        //用path圈出一個矩形,把水波和球的包含進去
        mPath.moveTo(width / 2 + 200, height / 2 + 200 - progress / maxProgress * 400);
        mPath.lineTo(width / 2 + 200, height / 2 + 200);
        mPath.lineTo(0, height / 2 + 200);
        mPath.lineTo(0, height / 2 + 200 - progress / maxProgress * 400);
        /*
        畫一條個模擬流動的波浪
         */
        //當count增大時,重繪會顯示向前流動效果,count的值不能大於width/2-200
        mPath.lineTo(count, height / 2 + 200 -(float) progress / maxProgress * 400);
//        mPath.moveTo(count,200);
        //size的從大到小從小到大變化,重繪時會產生波浪起伏效果
        for (int i = 0; i < 20; i++) {
            /*
            rQuadTo()方法每次都會自動移動到下一位置,參數依次為水平幅度,
            垂直幅度,水平位移,處置位移
            */
            mPath.rQuadTo(20, size, 90, 0);
            mPath.rQuadTo(20, -size, 90, 0);
        }
        mPath.close();
        mCanvasBitmap.drawPath(mPath, mPaintWave);
        canvas.drawBitmap(mBitmapBubble, 0, 0, null);
        //繪制文本,當前進度
        canvas.drawText(progress*100/maxProgress+%,width/2,height/2,mPaintText);

    }
}

主活動調用自定義View:

public class MainActivity extends Activity {
    private int progress;
    private Button mButtonStart;
    private MyPathView myPathView;

    private static final int DOWNLOAD_UPDATE = 0x99;
    //模擬下載
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //處理msg
            switch (msg.what) {
                case DOWNLOAD_UPDATE:
                    progress += 1;
                    //當progress大於maxProgress時,不再調用一下方法
                    if (progress<=myPathView.getMaxProgress()){
                        myPathView.setProgress(progress);//設置新的進度
                        sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 100);//每隔100毫秒發送一次handler
                    }
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mButtonStart = (Button) findViewById(R.id.button_start);
        myPathView = (MyPathView) findViewById(R.id.progress_view_first);

        mButtonStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //向handler發送一個延時空消息,1000毫秒後發送
                mHandler.sendEmptyMessageDelayed(DOWNLOAD_UPDATE, 1000);
            }
        });

    }
}

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved