android -------- custom control (4)

The first part introduces a simple case of custom control. This article mainly introduces how to customize some properties of custom control.

 

General steps for using custom attributes in Android:

  1. Define declare styleable, add attr
  2. Get custom properties using TypedArray
  3. Set to View

 

Custom attributes exist in the / value/attr.xml file in the following format

    <resource>  
    <declare-styleable name="Custom attribute name">  
      
    <attr name="Attribute name" format="Attribute types"/>  
      
    ......  
      
    </declare-styleable>  
      
    </resource>  

format property value:

  • reference: reference Resources

  • string: string

  • Color: color

  • boolean: boolean

  • Dimension: dimension value

  • float: floating point

  • Integer: integer

  • fraction: percentage

  • enum: enumeration type

  • flag: bit or operation

 

Code words:

    <?xml version="1.0" encoding="utf-8"?>  
    <resources>  
        <declare-styleable name="CircularAttrsView">  
            <!--Where the circle is drawn-->  
            <attr name="circular_circle_gravity">  
                <flag name="left" value="0"/>  
                <flag name="top" value="1"/>  
                <flag name="center" value="2"/>  
                <flag name="right" value="3"/>  
                <flag name="bottom" value="4"/>  
            </attr>  
      
            <attr name="circular_circle_radius" format="dimension"/><!--Circular radius-->  
            <attr name="circular_circle_progress" format="integer"/><!--Current progress value-->  
            <attr name="circular_progress_color" format="color"/><!--Progress display color-->  
            <attr name="circular_background_color" format="color"/><!--Circular background color-->  
        </declare-styleable>  
    </resources>  

Use attributes

    <com.zhangqie.customcontrol.demo2.CircularAttrsView  
            android:layout_width="300dp"  
            android:layout_height="300dp"  
            android:background="#e4e4e4"  
            zq:circular_background_color="@color/colorAccent"  
            zq:circular_circle_gravity="center"  
            zq:circular_circle_progress="30"  
            zq:circular_progress_color="@color/colorPrimary"  
            zq:circular_circle_radius="50dp"  
            android:layout_margin="5dp"  
            android:padding="10dp"  
            />  

Above zq: this one can go anywhere, only the same

 

The next step is to get the properties and use or set the properties

    public class CircularAttrsView extends View {  
      
      
        /**** 
         * The third parameter in a three parameter constructor is the default Style, 
         * The default Style here refers to the default Style in the Theme used by the current Application or Activity, and it will take effect only when explicitly called, 
         */  
      
        private final static String TAG = CircularAttrsView.class.getName();  
      
        private Paint mPaint;  
        private int backgroundColor = Color.GRAY;  
        private int progressColor = Color.BLUE;  
        private float radius;  
        private float progress;  
      
        private float centerX = 0;  
        private float centerY = 0;  
        public static final int LEFT = 0;  
        public static final int TOP = 1;  
        public static final int CENTER = 2;  
        public static final int RIGHT = 3;  
        public static final int BOTTOM = 4;  
      
        private int gravity = CENTER;  
      
        private RectF rectF;  
      
      
      
        public CircularAttrsView(Context context) {  
            super(context);  
            init();  
        }  
      
        public CircularAttrsView(Context context, AttributeSet attrs) {  
            super(context, attrs);  
            initParams(context,attrs);  
        }  
      
        public CircularAttrsView(Context context, AttributeSet attrs, int defStyleAttr) {  
            super(context, attrs, defStyleAttr);  
            initParams(context,attrs);  
        }  
      
      
        private void init(){  
            mPaint = new Paint();  
            mPaint.setAntiAlias(true);  
        }  
      
        private void initParams(Context context,AttributeSet attrs){  
            mPaint = new Paint();  
            mPaint.setAntiAlias(true);  
            rectF = new RectF();  
            /*** 
             * After compiling each attribute set, it will correspond to a styleable object. Get TypedArray typedArray through the styleable object, 
             * Then get the property value through the key value pair, which is similar to the method of SharedPreference. 
             */  
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularAttrsView);  
            if (typedArray != null){  
                backgroundColor = typedArray.getColor(R.styleable.CircularAttrsView_circular_background_color,Color.GRAY);  
                progressColor = typedArray.getColor(R.styleable.CircularAttrsView_circular_progress_color,Color.BLUE);  
                radius = typedArray.getDimension(R.styleable.CircularAttrsView_circular_circle_radius,0);  
                progress = typedArray.getInt(R.styleable.CircularAttrsView_circular_circle_progress,0);  
                gravity = typedArray.getInt(R.styleable.CircularAttrsView_circular_circle_gravity,CENTER);  
                Log.e(TAG,backgroundColor+"--"+progressColor+"--"+radius+"--"+progress+"--"+gravity);  
                typedArray.recycle();  
            }  
        }  
      
        /**** 
         * The Measure measure process calculates the size of the view 
         * 
         * @param widthMeasureSpec 
         * @param heightMeasureSpec 
         */  
        @Override  
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
      
            //Extract the mode (one of three modes) according to the measurement value (format) provided  
            //MeasureSpec has three modes: unspecified, efficient and at? Most,  
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);  //Take out the measurement mode of width  
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);//Get the size of the View (the exact value of the width)  
      
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);  
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);  
      
            Log.i(TAG,"onMeasure---widthMode--->"+widthMode);  
            switch (widthMode){  
                case MeasureSpec.EXACTLY:  
      
                    break;  
                case MeasureSpec.AT_MOST:  
      
                    break;  
                case MeasureSpec.UNSPECIFIED:  
      
                  break;  
            }  
            Log.i(TAG,"onMeasure--widthSize--->"+ widthSize);  
            Log.i(TAG,"onMeasure--heightMode-->"+ heightMode);  
            Log.i(TAG,"onMeasure--heightSize-->"+heightSize);  
      
            int width = getWidth();  
            int height = getHeight();  
            Log.e(TAG, "onDraw---->" + width + "*" + height);  
      
            centerX = width / 2;  
            centerY = width / 2;  
            switch (gravity){  
                case LEFT:  
                    centerX = radius + getPaddingLeft();  
                    break;  
                case TOP:  
                    centerY = radius + getPaddingTop();  
                    break;  
                case CENTER:  
                    break;  
                case RIGHT:  
                    centerX = width - radius - getPaddingRight();  
                    break;  
                case BOTTOM:  
                    centerY = height - radius - getPaddingBottom();  
                    break;  
            }  
      
            float left = centerX - radius;  
            float top = centerY - radius;  
            float right = centerX + radius;  
            float bottom = centerY + radius;  
            rectF.set(left,top,right,bottom);  
        }  
      
      
        /*** 
         * Determines the size of the View (this function is called when the View size changes. ) 
         * 
         * Width, height, previous width, previous height. 
         * Just focus on width (w) and height (h). These two parameters are the final size of View. 
         * @param w 
         * @param h 
         * @param oldw 
         * @param oldh 
         */  
        @Override  
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
            super.onSizeChanged(w, h, oldw, oldh);  
            Log.i(TAG,"onSizeChanged");  
        }  
      
        /**** 
         * The Layout layout process is used to set the position of the view in the screen. onLayout is generally only used in the custom ViewGroup 
         * 
         * The function to determine the layout is onLayout, which is used to determine the location of the child View. It will be used in the custom ViewGroup. It calls the layout function of the child View. 
         * 
         * @param changed 
         * @param left 
         * @param top 
         * @param right 
         * @param bottom 
         */  
        @Override  
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {  
            super.onLayout(changed, left, top, right, bottom);  
            Log.i(TAG,"onLayout");  
        }  
      
      
        /*** 
         * The drawing drawing process is mainly used to display the view on the screen by using the parameters obtained in the first two steps, and the whole drawing work is completed here 
         * @param canvas 
         */  
        @Override  
        protected void onDraw(Canvas canvas) {  
            super.onDraw(canvas);  
            mPaint.setColor(backgroundColor);  
            // FILL, STROKE, FILL and STROKE  
            mPaint.setStyle(Paint.Style.FILL_AND_STROKE);  
      
      
            canvas.drawCircle(centerX,centerY,radius,mPaint);//Circle drawing  
            mPaint.setColor(progressColor);  
      
            double percent = progress * 1.0 / 100;  
            int angle = (int)(percent * 360);  
            //Draw an arc according to the progress  
            canvas.drawArc(rectF,270,angle,true,mPaint);  
        }  
    }  

Renderings: (for the center, you can set the display position through ZQ: Circular? Circle? Gravity = "center")

 

 

 

 

Source address: https://github.com/DickyQie/android-custom-control

Tags: Android Attribute xml encoding

Posted on Wed, 25 Mar 2020 08:00:01 -0700 by aneesme