LinearColorBar, a custom control under Setting

Source: Internet
Author: User

Version: 1.0 Date: 2014.3.21 copyright:©Please refer to the source document for reprinted by kince

Many custom controls are used in the Setting application, such as the traffic display power display.
Bucket display
First, we will introduce the LinearColorBar displayed in the bucket. We can see that it is inherited from LinearLayout by name. Analyze the effect and show the space used on the left side of the control, and all available space on the right side. The categories shown above are RAM. Of course, the most important thing is the effect of the ring. Let's take a look at the implementation code of LinearColorBar:

/****/package com.example.settingscustomviewdemo.widget;import android.content.Context;import android.graphics.Canvas;import android.graphics.LinearGradient;import android.graphics.Paint;import android.graphics.Path;import android.graphics.Rect;import android.graphics.Shader;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.widget.LinearLayout;public class LinearColorBar extends LinearLayout {        static final int LEFT_COLOR = 0xff0099cc;    static final int MIDDLE_COLOR = 0xff0099cc;    static final int RIGHT_COLOR = 0xff888888;       private float mRedRatio;    private float mYellowRatio;    private float mGreenRatio;    private boolean mShowingGreen;    final Rect mRect = new Rect();    final Paint mPaint = new Paint();    int mLastInterestingLeft, mLastInterestingRight;    int mLineWidth;    final Path mColorPath = new Path();    final Path mEdgePath = new Path();    final Paint mColorGradientPaint = new Paint();    final Paint mEdgeGradientPaint = new Paint();    public LinearColorBar(Context context, AttributeSet attrs) {        super(context, attrs);        setWillNotDraw(false);        mPaint.setStyle(Paint.Style.FILL);        mColorGradientPaint.setStyle(Paint.Style.FILL);        mColorGradientPaint.setAntiAlias(true);        mEdgeGradientPaint.setStyle(Paint.Style.STROKE);        mLineWidth = getResources().getDisplayMetrics().densityDpi >= DisplayMetrics.DENSITY_HIGH                ? 2 : 1;        mEdgeGradientPaint.setStrokeWidth(mLineWidth);        mEdgeGradientPaint.setAntiAlias(true);           }    public void setRatios(float red, float yellow, float green) {        mRedRatio = red;        mYellowRatio = yellow;        mGreenRatio = green;        invalidate();    }    public void setShowingGreen(boolean showingGreen) {        if (mShowingGreen != showingGreen) {            mShowingGreen = showingGreen;            updateIndicator();            invalidate();        }    }    private void updateIndicator() {        int off = getPaddingTop() - getPaddingBottom();        if (off < 0) off = 0;        mRect.top = off;        mRect.bottom = getHeight();        if (mShowingGreen) {            mColorGradientPaint.setShader(new LinearGradient(                    0, 0, 0, off-2, RIGHT_COLOR&0xffffff, RIGHT_COLOR, Shader.TileMode.CLAMP));        } else {            mColorGradientPaint.setShader(new LinearGradient(                    0, 0, 0, off-2, MIDDLE_COLOR&0xffffff, MIDDLE_COLOR, Shader.TileMode.CLAMP));        }        mEdgeGradientPaint.setShader(new LinearGradient(                0, 0, 0, off/2, 0x00a0a0a0, 0xffa0a0a0, Shader.TileMode.CLAMP));    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        updateIndicator();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int width = getWidth();        int left = 0;        int right = left + (int)(width*mRedRatio);        int right2 = right + (int)(width*mYellowRatio);        int right3 = right2 + (int)(width*mGreenRatio);        int indicatorLeft, indicatorRight;        if (mShowingGreen) {            indicatorLeft = right2;            indicatorRight = right3;        } else {            indicatorLeft = right;            indicatorRight = right2;        }        if (mLastInterestingLeft != indicatorLeft || mLastInterestingRight != indicatorRight) {            mColorPath.reset();            mEdgePath.reset();            if (indicatorLeft < indicatorRight) {                final int midTopY = mRect.top;                final int midBottomY = 0;                final int xoff = 2;                mColorPath.moveTo(indicatorLeft, mRect.top);                mColorPath.cubicTo(indicatorLeft, midBottomY,                        -xoff, midTopY,                        -xoff, 0);                mColorPath.lineTo(width+xoff-1, 0);                mColorPath.cubicTo(width+xoff-1, midTopY,                        indicatorRight, midBottomY,                        indicatorRight, mRect.top);                mColorPath.close();                final float lineOffset = mLineWidth+.5f;                mEdgePath.moveTo(-xoff+lineOffset, 0);                mEdgePath.cubicTo(-xoff+lineOffset, midTopY,                        indicatorLeft+lineOffset, midBottomY,                        indicatorLeft+lineOffset, mRect.top);                mEdgePath.moveTo(width+xoff-1-lineOffset, 0);                mEdgePath.cubicTo(width+xoff-1-lineOffset, midTopY,                        indicatorRight-lineOffset, midBottomY,                        indicatorRight-lineOffset, mRect.top);            }            mLastInterestingLeft = indicatorLeft;            mLastInterestingRight = indicatorRight;        }        if (!mEdgePath.isEmpty()) {            canvas.drawPath(mEdgePath, mEdgeGradientPaint);            canvas.drawPath(mColorPath, mColorGradientPaint);        }        if (left < right) {            mRect.left = left;            mRect.right = right;            mPaint.setColor(LEFT_COLOR);            canvas.drawRect(mRect, mPaint);            width -= (right-left);            left = right;        }        right = right2;        if (left < right) {            mRect.left = left;            mRect.right = right;            mPaint.setColor(MIDDLE_COLOR);            canvas.drawRect(mRect, mPaint);            width -= (right-left);            left = right;        }        right = left + width;        if (left < right) {            mRect.left = left;            mRect.right = right;            mPaint.setColor(RIGHT_COLOR);            canvas.drawRect(mRect, mPaint);        }    }}
After reading the source code, let's take a look at its variables. The Paint brush is used to set the stroke style. In addition, Rect and Path are used. The functions of these two classes can be guessed from the literal meaning. Rect is used to draw a rectangle, while Path is used to draw a line, including a straight line, a quadratic curve, and a cubic curve. From the usage of these two classes, it is not difficult to guess their respective functions in the LinaerColorBar. Rect is used to draw the progress bar of the space used, and Path is used to draw the quadratic pattern. Then directly go to the Draw () method and start initializing some variables. These variables will be used later.
Int width = getWidth (); // get the component width int left = 0; // int right = left + (int) (width * mRedRatio ); // int right2 = right + (int) (width * mYellowRatio); // int right3 = right2 + (int) (width * mGreenRatio); // int indicatorLeft, indicatorRight; if (mShowingGreen) {indicatorLeft = right2; indicatorRight = right3;} else {indicatorLeft = right; indicatorRight = right2 ;}
These right values are converted based on the size of the set space. In fact, they are the proportional value of the control width, which can be input during Rect painting. Next, let's look at it,
                    mColorPath.moveTo(indicatorLeft, mRect.top);                    mColorPath.cubicTo(indicatorLeft, midBottomY, -xoff, midTopY,                              -xoff, 0);                    mColorPath.lineTo(width + xoff - 1, 0);                    mColorPath.cubicTo(width + xoff - 1, midTopY, indicatorRight,                              midBottomY, indicatorRight, mRect.top);                    mColorPath.close();
