Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android自定義水平的帶進度的刻度條

Android自定義水平的帶進度的刻度條

編輯:關於Android編程

如何自定義控件?
1.自定義屬性的聲明和獲取;
2.測量onMeasure;
3.布局onLayout(ViewGroup);
4.繪制onDraw;
5.onTouchEvent;
6.onInterceptTouchEvent(ViewGroup);
7.狀態的恢復與保存(與Activity生命周期有關);

自定義繪制的PrograssBar的水平進度條如下 有刻度 刻度在中間顯示
這裡寫圖片描述

下面由代碼實現:在values文件夾下建立attr.xml 放入要繪制進度條所需要的。分別是進度條字體①顏色和②大小,Prograss走過的條的③顏色和④高度,Prograss沒有走過的條的⑤顏色和⑥高度,還有顯示數值和進度條之間有間隔的空間⑦寬度。一共七個參數。




    
    
    
    
    
    
    
    

    
    
        
        
        
        
        
        
        


    

新建包View,並新建類class horizonalPrograssBarWithPrograss,如下:

package com.chase.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;

import com.chase.cn.customprograssbar.R;

/**
 * Created by Chase on 2016/11/29.
 */

public class horizonalPrograssBarWithPrograss extends ProgressBar {

    //這裡聲明默認值
    private static final int DEFAULT_TEXT_SIZE = 10;//sp
    private static final int DEFAULT_TEXT_COLOR = 0xFFC00D1;
    private static final int DEFAULT_COLOR_UNREACH = 0XFFD3D6DA;
    private static final int DEFAULT_HEIGHT_UNREACH = 2;//dp
    private static final int DEFAULT_COLOR_REACH = 0xFFC00D1;
    private static final int DEFAULT_HRIGHT_REACH = 2;//dp
    private static final int DEFAULT_TEXT_OFFSET = 10;//dp

