AndroidカスタムView-菊の進捗バー


このブログを見た後、カスタマイズされたViewの道を触ることができると信じています.このブログでは、カスタマイズされたViewの旅を案内します.くだらないことを言わないで効果図を先に行きます.
実現構想.
1.attrsを作成する.xmlファイル、いくつかの私たちが必要とする属性をカスタマイズして、formatの値に対してみんなはネット上で多くのチュートリアルを検索することができて、私はここで車輪を繰り返しません.
<declare-styleable name="a_zhon">
        <!--      -->
        <attr name="paintBold" format="dimension" />
        <!--      -->
        <attr name="lineLength" format="dimension" />
        <!--    -->
        <attr name="lines" format="integer" />
        <!--    -->
        <attr name="max" format="integer" />
        <!--    -->
        <attr name="progress" format="integer" />
        <!--      -->
        <attr name="backgroundColor" format="reference|color" />
        <!--      -->
        <attr name="beforeColor" format="reference|color" />
        <!--      -->
        <attr name="textColor" format="reference|color" />
  </declare-styleable>
2.プロパティを定義したら、viewにロードする必要があります.これにより、レイアウトでカスタムプロパティを使用すると、次のコードが効果的になります.
    /** *                 attrs.xml          */
    private void loadAttrs(Context context, AttributeSet attrs) {
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.a_zhon);
        paintBold = array.getDimensionPixelSize(R.styleable.a_zhon_paintBold, 10);
        lineLength = array.getDimensionPixelSize(R.styleable.a_zhon_lineLength, 25);
        bgPaintColor = array.getColor(R.styleable.a_zhon_backgroundColor, Color.GRAY);
        beforePaintColor = array.getColor(R.styleable.a_zhon_beforeColor, Color.YELLOW);
        lines = array.getInt(R.styleable.a_zhon_lines, 20);
        max = array.getInt(R.styleable.a_zhon_max, 100);
        progress = array.getInt(R.styleable.a_zhon_progress, 0);
        textColor = array.getColor(R.styleable.a_zhon_textColor, Color.BLACK);
        array.recycle();//TypedArray     
    }
3.レイアウトに占めるViewのサイズを取得するには、onMeasure関数を書き換える必要があります.
@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //  view   
        mWidth = getViewSize(100, widthMeasureSpec);
        //  view   
        mHeight = getViewSize(100, heightMeasureSpec);
    }
MeasureSpecには測定モードやアスペクト情報が含まれていますが、ここではコメントを見てわかると思います
    /** *           * UNSPECIFIED         View     ,  View        * EXACTLY          View       * AT_MOST        View        * * @param defaultSize      * @param measureSpec             * @return   View      */
    private int getViewSize(int defaultSize, int measureSpec) {
        int viewSize = defaultSize;
        //      
        int mode = MeasureSpec.getMode(measureSpec);
        //    
        int size = MeasureSpec.getSize(measureSpec);
        switch (mode) {
            case MeasureSpec.UNSPECIFIED: //        ,        
                viewSize = defaultSize;
                break;
            case MeasureSpec.AT_MOST: //            size
                //         ,        
                viewSize = size;
                break;
            case MeasureSpec.EXACTLY: //        ,        
                viewSize = size;
                break;
        }
        return viewSize;
    }
4.準備はすべてできました(ここではブラシと属性の初期化の詳細を省略して私のソースコードを参照してください)、次はまず下地の菊の絵を描き始めます.
        int x = mWidth / 2;
        int y = mHeight / 2;
        int r = x - 5;
        for (int i = 0; i < lines; i++) {
            //      
            canvas.drawLine(x, y - r, x, y - r + lineLength, bgPaint);
            canvas.rotate(360 / lines, x, y);
        }
5.上位デイジーの描画を続行します.つまり、ロードの進行状況です.
        //           
        int count = (progress * lines) / max;
        //         
        canvas.drawText((progress * 100) / max) + "%", x, y + 5, textPaint);
        //      ,     
        canvas.rotate(360 / lines, x, y);
        for (; count > 0; count--) {
            canvas.drawLine(x, y - r, x, y - r + lineLength, bfPaint);
            canvas.rotate(360 / lines, x, y);
        }
6.図の2番目の菊の進捗を達成するには、内部でアニメーションを定義して使用者に提供する必要があります.ここではValueAnimatorを使って詳しく知りたいのでネットで検索してみると資料もたくさんありますが、ここでは造輪を繰り返しません.
    /** *         * ValueAnimator                  ,                         , *                   ValueAnimator         。 *                             , *                 ValueAnimator,              , *   ValueAnimator                           。 * * @param start     * @param current     * @param duration      */
    public void startAnimation(int start, int current, int duration) {
        ValueAnimator progressAnimator = ValueAnimator.ofInt(start, current);
        progressAnimator.setDuration(duration);
        progressAnimator.setTarget(progress);
        progressAnimator.setInterpolator(new BounceInterpolator());
        progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                progress = (int) animation.getAnimatedValue();
                invalidate();
            }
        });
        progressAnimator.start();
    }
7.同時に対外に二つの方法を提供し、最大進度と現在進度を設定する
    /*       */
    public void setMax(int max) {
        this.max = max;
        invalidate();
    }

    /*      */
    public void setProgress(int progress) {
        this.progress = progress;
        invalidate();
    }
8.基本的にはこのビューは終わりですが、レイアウトで使ってみましょう.
<com.zsy.roate.LoadingView  android:layout_width="80dp" android:layout_height="80dp" a_zhon:backgroundColor="#9f9c9c" a_zhon:beforeColor="#1dcdef" a_zhon:lineLength="10dp" a_zhon:lines="20" a_zhon:max="100" a_zhon:paintBold="3dp" a_zhon:progress="70" <!--                  --> <!--xmlns:a_zhon="http://schemas.android.com/apk/res-auto"-->
最後にDemoがドアを転送します!いいと思うなら押してみろ