• 自定义加载等待控件


    MainActivity.java

    package com.loaderman.rollloaderingdemo;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    
    public class MainActivity extends AppCompatActivity {
        private RollSquareView rollSquareView1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            rollSquareView1 = (RollSquareView) findViewById(R.id.rollSquareView1);
        }
        //开始
        public void startRoll(View view) {
            rollSquareView1.setVisibility(View.VISIBLE);
            rollSquareView1.startRoll();
        }
        //停止
        public void stopRoll(View view) {
            rollSquareView1.stopRoll();
            rollSquareView1.setVisibility(View.VISIBLE);
        }
    }
    

     activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.loaderman.rollloaderingdemo.MainActivity">
    
        <com.loaderman.rollloaderingdemo.RollSquareView
            android:id="@+id/rollSquareView1"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@drawable/default_bg"
            android:visibility="invisible"
            app:fix_round_cornor="5"
            app:half_rect_width="15dp"
            app:is_clockwise="false"
            app:line_count="3"
            app:rect_divier_width="8dp"
            app:roll_interpolator="@android:anim/bounce_interpolator"
            app:roll_round_cornor="5"
            app:roll_speed="500"
            app:square_color="#9e40fb"
            app:start_empty_position="3" />
        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:onClick="startRoll"
            android:text="Roll开始滚动" />
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:onClick="stopRoll"
            android:text="Roll结束滚动" />
    </LinearLayout>
    

     default_bg.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners
            android:bottomLeftRadius="10dp"
            android:bottomRightRadius="10dp"
            android:radius="10dp"
            android:topLeftRadius="10dp"
            android:topRightRadius="10dp" />
        <solid android:color="#ff0" />
    </shape>
    

     attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="RollSquareView">
            <attr name="half_rect_width" format="dimension" />
            <attr name="rect_divier_width" format="dimension" />
            <attr name="start_empty_position" format="integer" />
            <attr name="is_clockwise" format="boolean" />
            <attr name="line_count" format="integer"  />
            <attr name="roll_speed" format="integer"  />
            <attr name="square_color" format="color"  />
            <attr name="roll_round_cornor" format="float"  />
            <attr name="fix_round_cornor" format="float"  />
            <attr name="roll_interpolator" format="reference"  />
        </declare-styleable>
    </resources>
    

     RollSquareView.java

    package com.loaderman.rollloaderingdemo;
    
    import android.animation.Animator;
    import android.animation.AnimatorListenerAdapter;
    import android.animation.AnimatorSet;
    import android.animation.PropertyValuesHolder;
    import android.animation.ValueAnimator;
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.Paint;
    import android.graphics.Rect;
    import android.graphics.RectF;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.view.View;
    import android.view.animation.AnimationUtils;
    import android.view.animation.Interpolator;
    
    
    public class RollSquareView extends View {
    
        private FixSquare[] mFixSquares;
        private RollSquare  mRollSquare;
        private float       mHalfSquareWidth;
        private float       mDividerWidth;
        private Paint       mPaint;
        private boolean     mIsClockwise;
        private int         mStartEmptyPosition;
        private int         mCurrEmptyPosition;
        private int         mLineCount;
        /**
         * 方框的圆角半径
         */
        private float       mRollRoundCornor;
        private float       mFixRoundCornor;
    
        private float mRotateDegree;
        private boolean mAllowRoll = false;
        private boolean mIsRolling = false;
        private int     mSpeed     = 250;
        /**
         * 一个方块的动画结束的后是否需要重置(再从startEmpty开始)
         */
        private boolean mIsReset   = false;
        private int          mSquareColor;
        /**
         * 动画插值器的全局变量
         * 默认为线性
         */
        private Interpolator mRollInterpolator;
        private AnimatorSet  mAnimatorSet;
        private Rect         mDirtyRect;
    
        public RollSquareView(Context context) {
            this(context, null);
        }
    
        public RollSquareView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public RollSquareView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initAttrs(context, attrs);
            init();
        }
    
        private void initAttrs(Context context, AttributeSet attrs) {
            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RollSquareView);
            mLineCount = typedArray.getInteger(R.styleable.RollSquareView_line_count, 3);
            mRollRoundCornor = typedArray.getFloat(R.styleable.RollSquareView_roll_round_cornor, 10);
            mFixRoundCornor = typedArray.getFloat(R.styleable.RollSquareView_fix_round_cornor, 10);
            int rollInterpolatorResId = typedArray.getResourceId(R.styleable.RollSquareView_roll_interpolator,
                    android.R.anim.linear_interpolator);
            mRollInterpolator = AnimationUtils.loadInterpolator(context, rollInterpolatorResId);
            int defaultColor = context.getResources().getColor(R.color.default_color);
            mSquareColor = typedArray.getColor(R.styleable.RollSquareView_square_color, defaultColor);
            mSpeed = typedArray.getInteger(R.styleable.RollSquareView_roll_speed, 250);
            if (mLineCount < 2) {
                mLineCount = 2;//至少要四个方块
            }
            mHalfSquareWidth = typedArray.getDimension(R.styleable.RollSquareView_half_rect_width, 30);
            mDividerWidth = typedArray.getDimension(R.styleable.RollSquareView_rect_divier_width, 10);
            mIsClockwise = typedArray.getBoolean(R.styleable.RollSquareView_is_clockwise, true);
            mStartEmptyPosition = typedArray.getInteger(R.styleable.RollSquareView_start_empty_position, 0);
            if (isInsideTheRect(mStartEmptyPosition, mLineCount)) {
                mStartEmptyPosition = 0;
            }
            mCurrEmptyPosition = mStartEmptyPosition;
            typedArray.recycle();
        }
    
        private boolean isInsideTheRect(int pos, int lineCount) {
            if (pos < lineCount) {//是否第一行
                return false;
            } else if (pos > (lineCount * lineCount - 1 - lineCount)) {//是否最后一行
                return false;
            } else if ((pos + 1) % lineCount == 0) {//是否右边
                return false;
            } else if (pos % lineCount == 0) {//是否左边
                return false;
            }
            return true;
        }
    
        private void init() {
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setColor(mSquareColor);
            initSquares(mStartEmptyPosition);
        }
    
        private void initSquares(int startEmptyPosition) {
            //创建mLineCount * mLineCount个方块
            mFixSquares = new FixSquare[mLineCount * mLineCount];
            for (int i = 0; i < mFixSquares.length; i++) {
                mFixSquares[i] = new FixSquare();
                mFixSquares[i].index = i;
                mFixSquares[i].isShow = startEmptyPosition == i ? false : true;
                mFixSquares[i].rectF = new RectF();
            }
            //外圈链接起来
            linkTheOuterSquare(mFixSquares, mIsClockwise);
            //创建1个滚动方块
            mRollSquare = new RollSquare();
            mRollSquare.rectF = new RectF();
            mRollSquare.isShow = false;
        }
    
        private void linkTheOuterSquare(FixSquare[] fixSquares, boolean isClockwise) {
            int lineCount = (int) Math.sqrt(fixSquares.length);
            //连接第一行
            for (int i = 0; i < lineCount; i++) {
                if (i % lineCount == 0) {//位于最左边
                    fixSquares[i].next = isClockwise ? fixSquares[i + lineCount] : fixSquares[i + 1];
                } else if ((i + 1) % lineCount == 0) {//位于最右边
                    fixSquares[i].next = isClockwise ? fixSquares[i - 1] : fixSquares[i + lineCount];
                } else {//中间
                    fixSquares[i].next = isClockwise ? fixSquares[i - 1] : fixSquares[i + 1];
                }
            }
            //连接最后一行
            for (int i = (lineCount - 1) * lineCount; i < lineCount * lineCount; i++) {
                if (i % lineCount == 0) {//位于最左边
                    fixSquares[i].next = isClockwise ? fixSquares[i + 1] : fixSquares[i - lineCount];
                } else if ((i + 1) % lineCount == 0) {//位于最右边
                    fixSquares[i].next = isClockwise ? fixSquares[i - lineCount] : fixSquares[i - 1];
                } else {//中间
                    fixSquares[i].next = isClockwise ? fixSquares[i + 1] : fixSquares[i - 1];
                }
            }
            //连接左边
            for (int i = 1 * lineCount; i <= (lineCount - 1) * lineCount; i += lineCount) {
                if (i == (lineCount - 1) * lineCount) {//如果是左下角的一个
                    fixSquares[i].next = isClockwise ? fixSquares[i + 1] : fixSquares[i - lineCount];
                    continue;
                }
                fixSquares[i].next = isClockwise ? fixSquares[i + lineCount] : fixSquares[i - lineCount];
            }
            //连接右边
            for (int i = 2 * lineCount - 1; i <= lineCount * lineCount - 1; i += lineCount) {
                if (i == lineCount * lineCount - 1) {//如果是右下角的一个
                    fixSquares[i].next = isClockwise ? fixSquares[i - lineCount] : fixSquares[i - 1];
                    continue;
                }
                fixSquares[i].next = isClockwise ? fixSquares[i - lineCount] : fixSquares[i + lineCount];
            }
        }
    
        //    RectF testRectF;
        //    public void testRectInvalidate() {
        //        testRectF = new RectF(mDirtyRect);
        //    }
    
        private class FixSquare {
            RectF     rectF;
            int       index;
            boolean   isShow;
            FixSquare next;
        }
    
        private class RollSquare {
            RectF   rectF;
            int     index;
            boolean isShow;
            /**
             * 旋转中心坐标
             */
            float   cx;
            float   cy;
        }
    
        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            int measuredWidth = getMeasuredWidth();
            int measuredHeight = getMeasuredHeight();
            int cx = measuredWidth / 2;
            int cy = measuredHeight / 2;
            fixFixSquarePosition(mFixSquares, cx, cy, mDividerWidth, mHalfSquareWidth);
            fixRollSquarePosition(mFixSquares, mRollSquare, mStartEmptyPosition, mIsClockwise);
            mDirtyRect = getDirtyRect(mFixSquares[0].rectF, mFixSquares[mFixSquares.length - 1].rectF);
        }
    
        private Rect getDirtyRect(RectF leftTopRectF, RectF rightBottomRectF) {
            if (leftTopRectF != null && rightBottomRectF != null) {
                float width = leftTopRectF.width();
                float height = leftTopRectF.height();
                float sqrt = (float) Math.sqrt(width * width + height * height);
                float extra = sqrt - width;
                Rect dirtyRectF = new Rect((int) (leftTopRectF.left - extra),
                        (int) (leftTopRectF.top - extra),
                        (int) (rightBottomRectF.right + extra),
                        (int) (rightBottomRectF.bottom + extra));
                return dirtyRectF;
            }
            return null;
        }
    
        private void fixRollSquarePosition(FixSquare[] fixSquares,
                                           RollSquare rollSquare, int startEmptyPosition, boolean isClockwise) {
            FixSquare fixSquare = fixSquares[startEmptyPosition];
            rollSquare.rectF.set(fixSquare.next.rectF);
        }
    
        /**
         * 固定这些图形的rect位置
         * @param fixSquares
         * @param cx
         * @param cy
         * @param dividerWidth
         * @param halfSquareWidth
         */
        private void fixFixSquarePosition(FixSquare[] fixSquares, int cx, int cy, float dividerWidth, float halfSquareWidth) {
            //确定第一个rect的位置
            float squareWidth = halfSquareWidth * 2;
            int lineCount = (int) Math.sqrt(fixSquares.length);
            float firstRectLeft = 0;
            float firstRectTop = 0;
            if (lineCount % 2 == 0) {//偶数
                int squareCountInAline = lineCount / 2;
                int diviCountInAline = squareCountInAline - 1;
                float firstRectLeftTopFromCenter = squareCountInAline * squareWidth
                        + diviCountInAline * dividerWidth
                        + dividerWidth / 2;
                firstRectLeft = cx - firstRectLeftTopFromCenter;
                firstRectTop = cy - firstRectLeftTopFromCenter;
            } else {//奇数
                int squareCountInAline = lineCount / 2;
                int diviCountInAline = squareCountInAline;
                float firstRectLeftTopFromCenter = squareCountInAline * squareWidth
                        + diviCountInAline * dividerWidth
                        + halfSquareWidth;
                firstRectLeft = cx - firstRectLeftTopFromCenter;
                firstRectTop = cy - firstRectLeftTopFromCenter;
            }
            for (int i = 0; i < lineCount; i++) {//行
                for (int j = 0; j < lineCount; j++) {//列
                    if (i == 0) {
                        if (j == 0) {
                            fixSquares[0].rectF.set(firstRectLeft, firstRectTop,
                                    firstRectLeft + squareWidth, firstRectTop + squareWidth);
                        } else {
                            int currIndex = i * lineCount + j;
                            fixSquares[currIndex].rectF.set(fixSquares[currIndex - 1].rectF);
                            fixSquares[currIndex].rectF.offset(dividerWidth + squareWidth, 0);
                        }
                    } else {
                        //                Log.i(TAG, "fixFixSquarePosition: i:" + i + " j:" + j + " i*lineCount + j="+(i*lineCount + j));
                        //i * lineCount + j ==> currentIndex
                        int currIndex = i * lineCount + j;
                        fixSquares[currIndex].rectF.set(fixSquares[currIndex - lineCount].rectF);
                        fixSquares[currIndex].rectF.offset(0, dividerWidth + squareWidth);
                    }
                }
            }
        }
    
        public void startRoll() {
            if (mIsRolling || getVisibility() != View.VISIBLE || getWindowVisibility() != VISIBLE) {
                return;
            }
            mIsRolling = true;
            mAllowRoll = true;
            FixSquare currEmptyFixSquare = mFixSquares[mCurrEmptyPosition];
            FixSquare rollSquare = currEmptyFixSquare.next;
            mAnimatorSet = new AnimatorSet();
            ValueAnimator translateConrtroller = createTranslateValueAnimator(currEmptyFixSquare,
                    rollSquare);
            ValueAnimator rollConrtroller = createRollValueAnimator();
            mAnimatorSet.setInterpolator(mRollInterpolator);
            mAnimatorSet.playTogether(translateConrtroller, rollConrtroller);
            mAnimatorSet.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    updateRollSquare();
                    //让空square的next隐藏,现在FixSquares中那就是有两个隐藏了
                    mFixSquares[mCurrEmptyPosition].next.isShow = false;
                    //然后滚动的suqare需要显示出来
                    mRollSquare.isShow = true;
                }
    
                @Override
                public void onAnimationEnd(Animator animation) {
                    mIsRolling = false;
                    mFixSquares[mCurrEmptyPosition].isShow = true;
                    mCurrEmptyPosition = mFixSquares[mCurrEmptyPosition].next.index;
                    //然后滚动的suqare隐藏
                    mRollSquare.isShow = false;
                    if (mAllowRoll) {
                        startRoll();
                    }
                    if (mIsReset) {
                        mCurrEmptyPosition = mStartEmptyPosition;
                        //重置所有的
                        for (int i = 0; i < mFixSquares.length; i++) {
                            mFixSquares[i].isShow = true;
                        }
                        mFixSquares[mCurrEmptyPosition].isShow = false;
                        updateRollSquare();
                        if (!isHardwareAccelerated()) {
                            invalidate(mDirtyRect);
                        } else {
                            invalidate();
                        }
                        startRoll();
                        mIsReset = false;
                    }
                }
            });
            mAnimatorSet.start();
        }
    
        private void updateRollSquare() {
            mRollSquare.rectF.set(mFixSquares[mCurrEmptyPosition].next.rectF);
            mRollSquare.index = mFixSquares[mCurrEmptyPosition].next.index;
            setRollSquareRotateCenter(mRollSquare, mIsClockwise);
        }
    
        public void stopRoll() {
            mAllowRoll = false;
        }
    
        public void resetRoll() {
            stopRoll();
            mIsReset = true;
        }
    
        private void setRollSquareRotateCenter(RollSquare rollSquare, boolean isClockwise) {
            if (rollSquare.index == 0) {//左上角
                rollSquare.cx = rollSquare.rectF.right;
                rollSquare.cy = rollSquare.rectF.bottom;
            } else if (rollSquare.index == mLineCount * mLineCount - 1) {//右下角
                rollSquare.cx = rollSquare.rectF.left;
                rollSquare.cy = rollSquare.rectF.top;
            } else if (rollSquare.index == mLineCount * (mLineCount - 1)) {//左下角
                rollSquare.cx = rollSquare.rectF.right;
                rollSquare.cy = rollSquare.rectF.top;
            } else if (rollSquare.index == mLineCount - 1) {//右上角
                rollSquare.cx = rollSquare.rectF.left;
                rollSquare.cy = rollSquare.rectF.bottom;
            }
            //以下和顺不顺时针有关,其中判断条件还包含了角落的,但是无关紧要,上边的判断已经过滤掉角落的了
            //走到下面的判断的都不可能是角落的index
            else if (rollSquare.index % mLineCount == 0) {//左边
                rollSquare.cx = rollSquare.rectF.right;
                rollSquare.cy = isClockwise ? rollSquare.rectF.top : rollSquare.rectF.bottom;
            } else if (rollSquare.index < mLineCount) {//上边
                rollSquare.cx = isClockwise ? rollSquare.rectF.right : rollSquare.rectF.left;
                rollSquare.cy = rollSquare.rectF.bottom;
            } else if ((rollSquare.index + 1) % mLineCount == 0) {//右边
                rollSquare.cx = rollSquare.rectF.left;
                rollSquare.cy = isClockwise ? rollSquare.rectF.bottom : rollSquare.rectF.top;
            } else if (rollSquare.index > (mLineCount - 1) * mLineCount) {//下边
                rollSquare.cx = isClockwise ? rollSquare.rectF.left : rollSquare.rectF.right;
                rollSquare.cy = rollSquare.rectF.top;
            }
        }
    
        private ValueAnimator createRollValueAnimator() {
            ValueAnimator rollAnim = ValueAnimator.ofFloat(0, 90).setDuration(mSpeed);
            //        rollAnim.setInterpolator(mRollInterpolator);
            rollAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    Object animatedValue = animation.getAnimatedValue();
                    mRotateDegree = (float) animatedValue;
                    if (!isHardwareAccelerated()) {
                        invalidate(mDirtyRect);
                    } else {
                        invalidate();
                    }
                }
            });
            return rollAnim;
        }
    
        private ValueAnimator createTranslateValueAnimator(FixSquare currEmptyFixSquare,
                                                           FixSquare rollSquare) {
            float startAnimValue = 0;
            float endAnimValue = 0;
            PropertyValuesHolder left = null;
            PropertyValuesHolder top = null;
            ValueAnimator valueAnimator = new ValueAnimator().setDuration(mSpeed);
            //        valueAnimator.setInterpolator(mRollInterpolator);
            if (isNextRollLeftOrRight(currEmptyFixSquare, rollSquare)) {
                if (mIsClockwise && currEmptyFixSquare.index > rollSquare.index//顺时针且在第一行
                        || !mIsClockwise && currEmptyFixSquare.index > rollSquare.index) {//逆时针且在最后一行
                    //向右滚
                    startAnimValue = rollSquare.rectF.left;
                    endAnimValue = rollSquare.rectF.left + mDividerWidth;
                } else if (mIsClockwise && currEmptyFixSquare.index < rollSquare.index//顺时针且在最后一行
                        || !mIsClockwise && currEmptyFixSquare.index < rollSquare.index) {//逆时针且在第一行
                    //向左滚
                    startAnimValue = rollSquare.rectF.left;
                    endAnimValue = rollSquare.rectF.left - mDividerWidth;
                }
                left = PropertyValuesHolder.ofFloat("left", startAnimValue, endAnimValue);
                valueAnimator.setValues(left);
            } else {
                if (mIsClockwise && currEmptyFixSquare.index < rollSquare.index//顺时针且在最左列
                        || !mIsClockwise && currEmptyFixSquare.index < rollSquare.index) {//逆时针且在最右列
                    //向上滚
                    startAnimValue = rollSquare.rectF.top;
                    endAnimValue = rollSquare.rectF.top - mDividerWidth;
                } else if (mIsClockwise && currEmptyFixSquare.index > rollSquare.index//顺时针且在最右列
                        || !mIsClockwise && currEmptyFixSquare.index > rollSquare.index) {//逆时针且在最左列
                    //向下滚
                    startAnimValue = rollSquare.rectF.top;
                    endAnimValue = rollSquare.rectF.top + mDividerWidth;
                }
                top = PropertyValuesHolder.ofFloat("top", startAnimValue, endAnimValue);
                valueAnimator.setValues(top);
            }
            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    Object left = animation.getAnimatedValue("left");
                    Object top = animation.getAnimatedValue("top");
                    if (left != null) {
                        mRollSquare.rectF.offsetTo((Float) left, mRollSquare.rectF.top);
                    }
                    if (top != null) {
                        mRollSquare.rectF.offsetTo(mRollSquare.rectF.left, (Float) top);
                    }
                    setRollSquareRotateCenter(mRollSquare, mIsClockwise);
                    if (!isHardwareAccelerated()) {
                        invalidate(mDirtyRect);
                    } else {
                        invalidate();
                    }
                }
            });
            return valueAnimator;
        }
    
        /**
         * 如果不是左右运动那就是上下运动
         * @param currEmptyFixSquare
         * @param rollSquare
         * @return
         */
        private boolean isNextRollLeftOrRight(FixSquare currEmptyFixSquare, FixSquare rollSquare) {
            if (currEmptyFixSquare.rectF.left - rollSquare.rectF.left == 0) {
                return false;
            } else {
                return true;
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            //for test the rect invalidate
            //        if (testRectF != null) {
            //            mPaint.setColor(Color.RED);
            //            canvas.drawCircle(testRectF.centerX(),testRectF.centerY(),testRectF.width(),mPaint);
            //            mPaint.setColor(mSquareColor);
            //        }
            //for test the rect invalidate
    
            for (int i = 0; i < mFixSquares.length; i++) {
                if (mFixSquares[i].isShow) {
                    canvas.drawRoundRect(mFixSquares[i].rectF, mFixRoundCornor, mFixRoundCornor, mPaint);
                }
            }
            if (mRollSquare.isShow) {
                canvas.rotate(mIsClockwise ? mRotateDegree : -mRotateDegree, mRollSquare.cx, mRollSquare.cy);
                canvas.drawRoundRect(mRollSquare.rectF, mRollRoundCornor, mRollRoundCornor, mPaint);
            }
        }
    
        @Override
        protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
            super.onVisibilityChanged(changedView, visibility);
            if (changedView == this && visibility == VISIBLE) {
                startRoll();
            } else if (changedView == this && visibility != VISIBLE) {
                stopRoll();
            }
        }
    
        @Override
        protected void onWindowVisibilityChanged(int visibility) {
            super.onWindowVisibilityChanged(visibility);
            if (visibility == VISIBLE && getVisibility() == VISIBLE) {
                startRoll();
            } else {
                stopRoll();
            }
        }
    }
    

     color.xml

    <color name="default_color">#ff820e</color>
    

     效果图


    学习来源:https://github.com/halohoop/RollSquareView


  • 相关阅读:
    设计一个数据结构,包含两个函数,1.插入一个数字,2.获得中数
    数状数组
    25匹马,每次能5匹一起跑,选出最快的3匹
    禁止ImageCapture自动启动
    SublimeText Videos Notes
    10G个64bit整数,找出中位数
    python初步要点II
    python初步要点
    找出丢失的数字
    nice & renice
  • 原文地址:https://www.cnblogs.com/loaderman/p/6956845.html
Copyright © 2020-2023  润新知