    //編寫我們的值
    private int mTextSize = dp2px(DEFAULT_TEXT_SIZE);
    private int mTextColor = DEFAULT_TEXT_COLOR;
    private int mUnReachColor = DEFAULT_COLOR_UNREACH;
    private int mUnReachHeight = DEFAULT_HEIGHT_UNREACH;
    private int mReachColor = DEFAULT_COLOR_REACH;
    private int mReachHeight = DEFAULT_HRIGHT_REACH;
    private int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);

    private Paint mPaint = new Paint();
    private int mRealWidth; //進度條實際寬度

    //2個參數法
    public horizonalPrograssBarWithPrograss(Context context, AttributeSet attrs) {
        this(context, attrs, 0);//2個參數繼承3個參數的方法
    }

    public horizonalPrograssBarWithPrograss(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        obtainStyledAttrs(attrs);


    }

    //獲取自定義屬性
    private void obtainStyledAttrs(AttributeSet attrs) {
        TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.horizonalPrograssBarWithPrograss);

        mTextSize = (int) ta.getDimension(R.styleable.horizonalPrograssBarWithPrograss_text_size, mTextSize);
        mTextColor = ta.getColor(R.styleable.horizonalPrograssBarWithPrograss_text_color, mTextColor);
        mTextOffset = (int) ta.getDimension(R.styleable.horizonalPrograssBarWithPrograss_prograss_text_offset, mTextOffset);
        mUnReachColor = ta.getColor(R.styleable.horizonalPrograssBarWithPrograss_prograss_unreach_color, mUnReachColor);
        mUnReachHeight = (int) ta.getDimension(R.styleable.horizonalPrograssBarWithPrograss_prograss_unreach_height, mUnReachHeight);
        mReachColor = ta.getColor(R.styleable.horizonalPrograssBarWithPrograss_prograss_reach_color, mReachColor);
        mReachHeight = (int) ta.getDimension(R.styleable.horizonalPrograssBarWithPrograss_prograss_reach_height, mReachHeight);

        mPaint.setTextSize(mTextSize);
        ta.recycle();
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        int widthMode = MeasureSpec.getMode(widthMeasureSpec);//因為是水平進度條 默認寬度為用戶的輸入 所以不需要判斷
        int widthVal = MeasureSpec.getSize(widthMeasureSpec);

        int height = measureHeight(heightMeasureSpec);

        setMeasuredDimension(widthVal, height);//完成測量
        //實際繪制區域的寬度
        mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    }

    //高度測量的方法
    private int measureHeight(int heightMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);

        if (mode == MeasureSpec.EXACTLY) {//精確值,用戶給的精確值 如200dp marchparent
            result = size;
        } else {//否則寬度 是由文字的距離確定的
            int textHeight = (int) (mPaint.descent() - mPaint.ascent());
            result = getPaddingTop() //上邊距
                    + getPaddingBottom() //下邊距
                    + Math.max(Math.max(mReachHeight, mUnReachHeight), Math.abs(textHeight));//三者最大值
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }

        return result;
    }

    //1個參法
    public horizonalPrograssBarWithPrograss(Context context) {
        this(context, null);//繼承兩個參數的構造方法,當用戶在使用時new的時候用,但是使用時一般是用兩個參數的構造方法的
    }



 /**
     *
     下面是繪制進度條的方法
     * @param canvas
     */
    @Override
    protected synchronized void onDraw(Canvas canvas) {
//        super.onDraw(canvas);
        canvas.save();
        canvas.translate(getPaddingLeft(), getHeight() / 2);//移動畫布到 最左邊 正中間

        //判斷是否需要繪制unReachBar
        boolean noNeedUnReach = false;
        //DrawReachBar如下:

        //拿到文本寬度
        String text = getProgress() + "";
        int textWidth = (int) mPaint.measureText(text);

        float ratio = getProgress() * 1.0f / getMax();
        float prograssX = ratio * mRealWidth;
        if (prograssX + textWidth > mRealWidth) {
            prograssX = mRealWidth - textWidth;//防止進度條到100文本出去
            noNeedUnReach = true;
        }

        float endX = prograssX - mTextOffset / 2;
        if (endX > 0) {
            mPaint.setColor(mReachColor);
            mPaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(0, 0, endX, 0, mPaint);
        }

        //Draw Text
        mPaint.setColor(mTextColor);
        int y = (int) (-(mPaint.descent()+mPaint.ascent())/2);
        canvas.drawText(text,prograssX,y,mPaint);

        //Draw UnReachBar
        if (!noNeedUnReach){
            float start = prograssX + mTextOffset/2 +textWidth;
            mPaint.setColor(mUnReachColor);
            mPaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(start,0,mRealWidth,0,mPaint);
        }

        canvas.restore();
    }

    //轉換方法dp 2 px
    private int dp2px(int dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, getResources().getDisplayMetrics());
    }

    private int sp2px(int spVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                spVal, getResources().getDisplayMetrics());
    }


}

這是進度條的繪制完成了,上面進度條高度的測量,實際比較關鍵的是測量文字的高度,如圖:這裡寫圖片描述

然後現在可以在activity_main.xml中定義並測試:




    

        

        


    

就如上面的,我們可以自定義進度條的屬性,只需要添加這行:(這是在AS中)

xmlns:chase="http://schemas.android.com/apk/res-auto"

Eclipse中應該要這麼寫(跟上ManiFeast中顯示的包名):

xmlns:chase="http://schemas.android.com/apk/com.chase.cn.customprograssbar"

如前面所示,第二個PrograssBar進行進度變化測試,在MainActivity中:用handler進行測試:

package com.chase.cn.customprograssbar;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;

import com.chase.view.horizonalPrograssBarWithPrograss;


public class MainActivity extends AppCompatActivity {

    private horizonalPrograssBarWithPrograss mPrograss;

    private static final int MSG_UPDATE = 0x111;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            int prograss = mPrograss.getProgress();
            mPrograss.setProgress(++prograss);
            if (prograss>=100){
                handler.removeMessages(MSG_UPDATE);
            }else {
                handler.sendEmptyMessageDelayed(MSG_UPDATE,100);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mPrograss = (horizonalPrograssBarWithPrograss) findViewById(R.id.prograss2);
        handler.sendEmptyMessage(MSG_UPDATE);
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved