Reprinted please indicate the source: http://blog.csdn.net/lmj623565791/article/details/24529807
Today, I have nothing to do with eoe. I saw someone asking for help to make the following effect. I think the following guy told me to use 12 pictures. This Nima's troubles against heaven, after taking a closer look, I felt that there was a problem with the custom control wood, so I took some time to write one.
Now, go to the topic and continue with our custom View.
1. Identify the required attributes, including the color of two small blocks, the image in the middle, the gap size, and the number of blocks. After analysis, write attr. xml.
2. obtain these attributes in the constructor:
/* The color of the first lap */private int mFirstColor;/* the color of the second lap */private int mSecondColor; /* ** circle width */private int mCircleWidth;/* Paint Brush */private Paint mPaint;/* current progress */private int mCurrentCount = 3; /*** intermediate image */private Bitmap mImage;/*** gap between blocks */private int mSplitSize;/*** Number */private int mCount; private Rect mRect; public CustomVolumControlBar (Context context, AttributeSet attrs) {this (context, attrs, 0);} public CustomVolumControlBar (Context context) {this (context, null );} /*** perform necessary initialization to obtain some custom values ** @ param context * @ param attrs * @ param defStyle */public CustomVolumControlBar (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); TypedArray a = context. getTheme (). obtainStyledAttributes (attrs, R. styleable. customVolumControlBar, defStyle, 0); int n =. getIndexCount (); for (int I = 0; I <n; I ++) {int attr =. getIndex (I); switch (attr) {case R. styleable. customVolumControlBar_firstColor: mFirstColor =. getColor (attr, Color. GREEN); break; case R. styleable. customVolumControlBar_secondColor: mSecondColor =. getColor (attr, Color. CYAN); break; case R. styleable. customVolumControlBar_bg: mImage = BitmapFactory. decodeResource (getResources (),. getResourceId (attr, 0); break; case R. styleable. customVolumControlBar_circleWidth: mCircleWidth =. getDimensionPixelSize (attr, (int) TypedValue. applyDimension (TypedValue. COMPLEX_UNIT_PX, 20, getResources (). getDisplayMetrics (); break; case R. styleable. customVolumControlBar_dotCount: mCount =. getInt (attr, 20); // The default value is 20 break; case R. styleable. customVolumControlBar_splitSize: mSplitSize =. getInt (attr, 20); break;}. recycle (); mPaint = new Paint (); mRect = new Rect ();}
3. Override onDraw
@ Overrideprotected void onDraw (Canvas canvas) {mPaint. setAntiAlias (true); // eliminate the Sawtooth mPaint. setStrokeWidth (mCircleWidth); // set the width of the ring mPaint. setStrokeCap (Paint. cap. ROUND); // defines the power-off shape of a line segment as the Circle head mPaint. setAntiAlias (true); // eliminate the Sawtooth mPaint. setStyle (Paint. style. STROKE); // set the hollow int center = getWidth ()/2; // obtain the x coordinate of the center int radius = center-mCircleWidth/2; // radius/** block to draw */drawOval (canvas, center, radius ); /*** calculate the inner tangent square position */int relRadius = radius-mCircleWidth/2; // obtain the inner circle radius. *** the distance from the inner Cut Square to the top is mCircleWidth + relRadius-√ 2/2 */mRect. left = (int) (relRadius-Math. sqrt (2) * 1.0f/2 * relRadius) + mCircleWidth;/*** distance from the left side of the intangent square = mCircleWidth + relRadius-√ 2/2 */mRect. top = (int) (relRadius-Math. sqrt (2) * 1.0f/2 * relRadius) + mCircleWidth; mRect. bottom = (int) (mRect. left + Math. sqrt (2) * relRadius); mRect. right = (int) (mRect. left + Math. sqrt (2) * relRadius);/*** if the image is small, place it in the center of the Image Based on the image size */if (mImage. getWidth () <Math. sqrt (2) * relRadius) {mRect. left = (int) (mRect. left + Math. sqrt (2) * relRadius * 1.0f/2-mImage. getWidth () * 1.0f/2); mRect. top = (int) (mRect. top + Math. sqrt (2) * relRadius * 1.0f/2-mImage. getHeight () * 1.0f/2); mRect. right = (int) (mRect. left + mImage. getWidth (); mRect. bottom = (int) (mRect. top + mImage. getHeight ();} // draw canvas. drawBitmap (mImage, null, mRect, mPaint );} /*** draw each small block based on parameters ** @ param canvas * @ param center * @ param radius */private void drawOval (Canvas canvas, int center, int radius) {/*** calculate the proportion of each block based on the number and gap required * 360 */float itemSize = (360 * 1.0f-mCount * mSplitSize)/mCount; rectF oval = new RectF (center-radius, center-radius, center + radius, center + radius); // defines the boundary between the shape and size of an arc mPaint. setColor (mFirstColor); // set the color of the ring for (int I = 0; I <mCount; I ++) {canvas. drawArc (oval, I * (itemSize + mSplitSize), itemSize, false, mPaint); // draw an Arc Based on the Progress} mPaint. setColor (mSecondColor); // set the color of the ring for (int I = 0; I <mCurrentCount; I ++) {canvas. drawArc (oval, I * (itemSize + mSplitSize), itemSize, false, mPaint); // draw an Arc Based on the Progress }}
Note the following:
Draw block: Calculate the proportion of each block based on the block quantity and gap.
Drawing: when the figure is relatively large, the square size inside the ring is directly used for constraints. When the image is relatively small, it is drawn in the center of the center. In some mathematical operations, I drew a draft on the draft for a while. It was not complicated. I did not post a draft on my own.
4. Add a touch listener:
/*** Current quantity + 1 */public void up () {mCurrentCount ++; postInvalidate () ;}/ *** current quantity-1 */public void down () {mCurrentCount --; postInvalidate ();} private int xDown, xUp; @ Overridepublic boolean onTouchEvent (MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: xDown = (int) event. getY (); break; case MotionEvent. ACTION_UP: xUp = (int) event. getY (); if (xUp> xDown) // decline {down () ;}else {up () ;}break ;}return true ;}
Touch listening is also very easy. Basically, it can be achieved. You can also add a minimum distance acceleration or something.
Finally ,:
Download
Hey, leave a message ~