Android custom View realizes QQ sports points lottery turntable and androidview

Source: Internet
Author: User

Android custom View realizes QQ sports points lottery turntable and androidview

Due to occasional attention to QQ sports, it is interesting to see the point drawing interface of QQ sports, so I tried to implement it with a custom View. I originally wanted to use the developer option to View some information about the lower bound, later, we found that the point drawing interface was displayed in WebView, which should be implemented by using js Code on the H5 page. We don't care about it for the time being.

The custom View here is used to inherit the custom View. You can think of Canvas as a Canvas and Paint as a Paint brush. The process of creating a custom View is similar to that of painting with a Paint brush on the Canvas, imagine the Painting Process on the canvas. How much image do you want to draw (corresponding to the onMeasure method of the View)? What kind of image do you want to draw, for example, the circular square (corresponding to the onDraw method of the View), in understanding some basic concepts of the View (location parameters, touch events, slide ), after the knowledge of the Measurement Mode, event distribution mechanism, and drawing process, it is not complicated to customize the View.

No matter how complicated a View is, it can basically be split into small units, such as the following QQ sports points lottery screen, (QQ --> dynamic --> sports --> I --> points)

  

 

Here we only focus on the lottery turntable, because there is no animation effect, you can view it on your mobile phone. The drawing interface looks complex and can be divided into several parts.

1. Outermost ring, with a small circle flashing

2. The interior rounded rectangle

3. An internal rounded corner card (containing an image or instructions)

 

The first step is to inherit the View class. If you need custom properties, you should implement the construction method with three parameters. Here we name the custom View as LotteryView.

public LotteryView(Context context) {        this(context, null);    }    public LotteryView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public LotteryView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context, attrs);    }

Some initialization operations can be performed in the init method, such as the required color value, Paint brush, width and height information. If you have custom attributes, you can also process them in the init method.

Then we can set the width and height of the View. Here we set the View as a square

  

 @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        //super.onMeasure(widthMeasureSpec, heightMeasureSpec);        setMeasuredDimension(mSelfTotalWidth, mSelfTotalWidth);    }

Call the setMeasureDimension method and set both width and height to mSelfTotalWidth. Here, the width and height are limited values, so we do not need to deal with different measurement modes. If other custom views need to support the wrap_content attribute, they must be processed in the onMeasure method.

Step 1: Draw a circle with rounded corners on the outer layer

  

/** Rectangular circle with rounded corners */private void drawOuterRoundCircle (Canvas canvas) {canvas. save (); canvas. clipRect (mOuterCircleWidth + getPaddingLeft (), mOuterCircleWidth + getPaddingTop (), objective-mOuterCircleWidth-getPaddingRight (), objective-mOuterCircleWidth-limit (), Region. op. DIFFERENCE); canvas. drawRoundRect (getPaddingLeft (), getPaddingTop (), mSelfTotalWidth-getPaddingRight (), mSelfTotalWidth-getPaddingBottom (), 18, 18, mOuterCirclePaint); canvas. restore ();}

  

Draw a small circle in the outer ring

