Android---自定义View

参考鸿洋大神博客:http://blog.csdn.net/lmj623565791/article/details/24300125

主要内容:
1.自定义view
2.自定义view的属性
3.在view的构造方法中获取自定义的属性
4.重写onMeasure()
5.重写onDraw()
效果:实现进度条效果

Android---自定义View_第1张图片
image.png

1.自定义View属性示例:

在values下新建attrs.xml


    
    
    
    
    
    
    
    
        
        
        
    
    
        
        
        
        
    


布局



    
    
    

两个自定义View,不同效果进阶:
CustomTitleView:

public class CustomTitleView extends View {

   private String mTitleText = "ggaggagh";
   private int mTitleTextColor = Color.BLUE;
   private int mTitleTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics());

   private Rect mBound;
   private Paint mPaint = new Paint();


   public CustomTitleView(Context context) {
       this(context, null);
   }

   public CustomTitleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

       super(context, attrs, defStyleAttr);
       Log.i("hello", "gas");

       //获得自定义样式属性
       TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleView);
       int n = ta.length();
       Log.i("hello", "gggggggg" + n);
       for (int i = 0; i < n; i++) {
           int attr = ta.getIndex(i);
           switch (attr) {
               case R.styleable.CustomTitleView_titleText:
                   //不知道为什么,这个函数就是不好使,运行就闪退
                   mTitleText = ta.getString(attr);
                   break;
               case R.styleable.CustomTitleView_titleTextColor:
                   //默认设置为蓝色
                   mTitleTextColor = ta.getColor(attr, Color.BLUE);
                   break;
               case R.styleable.CustomTitleView_titleTextSize:
                   //默认设置为16sp
                   mTitleTextSize = ta.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 26, getResources().getDisplayMetrics()));
                   break;
           }
       }
       ta.recycle();
       Log.wtf("nihao", mTitleText);
       //获得文本宽高
       mPaint.setTextSize(mTitleTextSize);
       mBound = new Rect();
       mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);

       this.setOnClickListener(new OnClickListener() {
           @Override
           public void onClick(View v) {
               mTitleText = randomText();
               postInvalidate();
           }
       });
   }

   public CustomTitleView(Context context, @Nullable AttributeSet attrs) {
       this(context, attrs, 0);
   }

   private String randomText(){
       Random random = new Random(System.currentTimeMillis());
       Set si = new HashSet();
       while(si.size() < 10){
           int rand = random.nextInt();
           si.add(rand);
       }
       StringBuffer sb = new StringBuffer();
       for(Integer i : si){
           sb.append("" + i);
       }
       return sb.toString();

   }

   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//通过重写onMeasure可以解决wrap_content与padding问题
       int widthMode = MeasureSpec.getMode(widthMeasureSpec);
       int widthSize = MeasureSpec.getSize(widthMeasureSpec);
       int heightMode = MeasureSpec.getMode(heightMeasureSpec);
       int heightSize = MeasureSpec.getSize(heightMeasureSpec);
       int width;
       int height;
       if (widthMode == MeasureSpec.EXACTLY) {
           width = widthSize;
       } else {
           mPaint.setTextSize(mTitleTextSize);
           mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
           float textWidth = mBound.width();
           int desired = (int) (getPaddingLeft() + textWidth + getPaddingRight());
           width = desired;
       }
       if (heightMode == MeasureSpec.EXACTLY) {
           height = heightSize;
       } else {
           mPaint.setTextSize(mTitleTextSize);
           mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
           float textheight = mBound.height();
           int desired = (int) (getPaddingTop() + textheight + getPaddingBottom());
           height = desired;
       }
       setMeasuredDimension(width, height);
   }

   @Override
   protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);
       mPaint.setColor(Color.YELLOW);
       canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
       mPaint.setColor(mTitleTextColor);
       canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);
   }
}

CustomProgressBar


public class CustomProgressBar extends View{

    private int mFirstColor;
    private int mSecondColor;
    private int mCircleWidth;
    private Paint mPaint;
    private int mProgress;
    private int mSpeed;
    private boolean isNext = false;

    public CustomProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomProgressBar);
        int n = a.length();
        for(int i = 0; i < n; i++){
            int attr = a.getIndex(i);
            switch (attr){
                case R.styleable.CustomProgressBar_firstColor:
                    mFirstColor = a.getColor(attr, Color.GREEN);
                    break;
                case R.styleable.CustomProgressBar_secondColor:
                    mSecondColor = a.getColor(attr, Color.RED);
                    break;
                case R.styleable.CustomProgressBar_circleWidth:
                    mCircleWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 140, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomProgressBar_speed:
                    mSpeed = a.getInt(attr, 20);
                    break;
            }
        }
        a.recycle();
        mPaint = new Paint();
        new Thread(){
            @Override
            public void run() {
                while(true){
                    mProgress++;
                    if(mProgress == 360){
                        mProgress = 0;
                        if(!isNext)
                            isNext = true;
                        else
                            isNext = false;
                    }
                    postInvalidate();
                    try{
                        Thread.sleep(mSpeed);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            };
        }.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int center = getWidth() / 2;//获取圆心的x坐标
        int radius = center - mCircleWidth / 2 -60;//半径
        mPaint.setStrokeWidth(100);//设置圆环的宽度
        mPaint.setAntiAlias(true);//消除锯齿
        mPaint.setStyle(Paint.Style.STROKE);//设置空心
        RectF oval = new RectF(center-radius, center-radius, center+radius, center+radius);
        //定义圆弧的形状和大小的界限
        if(!isNext){
            mPaint.setColor(mFirstColor);//设置圆环颜色
            canvas.drawCircle(center, center, radius, mPaint);//画出圆圈
            mPaint.setColor(mSecondColor);//设置圆环颜色
            canvas.drawArc(oval, -90, mProgress, false, mPaint);//根据进度画圆弧
        }else{
            mPaint.setColor(mSecondColor);
            canvas.drawCircle(center, center, radius, mPaint);
            mPaint.setColor(mFirstColor);
            canvas.drawArc(oval, -90, mProgress, false, mPaint);
        }
    }

    public CustomProgressBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomProgressBar(Context context) {
        this(context, null);
    }
}

你可能感兴趣的:(Android---自定义View)