This code is used to draw this arc. First, the moveTo () method moves the Paint brush to this point, and then draws a quadratic curve using the cubicTo method, because the Paint brush is set to Paint. style. FILL, so it looks like a piece of effect, not a straight line.
                    final float lineOffset = mLineWidth + .5f;                    mEdgePath.moveTo(-xoff + lineOffset, 0);                    mEdgePath.cubicTo(-xoff + lineOffset, midTopY, indicatorLeft                              + lineOffset, midBottomY, indicatorLeft + lineOffset,                              mRect.top);                    mEdgePath.moveTo(width + xoff - 1 - lineOffset, 0);                    mEdgePath.cubicTo(width + xoff - 1 - lineOffset, midTopY,                              indicatorRight - lineOffset, midBottomY, indicatorRight                                        - lineOffset, mRect.top);
This code is used to draw edges based on the previous steps,
In this way, the arc effect is achieved. Then there is the rectangle below,
if (left < right) {               mRect.left = left;               mRect.right = right;               mPaint.setColor(LEFT_COLOR);               canvas.drawRect(mRect, mPaint);               width -= (right - left);               left = right;          }          right = right2;          if (left < right) {               mRect.left = left;               mRect.right = right;               mPaint.setColor(MIDDLE_COLOR);               canvas.drawRect(mRect, mPaint);               width -= (right - left);               left = right;          }          right = left + width;          if (left < right) {               mRect.left = left;               mRect.right = right;               mPaint.setColor(RIGHT_COLOR);               canvas.drawRect(mRect, mPaint);          }
This is relatively simple, just use Rect to draw it directly. Conclusion: This custom control is inherited from the system's original container control LinearLayout. Why do we choose LinearLayout? In fact, it can also be RelativeLayout or container control, you only need to place the three textviews. Next we will draw a graph. Here we combine the usage of Paint, Path, Rect, and Canvas. In fact, custom controls often use these classes, so it is particularly important to master these classes. The last step is the logic. This is also a very important part. For the effect, we may think of the class to implement it. The control and change of the effect will depend on the logic.
Download demo

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.