Private void Merge (Canvas canvas) {int result = mInvalidateCircleCount % 2; // top int x = 0, y = 0; int sideSize = mSelfTotalWidth-mOuterCircleWidth * 2-getPaddingLeft () -getPaddingRight (); // remove the edge length after the outermost ring for (int I = 0; I <10; I ++) {mSmallCirclePaint. setColor (I % 2 = result? MSmallCircleYellowColor: mSmallCircleBlueColor); x = mOuterCircleWidth + (sideSize-mSmallCircleRadius * 2*9)/9 * I + limit * 2 * I + getPaddingLeft (); y = (mOuterCircleWidth-mSmallCircleRadius * 2)/2 + mSmallCircleRadius + getPaddingTop (); canvas. drawCircle (x, y, mSmallCircleRadius, mSmallCirclePaint);} // bottom for (int I = 0; I <10; I ++) {mSmallCirclePaint. setColor (I % 2 = result? MSmallCircleYellowColor: mSmallCircleBlueColor); x = mOuterCircleWidth + (sideSize-mSmallCircleRadius * 2*9)/9 * I + limit * 2 * I + getPaddingLeft (); y = mSelfTotalWidth-mOuterCircleWidth + (mOuterCircleWidth-mSmallCircleRadius * 2)/2 + mSmallCircleRadius-getPaddingBottom (); canvas. drawCircle (x, y, mSmallCircleRadius, mSmallCirclePaint);} // left for (int I = 0; I <9; I ++) {mSmallCirclePaint. setColor (I % 2 = (result = 0? 1: 0 )? MSmallCircleYellowColor: mSmallCircleBlueColor); x = mOuterCircleWidth/2 + getPaddingLeft (); y = mOuterCircleWidth * 2 + (sideSize-mSmallCircleRadius * 2*9) /9 * I + mSmallCircleRadius * 2 * I + getPaddingTop (); canvas. drawCircle (x, y, mSmallCircleRadius, mSmallCirclePaint);} // right for (int I = 0; I <9; I ++) {mSmallCirclePaint. setColor (I % 2 = result? MSmallCircleYellowColor: mSmallCircleBlueColor); x = mSelfTotalWidth-mOuterCircleWidth/2-getPaddingRight (); y = mOuterCircleWidth * 2 + (sideSize-limit * 2*9) /9 * I + mSmallCircleRadius * 2 * I + getPaddingTop (); canvas. drawCircle (x, y, mSmallCircleRadius, mSmallCirclePaint );}}View Code

  

Step 2: draw an internal rounded rectangle, that is, the background of the area where the card is located

private void drawInnerBackground(Canvas canvas) {        canvas.drawRect(mOuterCircleWidth + getPaddingLeft(), mOuterCircleWidth + getPaddingTop(),                mSelfTotalWidth - mOuterCircleWidth - getPaddingRight(),                mSelfTotalWidth - mOuterCircleWidth - getPaddingBottom(), mInnerPaint);    }

 

Step 3: Draw Internal small cards

private void drawInnerCards(Canvas canvas) {        int left = 0, top = 0, right = 0, bottom = 0;        int spaceNum = 0;        for(int i = 0 ; i < 9 ; i++) {            spaceNum = i % 3 + 1;            left = mOuterCircleWidth + mInnerCardWidth * (i%3) + mInnerCardSpace * spaceNum + getPaddingLeft();            top = mOuterCircleWidth + mInnerCardWidth * (i/3) +mInnerCardSpace * (i/3 + 1) + getPaddingTop();            right = left + mInnerCardWidth;            bottom = top + mInnerCardWidth;            if(!mHadInitial) {                mCardPositionInfoList.add(new Pair(new Pair(left, right), new Pair(top, bottom)));            }            drawInnerRoundCard(canvas, left, top, right, bottom, i);        }        mHadInitial = true;    }

  

After the painting is complete, you can process the Click Event in onTouchEvent. How can we determine that we are clicking the lucky draw area? Here we use the method of comparing the location information,

As follows,

private int getTouchPositionInCardList(int x, int y) {        if(mCardPositionInfoList != null) {            int index = 1;            for (Pair<Pair<Integer, Integer>,Pair<Integer, Integer>> pair : mCardPositionInfoList) {                if(x > pair.first.first && x < pair.first.second && y > pair.second.first && y < pair.second.second) {                    return index;                }                index++;            }        }        return 0;    }

Store the coordinate information (left, top, right, bottom) of each small card in the ArrayList <Pair <Integer, Integer>, Pair <Integer, in Integer >>> mCardPosttionInfoList, the x y coordinate and

The coordinate information saved in the list is compared. If index = 5, it indicates that you click the small card area where the lottery is located.

 

Code hosted in: https://github.com/aquarius520/LotteryView welcome star fork

 

Related Article

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.