Ver código fonte

v1.0.1开发:通过build.gradle选择volley版本

#Suyghur 3 anos atrás
pai
commit
0b3805081e

+ 17 - 15
build.gradle

@@ -1,21 +1,23 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 buildscript {
 
-    ext.USE_ANDROIDX_VOLLEY=true
-    // 混淆开关
-    ext.MINIFY_ENABLE = true
-    // ndk版本
-    ext.NDK_VERSION = '21.3.6528147'
-    // kotlin版本
-    ext.KOTLIN_VERSION = '1.4.20'
-    // compileSdkVersion
-    ext.COMPILE_SDK_VERSION = 30
-    // buildToolsVersion
-    ext.BUILD_TOOLS_VERSION = '30.0.3'
-    // minSdkVersion
-    ext.MIN_SDK_VERSION = 16
-    // targetSdkVersion
-    ext.TARGET_SDK_VERSION = 28
+    ext {
+        USE_ANDROIDX_VOLLEY = true
+        // 混淆开关
+        MINIFY_ENABLE = true
+        // ndk版本
+        NDK_VERSION = '21.4.7075529'
+        // kotlin版本
+        KOTLIN_VERSION = '1.4.20'
+        // compileSdkVersion
+        COMPILE_SDK_VERSION = 30
+        // buildToolsVersion
+        BUILD_TOOLS_VERSION = '30.0.3'
+        // minSdkVersion
+        MIN_SDK_VERSION = 16
+        // targetSdkVersion
+        TARGET_SDK_VERSION = 30
+    }
 
     repositories {
         google()

+ 23 - 10
demo/src/main/java/com/yyxx/support/demo/DemoActivity.kt

@@ -2,17 +2,22 @@ package com.yyxx.support.demo
 
 import android.app.Activity
 import android.graphics.Bitmap
+import android.graphics.Color
 import android.os.Bundle
 import android.view.View
 import android.widget.*
 import cn.yyxx.support.AppUtils
+import cn.yyxx.support.DensityUtils
 import cn.yyxx.support.device.DeviceInfoUtils
 import cn.yyxx.support.hawkeye.LogUtils
+import cn.yyxx.support.hawkeye.OwnDebugUtils
 import cn.yyxx.support.msa.MsaDeviceIdsHandler
+import cn.yyxx.support.ui.scaleprogress.ScaleLoadingView
 import cn.yyxx.support.volley.VolleySingleton
 import cn.yyxx.support.volley.source.Response
 import cn.yyxx.support.volley.source.toolbox.ImageRequest
 import com.tencent.mmkv.MMKV
+import kotlin.system.exitProcess
 
 /**
  * @author #Suyghur.
@@ -27,7 +32,9 @@ class DemoActivity : Activity(), View.OnClickListener {
         Item(3, "显示浮标"),
         Item(4, "隐藏浮标"),
         Item(5, "MMKV测试 encode"),
-        Item(6, "MMKV测试 decode")
+        Item(6, "MMKV测试 decode"),
+        Item(7, "test")
+
     )
 
     private lateinit var textView: TextView
@@ -40,6 +47,7 @@ class DemoActivity : Activity(), View.OnClickListener {
         super.onCreate(savedInstanceState)
         initView()
         initDeviceInfo()
+        LogUtils.d("own ${OwnDebugUtils.isOwnDebug(this, "yyxx_cfg.properties", "yyxx_game", "YYXX_OWN_DEBUG")}")
     }
 
     private fun initView() {
@@ -60,6 +68,11 @@ class DemoActivity : Activity(), View.OnClickListener {
 //        gifView.setGifResource(ResUtils.getResId(this, "test", "drawable"))
 //        layout.addView(gifView)
         imgView = ImageView(this)
+        val viewSize = DensityUtils.dip2px(this, 60f)
+        val divideSize = DensityUtils.dip2px(this, 3f)
+        val count = 6
+        val color = Color.parseColor("#1DB1AD")
+        layout.addView(ScaleLoadingView(this, viewSize, divideSize, count, Color.parseColor("#1DB1AD"), Color.parseColor("#7EB944")))
         layout.addView(imgView)
         val scrollView = ScrollView(this)
         scrollView.addView(layout)
@@ -116,16 +129,16 @@ class DemoActivity : Activity(), View.OnClickListener {
                 4 -> FloatViewServiceManager.getInstance().detach()
 
                 5 -> {
-//                    MMKV.defaultMMKV()!!.encode("test", "yyxx support")
-//                    MMKV.defaultMMKV()!!.encode("test1", "yyxx support1")
-//                    MMKV.defaultMMKV()!!.encode("test2", "yyxx support2")
-//                    MMKV.defaultMMKV()!!.encode("test3", "yyxx support3")
-//                    val text =
-//                        "eFeiSQvEaVfyAmbsKfYpHjK/g3VFQ2lzHaLMv7f2yKXCoka0wGE6zp/4y6REvnpjspBn81Gya+yi3Q3MV3h3csxF0QA2ebKy+ytV3Lmwb5RUx/F5ps01wZ83QkVa2WpxzDG1zBaT6NxnfDXO2oL0J+6d4/E82fbEt0kwvO0KyfU="
+                    MMKV.defaultMMKV()!!.encode("test", "yyxx support")
+                    MMKV.defaultMMKV()!!.encode("test1", "yyxx support1")
+                    MMKV.defaultMMKV()!!.encode("test2", "yyxx support2")
+                    MMKV.defaultMMKV()!!.encode("test3", "yyxx support3")
+                    val text =
+                        "eFeiSQvEaVfyAmbsKfYpHjK/g3VFQ2lzHaLMv7f2yKXCoka0wGE6zp/4y6REvnpjspBn81Gya+yi3Q3MV3h3csxF0QA2ebKy+ytV3Lmwb5RUx/F5ps01wZ83QkVa2WpxzDG1zBaT6NxnfDXO2oL0J+6d4/E82fbEt0kwvO0KyfU="
                 }
                 6 -> {
-//                    sb.append("MMKV decode : ").append(MMKV.defaultMMKV()!!.decodeString("test"))
-//                    textView.text = sb.toString()
+                    sb.append("MMKV decode : ").append(MMKV.defaultMMKV()!!.decodeString("test"))
+                    textView.text = sb.toString()
                     val keys = MMKV.defaultMMKV()!!.allKeys()
                     keys?.apply {
                         for (key in this) {
@@ -150,6 +163,6 @@ class DemoActivity : Activity(), View.OnClickListener {
     override fun onDestroy() {
         super.onDestroy()
         FloatViewServiceManager.getInstance().release()
-
+        exitProcess(0)
     }
 }

+ 0 - 1
demo/src/main/java/com/yyxx/support/demo/DemoApplication.kt

@@ -4,7 +4,6 @@ import android.app.Application
 import android.content.Context
 import cn.yyxx.support.hawkeye.LogUtils
 import cn.yyxx.support.msa.MsaDeviceIdsHandler
-import com.tencent.mmkv.MMKV
 
 /**
  * @author #Suyghur.

+ 2 - 43
demo/src/main/java/com/yyxx/support/demo/FloatViewService.kt

@@ -3,14 +3,9 @@ package com.yyxx.support.demo
 import android.app.Activity
 import android.app.Service
 import android.content.Intent
-import android.graphics.BitmapFactory
 import android.os.Binder
 import android.os.IBinder
-import cn.yyxx.support.ResUtils
 import cn.yyxx.support.hawkeye.LogUtils
-import cn.yyxx.support.ui.floating.FloatItem
-import cn.yyxx.support.ui.floating.FloatLogoMenu
-import cn.yyxx.support.ui.floating.FloatMenuView
 
 /**
  * @author #Suyghur.
@@ -19,13 +14,12 @@ import cn.yyxx.support.ui.floating.FloatMenuView
 class FloatViewService : Service() {
 
     private lateinit var activity: Activity
-    private var floatView: FloatLogoMenu? = null
+    private var floatView: FloatView? = null
 
     override fun onCreate() {
         super.onCreate()
     }
 
-
     fun initFloatView(activity: Activity) {
         this.activity = activity
         LogUtils.d("init")
@@ -33,42 +27,7 @@ class FloatViewService : Service() {
 
     fun show() {
         if (floatView == null) {
-            val features = mutableListOf(
-                FloatItem(
-                    "aaaa", "#1DB1AD",
-                    "#000000", BitmapFactory.decodeResource(activity.resources, ResUtils.getResId(activity, "float_icon", "drawable"))
-                ),
-                FloatItem(
-                    "aaaa", "#1DB1AD",
-                    "#000000", BitmapFactory.decodeResource(activity.resources, ResUtils.getResId(activity, "float_icon", "drawable"))
-                ),
-                FloatItem(
-                    "aaaa", "#1DB1AD",
-                    "#000000", BitmapFactory.decodeResource(activity.resources, ResUtils.getResId(activity, "float_icon", "drawable"))
-                ),
-                FloatItem(
-                    "aaaa", "#1DB1AD",
-                    "#000000", BitmapFactory.decodeResource(activity.resources, ResUtils.getResId(activity, "float_icon", "drawable"))
-                )
-            )
-            floatView = FloatLogoMenu.Builder()
-                .withActivity(activity)
-                .logo(BitmapFactory.decodeResource(activity.resources, ResUtils.getResId(activity, "float_icon", "drawable")))
-                .drawCicleMenuBg(true)
-                .backMenuColor("#FFFFFF")
-                .setBgDrawable(activity.resources.getDrawable(ResUtils.getResId(activity, "yyxx_float_menu_bg", "drawable")))
-                //这个背景色需要和logo的背景色一致
-                .setFloatItems(features)
-                .defaultLocation(FloatLogoMenu.LEFT)
-                .drawRedPointNum(false)
-                .showWithListener(object : FloatMenuView.OnMenuClickListener {
-                    override fun onItemClick(position: Int, title: String?) {
-                    }
-
-                    override fun dismiss() {
-                    }
-
-                })
+            floatView = FloatView(activity)
         }
 
         floatView?.show()

BIN
demo/src/main/res/drawable-xhdpi/test.png


+ 2 - 2
library_support/src/main/java/cn/yyxx/support/JsonUtils.java

@@ -14,7 +14,7 @@ public class JsonUtils {
     }
 
     public static boolean hasJsonKey(JSONObject jsonObject, String key) throws JSONException {
-//        return jsonObject.has(key) && !jsonObject.getString(key).equals("[]")&&!jsonObject.getString(key).equals("{}");
-        return jsonObject.has(key) && !jsonObject.getString(key).equals("[]");
+        return jsonObject.has(key) && !jsonObject.getString(key).equals("[]")&&!jsonObject.getString(key).equals("{}");
+//        return jsonObject.has(key) && !jsonObject.getString(key).equals("[]");
     }
 }

+ 1 - 1
library_support/src/main/java/cn/yyxx/support/hawkeye/OwnDebugUtils.java

@@ -23,7 +23,7 @@ public class OwnDebugUtils {
         }
         //配置文件中关闭时再判断私有目录
         String ownFileName = context.getExternalFilesDir(null).getAbsolutePath() + "/" + OWN_DEBUG_FILE;
-        File file = new File(fileName);
+        File file = new File(ownFileName);
         if (!file.exists()) {
             return false;
         }

+ 1 - 1
library_support/src/main/java/cn/yyxx/support/ui/DragViewLayout.java

@@ -16,7 +16,7 @@ import android.widget.RelativeLayout;
  * @author #Suyghur.
  * Created on 2021/05/12
  */
-public class DragViewLayout extends LinearLayout {
+public class DragViewLayout extends FrameLayout {
 
     //view所在位置
     private int mLastX, mLastY;

+ 0 - 394
library_support/src/main/java/cn/yyxx/support/ui/floating/DotImageView.java

@@ -1,394 +0,0 @@
-/*
- * Copyright (c) 2016, Shanghai YUEWEN Information Technology Co., Ltd.
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- *  Neither the name of Shanghai YUEWEN Information Technology Co., Ltd. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY SHANGHAI YUEWEN INFORMATION TECHNOLOGY CO., LTD. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-package cn.yyxx.support.ui.floating;
-
-import android.animation.Animator;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.Camera;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.animation.LinearInterpolator;
-
-import cn.yyxx.support.DensityUtils;
-
-/**
- * 00%=FF(不透明)    5%=F2    10%=E5    15%=D8    20%=CC    25%=BF    30%=B2    35%=A5    40%=99    45%=8c    50%=7F
- * 55%=72    60%=66    65%=59    70%=4c    75%=3F    80%=33    85%=21    90%=19    95%=0c    100%=00(全透明)
- */
-public class DotImageView extends View {
-    private static final String TAG = DotImageView.class.getSimpleName();
-    public static final int NORMAL = 0;//不隐藏
-    public static final int HIDE_LEFT = 1;//左边隐藏
-    public static final int HIDE_RIGHT = 2;//右边隐藏
-    private Paint mPaint;//用于画anything
-
-    private Paint mPaintBg;//用于画anything
-    private String dotNum = null;//红点数字
-    private float mAlphaValue;//透明度动画值
-    private float mRelateValue = 1f;//旋转动画值
-    private boolean inited = false;//标记透明动画是否执行过,防止因onreseme 切换导致重复执行
-
-
-    private Bitmap mBitmap;//logo
-    private int mLogoBackgroundRadius = 0;//logo的灰色背景圆的半径
-    private int mLogoWhiteRadius = 0;//logo的白色背景的圆的半径
-    private int mRedPointRadiusWithNum = 0;//红点圆半径
-    private int mRedPointRadius = 0;//红点圆半径
-    private int mRedPointOffset = 0;//红点对logo的偏移量,比如左红点就是logo中心的 x - mRedPointOffset
-
-    private boolean isDragging = false;//是否 绘制旋转放大动画,只有 非停靠边缘才绘制
-    private float scaleOffset;//放大偏移值
-    private ValueAnimator mDraggingValueAnimator;//放大、旋转 属性动画
-    private LinearInterpolator mLinearInterpolator = new LinearInterpolator();//通用用加速器
-    public boolean mDrawDarkBg = true;//是否绘制黑色背景,当菜单关闭时,才绘制灰色背景
-    private static final float hideOffset = 0.5f;//往左右隐藏多少宽度的偏移值, 隐藏宽度的0.4
-    private static final float hideOffsetAlpha = 0.5f;//往左右隐藏多少宽度的偏移值, 隐藏宽度的0.4
-    private Camera mCamera;//camera用于执行3D动画
-
-    private boolean mDrawNum = false;//只绘制红点还是红点+白色数字
-
-    private int mStatus = NORMAL;//0 正常,1 左,2右,3 中间方法旋转
-    private int mLastStatus = mStatus;
-    private Matrix mMatrix;
-    private boolean mIsResetPosition;
-
-    private int mBgColor = 0x99000000;
-
-
-    public void setBgColor(int bgColor) {
-        mBgColor = bgColor;
-    }
-
-
-    public void setDrawNum(boolean drawNum) {
-        this.mDrawNum = drawNum;
-    }
-
-    public void setDrawDarkBg(boolean drawDarkBg) {
-        mDrawDarkBg = drawDarkBg;
-        invalidate();
-    }
-
-    public int getStatus() {
-        return mStatus;
-    }
-
-
-    public void setStatus(int status) {
-        this.mStatus = status;
-        isDragging = false;
-        if (this.mStatus != NORMAL) {
-            setDrawNum(mDrawNum);
-            this.mDrawDarkBg = true;
-        }
-        invalidate();
-
-    }
-
-    public void setBitmap(Bitmap bitmap) {
-        mBitmap = bitmap;
-    }
-
-    public DotImageView(Context context, Bitmap bitmap) {
-        super(context);
-        this.mBitmap = bitmap;
-        init(context);
-    }
-
-
-//    public DotImageView(Context context) {
-//        super(context);
-//        init();
-//    }
-//
-//    public DotImageView(Context context, AttributeSet attrs) {
-//        super(context, attrs);
-//        init();
-//    }
-//
-//    public DotImageView(Context context, AttributeSet attrs, int defStyleAttr) {
-//        super(context, attrs, defStyleAttr);
-//        init();
-//    }
-
-    private void init(Context context) {
-
-
-        mPaint = new Paint();
-        mPaint.setAntiAlias(true);
-        mPaint.setTextSize(sp2px(10));
-        mPaint.setStyle(Paint.Style.FILL);
-
-        mPaintBg = new Paint();
-        mPaintBg.setAntiAlias(true);
-        mPaintBg.setStyle(Paint.Style.FILL);
-        mPaintBg.setColor(mBgColor);//60% 黑色背景 (透明度 40%)
-
-        mCamera = new Camera();
-        mMatrix = new Matrix();
-
-        mLogoBackgroundRadius = DensityUtils.dip2px(context, 25);//logo的灰色背景圆的半径
-        mLogoWhiteRadius = DensityUtils.dip2px(context, 20);//logo的白色背景的圆的半径
-        mRedPointRadiusWithNum = DensityUtils.dip2px(context, 6);//红点圆半径
-        mRedPointRadius = DensityUtils.dip2px(context, 3);//红点圆半径
-        mRedPointOffset = DensityUtils.dip2px(context, 10);//红点对logo的偏移量,比如左红点就是logo中心的 x - mRedPointOffset
-    }
-
-    /**
-     * 这个方法是否有优化空间
-     */
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        int wh = mLogoBackgroundRadius * 2;
-        setMeasuredDimension(wh, wh);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        float centerX = getWidth() / 2f;
-        float centerY = getHeight() / 2f;
-        canvas.save();//保存一份快照,方便后面恢复
-        mCamera.save();
-        setAlpha(1.0f);
-        if (mStatus == NORMAL) {
-            if (mLastStatus != NORMAL) {
-                canvas.restore();//恢复画布的原始快照
-                mCamera.restore();
-            }
-
-            if (isDragging) {
-
-                //如果当前是拖动状态则放大并旋转
-                // canvas.scale((scaleOffset + 1f), (scaleOffset + 1f), getWidth() / 2, getHeight() / 2);
-                if (mIsResetPosition) {
-                    //手指拖动后离开屏幕复位时使用 x轴旋转 3d动画
-                    mCamera.save();
-                    mCamera.rotateX(720 * scaleOffset);//0-720度 最多转两圈
-                    mCamera.getMatrix(mMatrix);
-
-                    mMatrix.preTranslate(-getWidth() / 2f, -getHeight() / 2f);
-                    mMatrix.postTranslate(getWidth() / 2f, getHeight() / 2f);
-                    canvas.concat(mMatrix);
-                    mCamera.restore();
-                } else {
-                    //手指拖动且手指未离开屏幕则使用 绕图心2d旋转动画
-                    canvas.rotate(60 * mRelateValue, getWidth() / 2f, getHeight() / 2f);
-                }
-            }
-
-
-        } else if (mStatus == HIDE_LEFT) {
-            canvas.translate(-getWidth() * hideOffset, 0);
-            canvas.rotate(0, getWidth() / 2f, getHeight() / 2f);
-            setAlpha(hideOffsetAlpha);
-
-        } else if (mStatus == HIDE_RIGHT) {
-            canvas.translate(getWidth() * hideOffset, 0);
-            canvas.rotate(0, getWidth() / 2f, getHeight() / 2f);
-            setAlpha(hideOffsetAlpha);
-        }
-        canvas.save();
-        if (!isDragging) {
-            if (mDrawDarkBg) {
-                mPaintBg.setColor(Color.TRANSPARENT);
-                canvas.drawCircle(centerX, centerY, mLogoBackgroundRadius, mPaintBg);
-                // 60% 白色 (透明度 40%)
-                mPaint.setColor(0x99ffffff);
-            } else {
-                //100% 白色背景 (透明度 0%)
-                mPaint.setColor(0xFFFFFFFF);
-            }
-            if (mAlphaValue != 0) {
-                mPaint.setAlpha((int) (mAlphaValue * 255));
-            }
-            canvas.drawCircle(centerX, centerY, mLogoWhiteRadius, mPaint);
-        }
-
-        canvas.restore();
-        //100% 白色背景 (透明度 0%)
-        mPaint.setColor(0xFFFFFFFF);
-        int left = (int) (centerX - mBitmap.getWidth() / 2);
-        int top = (int) (centerY - mBitmap.getHeight() / 2);
-        canvas.drawBitmap(mBitmap, left, top, mPaint);
-
-
-        if (!TextUtils.isEmpty(dotNum)) {
-            int readPointRadus = (mDrawNum ? mRedPointRadiusWithNum : mRedPointRadius);
-            mPaint.setColor(Color.RED);
-            if (mStatus == HIDE_LEFT) {
-                canvas.drawCircle(centerX + mRedPointOffset, centerY - mRedPointOffset, readPointRadus, mPaint);
-                if (mDrawNum) {
-                    mPaint.setColor(Color.WHITE);
-                    canvas.drawText(dotNum, centerX + mRedPointOffset - getTextWidth(dotNum, mPaint) / 2, centerY - mRedPointOffset + getTextHeight(dotNum, mPaint) / 2, mPaint);
-                }
-            } else if (mStatus == HIDE_RIGHT) {
-                canvas.drawCircle(centerX - mRedPointOffset, centerY - mRedPointOffset, readPointRadus, mPaint);
-                if (mDrawNum) {
-                    mPaint.setColor(Color.WHITE);
-                    canvas.drawText(dotNum, centerX - mRedPointOffset - getTextWidth(dotNum, mPaint) / 2, centerY - mRedPointOffset + getTextHeight(dotNum, mPaint) / 2, mPaint);
-                }
-            } else {
-                if (mLastStatus == HIDE_LEFT) {
-                    canvas.drawCircle(centerX + mRedPointOffset, centerY - mRedPointOffset, readPointRadus, mPaint);
-                    if (mDrawNum) {
-                        mPaint.setColor(Color.WHITE);
-                        canvas.drawText(dotNum, centerX + mRedPointOffset - getTextWidth(dotNum, mPaint) / 2, centerY - mRedPointOffset + getTextHeight(dotNum, mPaint) / 2, mPaint);
-                    }
-                } else if (mLastStatus == HIDE_RIGHT) {
-                    canvas.drawCircle(centerX - mRedPointOffset, centerY - mRedPointOffset, readPointRadus, mPaint);
-                    if (mDrawNum) {
-                        mPaint.setColor(Color.WHITE);
-                        canvas.drawText(dotNum, centerX - mRedPointOffset - getTextWidth(dotNum, mPaint) / 2, centerY - mRedPointOffset + getTextHeight(dotNum, mPaint) / 2, mPaint);
-                    }
-                }
-            }
-        }
-        mLastStatus = mStatus;
-    }
-
-
-    public void setDotNum(int num, Animator.AnimatorListener l) {
-        if (!inited) {
-            startAnim(num, l);
-        } else {
-            refreshDot(num);
-        }
-    }
-
-    public void refreshDot(int num) {
-        if (num > 0) {
-            String dotNumTmp = String.valueOf(num);
-            if (!TextUtils.equals(dotNum, dotNumTmp)) {
-                dotNum = dotNumTmp;
-                invalidate();
-            }
-        } else {
-            dotNum = null;
-        }
-    }
-
-    public void startAnim(final int num, Animator.AnimatorListener listener) {
-        ValueAnimator valueAnimator = ValueAnimator.ofFloat(1f, 0.6f, 1f, 0.6f);
-        valueAnimator.setInterpolator(mLinearInterpolator);
-        valueAnimator.setDuration(3000);
-        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                mAlphaValue = (float) animation.getAnimatedValue();
-                invalidate();
-
-            }
-        });
-        valueAnimator.addListener(listener);
-        valueAnimator.addListener(new Animator.AnimatorListener() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                inited = true;
-                refreshDot(num);
-                mAlphaValue = 0;
-
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-                mAlphaValue = 0;
-            }
-
-            @Override
-            public void onAnimationRepeat(Animator animation) {
-
-            }
-        });
-        valueAnimator.start();
-    }
-
-    public void setDragging(boolean dragging, float offset, boolean isResetPosition) {
-        isDragging = dragging;
-        this.mIsResetPosition = isResetPosition;
-        if (offset > 0 && offset != this.scaleOffset) {
-            this.scaleOffset = offset;
-        }
-        if (isDragging && mStatus == NORMAL) {
-            if (mDraggingValueAnimator != null) {
-                if (mDraggingValueAnimator.isRunning()) return;
-            }
-            mDraggingValueAnimator = ValueAnimator.ofFloat(0, 6f, 12f, 0f);
-            mDraggingValueAnimator.setInterpolator(mLinearInterpolator);
-            mDraggingValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    mRelateValue = (float) animation.getAnimatedValue();
-                    invalidate();
-                }
-            });
-            mDraggingValueAnimator.addListener(new Animator.AnimatorListener() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    isDragging = false;
-                    mIsResetPosition = false;
-                }
-
-                @Override
-                public void onAnimationCancel(Animator animation) {
-
-                }
-
-                @Override
-                public void onAnimationRepeat(Animator animation) {
-
-                }
-            });
-            mDraggingValueAnimator.setDuration(1000);
-            mDraggingValueAnimator.start();
-        }
-    }
-
-    private int dip2px(float dipValue) {
-        final float scale = getContext().getResources().getDisplayMetrics().density;
-        return (int) (dipValue * scale + 0.5f);
-    }
-
-    private int sp2px(float spValue) {
-        final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
-        return (int) (spValue * fontScale + 0.5f);
-    }
-
-    private float getTextHeight(String text, Paint paint) {
-        Rect rect = new Rect();
-        paint.getTextBounds(text, 0, text.length(), rect);
-        return rect.height() / 1.1f;
-    }
-
-    private float getTextWidth(String text, Paint paint) {
-        return paint.measureText(text);
-    }
-}

+ 0 - 73
library_support/src/main/java/cn/yyxx/support/ui/floating/FloatItem.java

@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2016, Shanghai YUEWEN Information Technology Co., Ltd.
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- *  Neither the name of Shanghai YUEWEN Information Technology Co., Ltd. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY SHANGHAI YUEWEN INFORMATION TECHNOLOGY CO., LTD. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-package cn.yyxx.support.ui.floating;
-
-import android.graphics.Bitmap;
-
-/**
- * Created by wengyiming on 2017/7/21.
- */
-
-public class FloatItem {
-    public String title;
-    public String titleColor;
-    public String bgColor;
-    public Bitmap icon;
-    public String dotNum = null;
-
-    public FloatItem(String title, String titleColor, String bgColor, Bitmap icon, String dotNum) {
-        this.title = title;
-        this.titleColor = titleColor;
-        this.bgColor = bgColor;
-        this.icon = icon;
-        this.dotNum = dotNum;
-    }
-
-    public FloatItem(String title, String titleColor, String bgColor, Bitmap bitmap) {
-        this.title = title;
-        this.titleColor = titleColor;
-        this.bgColor = bgColor;
-        this.icon = bitmap;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (obj == this) return true;
-
-        if (obj instanceof FloatItem) {
-            FloatItem floatItem = (FloatItem) obj;
-            return floatItem.title.equals(this.title);
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        return title.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return "FloatItem{" +
-                "title='" + title + '\'' +
-                ", titleColor=" + titleColor +
-                ", bgColor=" + bgColor +
-                ", icon=" + icon +
-                ", dotNum='" + dotNum + '\'' +
-                '}';
-    }
-}

+ 0 - 1036
library_support/src/main/java/cn/yyxx/support/ui/floating/FloatLogoMenu.java

@@ -1,1036 +0,0 @@
-/*
- * Copyright (c) 2016, Shanghai YUEWEN Information Technology Co., Ltd.
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- *  Neither the name of Shanghai YUEWEN Information Technology Co., Ltd. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY SHANGHAI YUEWEN INFORMATION TECHNOLOGY CO., LTD. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-package cn.yyxx.support.ui.floating;
-
-import android.animation.Animator;
-import android.animation.ValueAnimator;
-import android.app.Activity;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.graphics.Bitmap;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.Drawable;
-import android.os.Build;
-import android.os.CountDownTimer;
-import android.os.Handler;
-import android.os.Looper;
-import android.text.TextUtils;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnTouchListener;
-import android.view.WindowManager;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.widget.LinearLayout;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import cn.yyxx.support.DensityUtils;
-
-/**
- * Created by wengyiming on 2017/7/20.
- */
-public class FloatLogoMenu {
-    /**
-     * 记录 logo 停放的位置,以备下次恢复
-     */
-    private static final String LOCATION_X = "hintLocation";
-    private static final String LOCATION_Y = "locationY";
-
-    /**
-     * 悬浮球 坐落 左 右 标记
-     */
-    public static final int LEFT = 0;
-    public static final int RIGHT = 1;
-
-    /**
-     * 记录系统状态栏的高度
-     */
-    private int mStatusBarHeight;
-    /**
-     * 记录当前手指位置在屏幕上的横坐标值
-     */
-    private float mXInScreen;
-
-    /**
-     * 记录当前手指位置在屏幕上的纵坐标值
-     */
-    private float mYInScreen;
-
-    /**
-     * 记录手指按下时在屏幕上的横坐标的值
-     */
-    private float mXDownInScreen;
-
-    /**
-     * 记录手指按下时在屏幕上的纵坐标的值
-     */
-    private float mYDownInScreen;
-
-    /**
-     * 记录手指按下时在小悬浮窗的View上的横坐标的值
-     */
-    private float mXInView;
-
-    /**
-     * 记录手指按下时在小悬浮窗的View上的纵坐标的值
-     */
-    private float mYinview;
-
-    /**
-     * 记录屏幕的宽度
-     */
-    private int mScreenWidth;
-
-    /**
-     * 来自 activity 的 wManager
-     */
-    private WindowManager wManager;
-
-
-    /**
-     * 为 wManager 设置 LayoutParams
-     */
-    private WindowManager.LayoutParams wmParams;
-
-    /**
-     * 带透明度动画、旋转、放大的悬浮球
-     */
-    private DotImageView mFloatLogo;
-
-
-    /**
-     * 用于 定时 隐藏 logo的定时器
-     */
-    private CountDownTimer mHideTimer;
-
-
-    /**
-     * float menu的高度
-     */
-    private Handler mHandler = new Handler(Looper.getMainLooper());
-
-
-    /**
-     * 悬浮窗左右移动到默认位置 动画的 加速器
-     */
-    private Interpolator mLinearInterpolator = new LinearInterpolator();
-
-    /**
-     * 用于记录上次菜单打开的时间,判断时间间隔
-     */
-    private static double DOUBLE_CLICK_TIME = 0L;
-
-    /**
-     * 标记是否拖动中
-     */
-    private boolean isDraging = false;
-
-    /**
-     * 用于恢复悬浮球的location的属性动画值
-     */
-    private int mResetLocationValue;
-
-    /**
-     * 手指离开屏幕后 用于恢复 悬浮球的 logo 的左右位置
-     */
-    private Runnable updatePositionRunnable = new Runnable() {
-        @Override
-        public void run() {
-            isDraging = true;
-            checkPosition();
-
-        }
-    };
-
-    /**
-     * 这个事件不做任何事情、直接return false则 onclick 事件生效
-     */
-    private OnTouchListener mDefaultOnTouchListerner = new OnTouchListener() {
-        @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            isDraging = false;
-            return false;
-        }
-    };
-
-    /**
-     * 这个事件用于处理移动、自定义点击或者其它事情,return true可以保证onclick事件失效
-     */
-    private OnTouchListener touchListener = new OnTouchListener() {
-        @Override
-        public boolean onTouch(View v, MotionEvent event) {
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_DOWN:
-                    floatEventDown(event);
-                    break;
-                case MotionEvent.ACTION_MOVE:
-                    floatEventMove(event);
-                    break;
-                case MotionEvent.ACTION_UP:
-                case MotionEvent.ACTION_CANCEL:
-                    floatEventUp();
-                    break;
-            }
-            return true;
-        }
-    };
-
-
-    /**
-     * 菜单背景颜色
-     */
-    private String mBackMenuColor;
-
-    /**
-     * 是否绘制红点数字
-     */
-    private boolean mDrawRedPointNum;
-
-
-    /**
-     * 是否绘制圆形菜单项,false绘制方形
-     */
-    private boolean mCicleMenuBg;
-
-
-    /**
-     * R.drawable.game_logo
-     *
-     * @param floatItems
-     */
-    private Bitmap mLogoRes;
-
-    /**
-     * 用于显示在 mActivity 上的 mActivity
-     */
-    private Context mContext;
-
-    /**
-     * 菜单 点击、关闭 监听
-     */
-    private FloatMenuView.OnMenuClickListener mOnMenuClickListener;
-
-
-    /**
-     * 停靠默认位置
-     */
-    private int mDefaultLocation = RIGHT;
-
-
-    /**
-     * 悬浮窗 坐落 位置
-     */
-    private int mHintLocation = mDefaultLocation;
-
-
-    /**
-     * 用于记录菜单项内容
-     */
-    private List<FloatItem> mFloatItems;
-
-    private LinearLayout rootViewRight;
-
-    private LinearLayout rootView;
-
-    private ValueAnimator valueAnimator;
-
-    private boolean isExpaned = false;
-
-    private Drawable mBackground;
-
-
-    private FloatLogoMenu(Builder builder) {
-        mBackMenuColor = builder.mBackMenuColor;
-        mDrawRedPointNum = builder.mDrawRedPointNum;
-        mCicleMenuBg = builder.mCicleMenuBg;
-        mLogoRes = builder.mLogoRes;
-        mContext = builder.mContext;
-        mOnMenuClickListener = builder.mOnMenuClickListener;
-        mDefaultLocation = builder.mDefaultLocation;
-        mFloatItems = builder.mFloatItems;
-        mBackground = builder.mDrawable;
-
-
-//        if (mActivity == null || mActivity.isFinishing() || mActivity.getWindowManager() == null) {
-//            throw new IllegalArgumentException("Activity = null, or Activity is isFinishing ,or this Activity`s  token is bad");
-//        }
-
-        if (mLogoRes == null) {
-            throw new IllegalArgumentException("No logo found,you can setLogo/showWithLogo to set a FloatLogo ");
-        }
-
-        if (mFloatItems.isEmpty()) {
-            throw new IllegalArgumentException("At least one menu item!");
-        }
-
-        initFloatWindow();
-        initTimer();
-        initFloat();
-
-    }
-
-    public void setFloatItemList(List<FloatItem> floatItems) {
-        this.mFloatItems = floatItems;
-        caculateDotNum();
-    }
-
-    /**
-     * 初始化悬浮球 window
-     */
-    private void initFloatWindow() {
-//        wmParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
-//                WindowManager.LayoutParams.WRAP_CONTENT,
-//                WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
-//                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-//                        | WindowManager.LayoutParams.FLAG_FULLSCREEN,
-//                PixelFormat.TRANSLUCENT);
-
-        wmParams = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,
-                WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.FIRST_SUB_WINDOW,
-                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
-                        | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
-                PixelFormat.RGBA_8888);
-
-        if (mContext instanceof Activity) {
-            Activity activity = (Activity) mContext;
-            wManager = activity.getWindowManager();
-            //类似dialog,寄托在activity的windows上,activity关闭时需要关闭当前float
-            wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
-        } else {
-            wManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-                if (Build.VERSION.SDK_INT > 23) {
-                    //在android7.1以上系统需要使用TYPE_PHONE类型 配合运行时权限
-                    wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
-                } else {
-                    wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
-                }
-            } else {
-                wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
-            }
-        }
-
-        mScreenWidth = wManager.getDefaultDisplay().getWidth();
-        int screenHeigth = wManager.getDefaultDisplay().getHeight();
-
-        //判断状态栏是否显示 如果不显示则statusBarHeight为0
-        mStatusBarHeight = dp2Px(0, mContext);
-
-        wmParams.format = PixelFormat.RGBA_8888;
-        wmParams.gravity = Gravity.LEFT | Gravity.TOP;
-
-
-        wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
-                | WindowManager.LayoutParams.FLAG_FULLSCREEN;
-        mHintLocation = getSetting(LOCATION_X, mDefaultLocation);
-        int defaultY = ((screenHeigth - mStatusBarHeight) / 2) / 3;
-        int y = getSetting(LOCATION_Y, defaultY);
-        if (mHintLocation == LEFT) {
-            wmParams.x = 0;
-        } else {
-            wmParams.x = mScreenWidth;
-        }
-
-
-        if (y != 0 && y != defaultY) {
-            wmParams.y = y;
-        } else {
-            wmParams.y = defaultY;
-        }
-
-        wmParams.alpha = 1;
-        wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
-        wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
-    }
-
-
-    /**
-     * 初始化悬浮球
-     */
-    private void initFloat() {
-        generateLeftLineLayout();
-        generateRightLineLayout();
-        mFloatLogo = new DotImageView(mContext, mLogoRes);
-        mFloatLogo.setLayoutParams(new LinearLayout.LayoutParams(dp2Px(30, mContext), dp2Px(30, mContext)));
-        mFloatLogo.setDrawNum(mDrawRedPointNum);
-        mFloatLogo.setBgColor(Color.parseColor(mBackMenuColor));
-        mFloatLogo.setDrawDarkBg(true);
-
-        caculateDotNum();
-        floatBtnEvent();
-        try {
-            wManager.addView(mFloatLogo, wmParams);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-    }
-
-    private void generateLeftLineLayout() {
-
-        rootView = new LinearLayout(mContext);
-        rootView.setOrientation(LinearLayout.HORIZONTAL);
-        rootView.setGravity(Gravity.CENTER);
-        rootView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, DensityUtils.dip2px(mContext, 30)));
-
-        rootView.setBackgroundDrawable(mBackground);
-
-        DotImageView floatLogo = new DotImageView(mContext, mLogoRes);
-        floatLogo.setLayoutParams(new LinearLayout.LayoutParams(DensityUtils.dip2px(mContext, 30), DensityUtils.dip2px(mContext, 30)));
-        floatLogo.setDrawNum(mDrawRedPointNum);
-        floatLogo.setDrawDarkBg(false);
-        floatLogo.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (isExpaned) {
-                    try {
-                        wManager.removeViewImmediate(rootView);
-                        wManager.addView(FloatLogoMenu.this.mFloatLogo, wmParams);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    isExpaned = false;
-                }
-            }
-        });
-
-        final FloatMenuView mFloatMenuView = new FloatMenuView.Builder(mContext)
-                .setFloatItems(mFloatItems)
-                .setBackgroundColor(Color.TRANSPARENT)
-                .setCircleBg(mCicleMenuBg)
-                .setStatus(FloatMenuView.STATUS_LEFT)
-                .setMenuBackgroundColor(Color.TRANSPARENT)
-                .drawNum(mDrawRedPointNum)
-                .create();
-        setMenuClickListener(mFloatMenuView);
-
-        rootView.addView(floatLogo);
-        rootView.addView(mFloatMenuView);
-    }
-
-    public void hideMenu() {
-        if (isExpaned) {
-            try {
-                wManager.removeViewImmediate(mHintLocation == LEFT ? rootView : rootViewRight);
-                wManager.addView(FloatLogoMenu.this.mFloatLogo, wmParams);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            isExpaned = false;
-        }
-    }
-
-    private void generateRightLineLayout() {
-        final DotImageView floatLogo = new DotImageView(mContext, mLogoRes);
-        floatLogo.setLayoutParams(new LinearLayout.LayoutParams(DensityUtils.dip2px(mContext, 30), DensityUtils.dip2px(mContext, 30)));
-        floatLogo.setDrawNum(mDrawRedPointNum);
-        floatLogo.setDrawDarkBg(false);
-
-        floatLogo.setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                if (isExpaned) {
-                    try {
-                        wManager.removeViewImmediate(rootViewRight);
-                        wManager.addView(FloatLogoMenu.this.mFloatLogo, wmParams);
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                    isExpaned = false;
-                }
-            }
-        });
-
-        rootViewRight = new LinearLayout(mContext);
-        rootViewRight.setOrientation(LinearLayout.HORIZONTAL);
-        rootViewRight.setGravity(Gravity.CENTER);
-        rootViewRight.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, DensityUtils.dip2px(mContext, 30)));
-        rootViewRight.setBackgroundDrawable(mBackground);
-
-
-        FloatMenuView mFloatMenuView = new FloatMenuView.Builder(mContext)
-                .setFloatItems(mFloatItems)
-                .setBackgroundColor(Color.TRANSPARENT)
-                .setCircleBg(mCicleMenuBg)
-                .setStatus(FloatMenuView.STATUS_RIGHT)
-                .setMenuBackgroundColor(Color.TRANSPARENT)
-                .drawNum(mDrawRedPointNum)
-                .create();
-        setMenuClickListener(mFloatMenuView);
-
-        rootViewRight.addView(mFloatMenuView);
-        rootViewRight.addView(floatLogo);
-
-
-    }
-
-    /**
-     * 初始化 隐藏悬浮球的定时器
-     */
-    private void initTimer() {
-        if (mHideTimer != null) {
-            mHideTimer.cancel();
-            mHideTimer = null;
-        }
-        mHideTimer = new CountDownTimer(2000, 10) {        //悬浮窗超过5秒没有操作的话会自动隐藏
-            @Override
-            public void onTick(long millisUntilFinished) {
-                if (isExpaned) {
-                    mHideTimer.cancel();
-                }
-            }
-
-            @Override
-            public void onFinish() {
-                if (isExpaned) {
-                    mHideTimer.cancel();
-                    return;
-                }
-                if (!isDraging) {
-                    if (mHintLocation == LEFT) {
-                        mFloatLogo.setStatus(DotImageView.HIDE_LEFT);
-                    } else {
-                        mFloatLogo.setStatus(DotImageView.HIDE_RIGHT);
-                    }
-                    mFloatLogo.setDrawDarkBg(true);
-//                    mFloatLogo.setOnTouchListener(mDefaultOnTouchListerner);//把onClick事件分发下去,防止onclick无效
-                }
-            }
-        };
-    }
-
-
-    /**
-     * 用于 拦截 菜单项的 关闭事件,以方便开始 隐藏定时器
-     *
-     * @param mFloatMenuView
-     */
-    private void setMenuClickListener(final FloatMenuView mFloatMenuView) {
-        mFloatMenuView.setOnMenuClickListener(new FloatMenuView.OnMenuClickListener() {
-            @Override
-            public void onItemClick(int position, String title) {
-
-
-                mFloatLogo.refreshDot(0);
-
-                mOnMenuClickListener.onItemClick(position, title);
-
-
-            }
-
-            @Override
-            public void dismiss() {
-                mFloatLogo.setDrawDarkBg(true);
-                mOnMenuClickListener.dismiss();
-                mHideTimer.start();
-            }
-        });
-
-    }
-
-    private void closeMenu() {
-        wManager.removeViewImmediate(rootView);
-        wManager.addView(FloatLogoMenu.this.mFloatLogo, wmParams);
-    }
-
-    /**
-     * 悬浮窗的点击事件和touch事件的切换
-     */
-    private void floatBtnEvent() {
-        //这里的onCick只有 touchListener = mDefaultOnTouchListerner 才会触发
-//        mFloatLogo.setOnClickListener(new OnClickListener() {
-//            @Override
-//            public void onClick(View v) {
-//                if (!isDraging) {
-//                    if (mFloatLogo.getStatus() != DotImageView.NORMAL) {
-//                        mFloatLogo.setBitmap(mLogoRes);
-//                        mFloatLogo.setStatus(DotImageView.NORMAL);
-//                        if (!mFloatLogo.mDrawDarkBg) {
-//                            mFloatLogo.setDrawDarkBg(true);
-//                        }
-//                    }
-//                    mFloatLogo.setOnTouchListener(touchListener);
-//                    mHideTimer.start();
-//                }
-//            }
-//        });
-
-        mFloatLogo.setOnTouchListener(touchListener);//恢复touch事件
-    }
-
-    /**
-     * 悬浮窗touch事件的 down 事件
-     */
-    private void floatEventDown(MotionEvent event) {
-        isDraging = false;
-        mHideTimer.cancel();
-        if (mFloatLogo.getStatus() != DotImageView.NORMAL) {
-            mFloatLogo.setStatus(DotImageView.NORMAL);
-        }
-        if (!mFloatLogo.mDrawDarkBg) {
-            mFloatLogo.setDrawDarkBg(true);
-        }
-        if (mFloatLogo.getStatus() != DotImageView.NORMAL) {
-            mFloatLogo.setStatus(DotImageView.NORMAL);
-        }
-        mXInView = event.getX();
-        mYinview = event.getY();
-        mXDownInScreen = event.getRawX();
-        mYDownInScreen = event.getRawY();
-        mXInScreen = event.getRawX();
-        mYInScreen = event.getRawY();
-    }
-
-    /**
-     * 悬浮窗touch事件的 move 事件
-     */
-    private void floatEventMove(MotionEvent event) {
-        mXInScreen = event.getRawX();
-        mYInScreen = event.getRawY();
-
-
-        //连续移动的距离超过3则更新一次视图位置
-        if (Math.abs(mXInScreen - mXDownInScreen) > mFloatLogo.getWidth() / 4f || Math.abs(mYInScreen - mYDownInScreen) > mFloatLogo.getWidth() / 4) {
-            wmParams.x = (int) (mXInScreen - mXInView);
-            wmParams.y = (int) (mYInScreen - mYinview) - mFloatLogo.getHeight() / 2;
-            updateViewPosition(); // 手指移动的时候更新小悬浮窗的位置
-            double a = mScreenWidth / 2;
-            float offset = (float) ((a - (Math.abs(wmParams.x - a))) / a);
-            mFloatLogo.setDragging(isDraging, offset, false);
-        } else {
-            isDraging = false;
-            mFloatLogo.setDragging(false, 0, true);
-        }
-    }
-
-    /**
-     * 悬浮窗touch事件的 up 事件
-     */
-    private void floatEventUp() {
-        if (mXInScreen < mScreenWidth / 2f) {   //在左边
-            mHintLocation = LEFT;
-        } else {                   //在右边
-            mHintLocation = RIGHT;
-        }
-        if (valueAnimator == null) {
-            valueAnimator = ValueAnimator.ofInt(64);
-            valueAnimator.setInterpolator(mLinearInterpolator);
-            valueAnimator.setDuration(1000);
-            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator animation) {
-                    mResetLocationValue = (int) animation.getAnimatedValue();
-                    mHandler.post(updatePositionRunnable);
-                }
-            });
-
-            valueAnimator.addListener(new Animator.AnimatorListener() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-
-                }
-
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    if (Math.abs(wmParams.x) < 0) {
-                        wmParams.x = 0;
-                    } else if (Math.abs(wmParams.x) > mScreenWidth) {
-                        wmParams.x = mScreenWidth;
-                    }
-                    updateViewPosition();
-                    isDraging = false;
-                    mFloatLogo.setDragging(false, 0, true);
-                    mHideTimer.start();
-                }
-
-                @Override
-                public void onAnimationCancel(Animator animation) {
-                    if (Math.abs(wmParams.x) < 0) {
-                        wmParams.x = 0;
-                    } else if (Math.abs(wmParams.x) > mScreenWidth) {
-                        wmParams.x = mScreenWidth;
-                    }
-
-                    updateViewPosition();
-                    isDraging = false;
-                    mFloatLogo.setDragging(false, 0, true);
-                    mHideTimer.start();
-
-                }
-
-                @Override
-                public void onAnimationRepeat(Animator animation) {
-
-                }
-            });
-        }
-        if (!valueAnimator.isRunning()) {
-            valueAnimator.start();
-        }
-
-//        //这里需要判断如果如果手指所在位置和logo所在位置在一个宽度内则不移动,
-        if (Math.abs(mXInScreen - mXDownInScreen) > mFloatLogo.getWidth() / 5f || Math.abs(mYInScreen - mYDownInScreen) > mFloatLogo.getHeight() / 5f) {
-            isDraging = false;
-        } else {
-            openMenu();
-        }
-
-    }
-
-
-    /**
-     * 用于检查并更新悬浮球的位置
-     */
-    private void checkPosition() {
-        if (wmParams.x > 0 && wmParams.x < mScreenWidth) {
-            if (mHintLocation == LEFT) {
-                wmParams.x = wmParams.x - mResetLocationValue;
-            } else {
-                wmParams.x = wmParams.x + mResetLocationValue;
-            }
-            updateViewPosition();
-            double a = mScreenWidth / 2f;
-            float offset = (float) ((a - (Math.abs(wmParams.x - a))) / a);
-            mFloatLogo.setDragging(isDraging, offset, true);
-            return;
-        }
-
-
-        if (Math.abs(wmParams.x) < 0) {
-            wmParams.x = 0;
-        } else if (Math.abs(wmParams.x) > mScreenWidth) {
-            wmParams.x = mScreenWidth;
-        }
-        if (valueAnimator.isRunning()) {
-            valueAnimator.cancel();
-        }
-
-        updateViewPosition();
-        isDraging = false;
-
-    }
-
-
-    /**
-     * 打开菜单
-     */
-    private void openMenu() {
-        if (isDraging) return;
-
-        if (!isExpaned) {
-            mFloatLogo.setDrawDarkBg(false);
-            try {
-                wManager.removeViewImmediate(mFloatLogo);
-                if (mHintLocation == RIGHT) {
-                    wManager.addView(rootViewRight, wmParams);
-                } else {
-                    wManager.addView(rootView, wmParams);
-                }
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-
-            isExpaned = true;
-            mHideTimer.cancel();
-        } else {
-            mFloatLogo.setDrawDarkBg(true);
-            if (isExpaned) {
-                try {
-                    wManager.removeViewImmediate(mHintLocation == LEFT ? rootView : rootViewRight);
-                    wManager.addView(mFloatLogo, wmParams);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-
-                isExpaned = false;
-            }
-            mHideTimer.start();
-        }
-
-    }
-
-
-    /**
-     * 更新悬浮窗在屏幕中的位置。
-     */
-    private void updateViewPosition() {
-        isDraging = true;
-        try {
-            if (!isExpaned) {
-                if (wmParams.y - mFloatLogo.getHeight() / 2 <= 0) {
-                    wmParams.y = mStatusBarHeight;
-                    isDraging = true;
-                }
-                wManager.updateViewLayout(mFloatLogo, wmParams);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public void show() {
-
-        if (wManager != null && wmParams != null && mFloatLogo != null) {
-            try {
-                wManager.removeView(mFloatLogo);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            wManager.addView(mFloatLogo, wmParams);
-
-        }
-
-        if (mHideTimer == null) {
-            initTimer();
-        }
-        mHideTimer.start();
-    }
-
-
-    /**
-     * 关闭菜单
-     */
-    public void hide() {
-        release();
-    }
-
-
-    /**
-     * 移除所有悬浮窗 释放资源
-     */
-    public void release() {
-        //记录上次的位置logo的停放位置,以备下次恢复
-        saveSetting(LOCATION_X, mHintLocation);
-        saveSetting(LOCATION_Y, wmParams.y);
-        mFloatLogo.clearAnimation();
-        if (mHideTimer != null) {
-            mHideTimer.cancel();
-            mHideTimer = null;
-        }
-        try {
-            if (isExpaned) {
-                wManager.removeViewImmediate(mHintLocation == LEFT ? rootView : rootViewRight);
-            } else {
-                wManager.removeViewImmediate(mFloatLogo);
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        isExpaned = false;
-        isDraging = false;
-        wManager = null;
-    }
-
-    /**
-     * 计算总红点数
-     */
-    private void caculateDotNum() {
-        int dotNum = 0;
-        for (FloatItem floatItem : mFloatItems) {
-            if (!TextUtils.isEmpty(floatItem.dotNum)) {
-                int num = Integer.parseInt(floatItem.dotNum);
-                dotNum = dotNum + num;
-            }
-        }
-        mFloatLogo.setDrawNum(mDrawRedPointNum);
-        setDotNum(dotNum);
-    }
-
-    /**
-     * 绘制悬浮球的红点
-     */
-    private void setDotNum(int dotNum) {
-        mFloatLogo.setDotNum(dotNum, new Animator.AnimatorListener() {
-            @Override
-            public void onAnimationStart(Animator animation) {
-
-            }
-
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!isDraging) {
-                    mHideTimer.start();
-                }
-            }
-
-            @Override
-            public void onAnimationCancel(Animator animation) {
-
-            }
-
-            @Override
-            public void onAnimationRepeat(Animator animation) {
-
-            }
-        });
-    }
-
-    /**
-     * 用于暴露给外部判断是否包含某个菜单项
-     *
-     * @param menuLabel string
-     * @return boolean
-     */
-    public boolean hasMenu(String menuLabel) {
-        for (FloatItem menuItem : mFloatItems) {
-            if (TextUtils.equals(menuItem.title, menuLabel)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * 用于保存悬浮球的位置记录
-     *
-     * @param key          String
-     * @param defaultValue int
-     * @return int
-     */
-    private int getSetting(String key, int defaultValue) {
-        try {
-            SharedPreferences sp = mContext.getSharedPreferences("floatLogo", 0);
-            return sp.getInt(key, defaultValue);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return defaultValue;
-    }
-
-    /**
-     * 用于保存悬浮球的位置记录
-     *
-     * @param key   String
-     * @param value int
-     */
-    public void saveSetting(String key, int value) {
-        try {
-            SharedPreferences.Editor sp = mContext.getSharedPreferences("floatLogo", 0).edit();
-            sp.putInt(key, value);
-            sp.apply();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-    public static int dp2Px(float dp, Context mContext) {
-        return (int) TypedValue.applyDimension(
-                TypedValue.COMPLEX_UNIT_DIP,
-                dp,
-                mContext.getResources().getDisplayMetrics());
-    }
-
-
-    public interface OnMenuClickListener {
-        void onMenuExpended(boolean isExpened);
-    }
-
-
-    public void setValueAnimator() {
-
-    }
-
-    public static final class Builder {
-        private String mBackMenuColor;
-        private boolean mDrawRedPointNum;
-        private boolean mCicleMenuBg;
-        private Bitmap mLogoRes;
-        private int mDefaultLocation;
-        private List<FloatItem> mFloatItems = new ArrayList<>();
-        private Context mContext;
-        private FloatMenuView.OnMenuClickListener mOnMenuClickListener;
-        private Drawable mDrawable;
-
-
-        public Builder setBgDrawable(Drawable drawable) {
-            mDrawable = drawable;
-            return this;
-        }
-
-        public Builder() {
-        }
-
-        public Builder setFloatItems(List<FloatItem> mFloatItems) {
-            this.mFloatItems = mFloatItems;
-            return this;
-        }
-
-        public Builder addFloatItem(FloatItem floatItem) {
-            this.mFloatItems.add(floatItem);
-            return this;
-        }
-
-        public Builder backMenuColor(String color) {
-            mBackMenuColor = color;
-            return this;
-        }
-
-        public Builder drawRedPointNum(boolean val) {
-            mDrawRedPointNum = val;
-            return this;
-        }
-
-        public Builder drawCicleMenuBg(boolean val) {
-            mCicleMenuBg = val;
-            return this;
-        }
-
-        public Builder logo(Bitmap bitmap) {
-            mLogoRes = bitmap;
-            return this;
-        }
-
-        public Builder withActivity(Activity activity) {
-            mContext = activity;
-            return this;
-        }
-
-        public Builder withContext(Context context) {
-            mContext = context;
-            return this;
-        }
-
-        public Builder setOnMenuItemClickListener(FloatMenuView.OnMenuClickListener val) {
-            mOnMenuClickListener = val;
-            return this;
-        }
-
-        public Builder defaultLocation(int location) {
-            mDefaultLocation = location;
-            return this;
-        }
-
-        public FloatLogoMenu showWithListener(FloatMenuView.OnMenuClickListener listener) {
-            mOnMenuClickListener = listener;
-            return new FloatLogoMenu(this);
-        }
-
-        public FloatLogoMenu showWithLogo(Bitmap logo) {
-            mLogoRes = logo;
-            return new FloatLogoMenu(this);
-        }
-
-        public FloatLogoMenu show() {
-            return new FloatLogoMenu(this);
-        }
-    }
-
-
-}

+ 0 - 413
library_support/src/main/java/cn/yyxx/support/ui/floating/FloatMenuView.java

@@ -1,413 +0,0 @@
-/*
- * Copyright (c) 2016, Shanghai YUEWEN Information Technology Co., Ltd.
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- *
- *  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- *  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- *  Neither the name of Shanghai YUEWEN Information Technology Co., Ltd. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY SHANGHAI YUEWEN INFORMATION TECHNOLOGY CO., LTD. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-package cn.yyxx.support.ui.floating;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.text.TextUtils;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import cn.yyxx.support.hawkeye.LogUtils;
-
-public class FloatMenuView extends View {
-    public static final int STATUS_LEFT = 3;//展开左边菜单
-    public static final int STATUS_RIGHT = 4;//展开右边菜单
-
-    private int mStatus = STATUS_RIGHT;//默认右边
-
-    private Paint mPaint;//画笔
-    private int mBackgroundColor = 0x00FFFFFF;//默认背景颜色 完全透明的白色
-
-    private int mMenuBackgroundColor = -1;//菜单的背景颜色
-
-    private RectF mBgRect;//菜单的背景矩阵
-    private int mItemWidth = dip2px(30);//菜单项的宽度
-    private int mItemHeight = dip2px(30);//菜单项的高度
-    private int mItemLeft = 0;//菜单项左边的默认偏移值,这里是0
-    //    private int mCorner = dip2px(2);//菜单背景的圆角多出的宽度
-    private int mCorner = 0;
-
-    private int mRadius = dip2px(4);//红点消息半径
-    private final int mRedPointRadiusWithNoNum = dip2px(3);//红点圆半径
-
-    private int mFontSizePointNum = sp2px(10);//红点消息数字的文字大小
-
-    private int mFontSizeTitle = sp2px(10);//菜单项的title的文字大小
-    private float mFirstItemTop;//菜单项的最小y值,上面起始那条线
-    private boolean mDrawNum = false;//是否绘制数字,false则只绘制红点
-    private boolean circleBg = false;//菜单项背景是否绘制成圆形,false则绘制矩阵
-
-    private Canvas canvas = null;
-    private List<FloatItem> mItemList = new ArrayList<>();//菜单项的内容
-    private List<RectF> mItemRectList = new ArrayList<>();//菜单项所占用位置的记录,用于判断点击事件
-
-    private OnMenuClickListener mOnMenuClickListener;//菜单项的点击事件回调
-
-    private ObjectAnimator mAlphaAnim;//消失关闭动画的透明值
-
-    //设置菜单内容集合
-    public void setItemList(List<FloatItem> itemList) {
-        mItemList = itemList;
-    }
-
-    //设置是否绘制红点数字
-    public void drawNum(boolean drawNum) {
-        mDrawNum = drawNum;
-    }
-
-    //设置是否绘制圆形菜单,否则矩阵
-    public void setCircleBg(boolean circleBg) {
-        this.circleBg = circleBg;
-    }
-
-    //用于标记所依赖的view的screen的坐标,实际view的坐标是window坐标,所以这里后面会减去状态栏的高度
-
-
-    //设置菜单的背景颜色
-    public void setMenuBackgroundColor(int mMenuBackgroundColor) {
-        this.mMenuBackgroundColor = mMenuBackgroundColor;
-    }
-
-    //设置这个view(整个屏幕)的背景,这里默认透明
-    public void setBackgroundColor(int BackgroundColor) {
-        this.mBackgroundColor = BackgroundColor;
-    }
-
-
-    //下面开始的注释我写不动了,看不懂的话请自行领悟吧
-    public FloatMenuView(Context context) {
-        super(context);
-    }
-
-    public FloatMenuView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public FloatMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public FloatMenuView(Context baseContext, int status) {
-        super(baseContext);
-        mStatus = status;
-        int screenWidth = getResources().getDisplayMetrics().widthPixels;
-        int screenHeight = getResources().getDisplayMetrics().heightPixels;
-        LogUtils.d(screenWidth);
-        LogUtils.d(screenHeight);
-        mBgRect = new RectF(0, 0, screenWidth, screenHeight);
-        initView();
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        setMeasuredDimension(mItemWidth * mItemList.size(), mItemHeight);
-    }
-
-    private void initView() {
-        mPaint = new Paint();
-        mPaint.setAntiAlias(true);
-        mPaint.setStyle(Paint.Style.FILL);
-        mPaint.setTextSize(sp2px(10));
-
-        mAlphaAnim = ObjectAnimator.ofFloat(this, "alpha", 1.0f, 0f);
-        mAlphaAnim.setDuration(50);
-        mAlphaAnim.addListener(new MyAnimListener() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (mOnMenuClickListener != null) {
-                    removeView();
-                    mOnMenuClickListener.dismiss();
-                }
-            }
-        });
-
-        mFirstItemTop = 0;
-        mItemLeft = 0;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        this.canvas = canvas;
-        switch (mStatus) {
-            case STATUS_LEFT:
-            case STATUS_RIGHT:
-                drawBackground(canvas);
-                drawFloatLeftItem(canvas);
-                break;
-        }
-    }
-
-    private void drawBackground(Canvas canvas) {
-        mPaint.setColor(mBackgroundColor);
-        canvas.drawRect(mBgRect, mPaint);
-
-    }
-
-    private void drawFloatLeftItem(Canvas canvas) {
-        mItemRectList.clear();
-        for (int i = 0; i < mItemList.size(); i++) {
-            canvas.save();
-            mPaint.setColor(mMenuBackgroundColor);
-            if (circleBg) {
-                float cx = (mItemLeft + i * mItemWidth) + mItemWidth / 2f;//x中心点
-                float cy = mFirstItemTop + mItemHeight / 2f;//y中心点
-                float radius = mItemWidth / 2f;//半径
-                canvas.drawCircle(cx, cy, radius, mPaint);
-            } else {
-                mPaint.setColor(Color.parseColor(mItemList.get(i).bgColor));
-                canvas.drawRect(mItemLeft + i * mItemWidth, mFirstItemTop, mItemLeft + mItemWidth + i * mItemWidth, mFirstItemTop + mItemHeight, mPaint);
-            }
-
-            mItemRectList.add(new RectF(mItemLeft + i * mItemWidth, mFirstItemTop, mItemLeft + mItemWidth + i * mItemWidth, mFirstItemTop + mItemHeight));
-            mPaint.setColor(Color.parseColor(mItemList.get(i).bgColor));
-            drawIconTitleDot(canvas, i);
-        }
-        canvas.restore();
-    }
-
-
-    private void drawIconTitleDot(Canvas canvas, int position) {
-        FloatItem floatItem = mItemList.get(position);
-
-        if (floatItem.icon != null) {
-            float centerX = mItemLeft + mItemWidth / 2f + (mItemWidth) * position;//计算每一个item的中心点x的坐标值
-            float centerY = mFirstItemTop + mItemHeight / 2f;//计算每一个item的中心点的y坐标值
-
-            float left = centerX - mItemWidth / 4f;//计算icon的左坐标值 中心点往左移宽度的四分之一
-            float right = centerX + mItemWidth / 4f;
-
-            float iconH = mItemHeight * 0.5f;//计算出icon的宽度 = icon的高度
-
-            float textH = getTextHeight(floatItem.title, mPaint);
-            float paddingH = (mItemHeight - iconH - textH - mRadius) / 2;//总高度减去文字的高度,减去icon高度,再除以2就是上下的间距剩余
-
-            float top = centerY - mItemHeight / 2f + paddingH;//计算icon的上坐标值
-            float bottom = top + iconH;//剩下的高度空间用于画文字
-
-            //画icon
-            mPaint.setColor(Color.parseColor(floatItem.titleColor));
-            canvas.drawBitmap(floatItem.icon, null, new RectF(left, top, right, bottom), mPaint);
-
-            if (!TextUtils.isEmpty(floatItem.dotNum) && !floatItem.dotNum.equals("0")) {
-                float dotLeft = centerX + mItemWidth / 5f;
-                float cx = dotLeft + mCorner;//x中心点
-                float cy = top + mCorner;//y中心点
-
-                int radiu = mDrawNum ? mRadius : mRedPointRadiusWithNoNum;
-                //画红点
-                mPaint.setColor(Color.RED);
-                canvas.drawCircle(cx, cy, radiu, mPaint);
-                if (mDrawNum) {
-                    mPaint.setColor(Color.WHITE);
-                    mPaint.setTextSize(mFontSizePointNum);
-                    //画红点消息数
-                    canvas.drawText(floatItem.dotNum, cx - getTextWidth(floatItem.dotNum, mPaint) / 2, cy + getTextHeight(floatItem.dotNum, mPaint) / 2, mPaint);
-                }
-            }
-            mPaint.setColor(Color.parseColor(floatItem.titleColor));
-            mPaint.setTextSize(mFontSizeTitle);
-            //画menu title
-            canvas.drawText(floatItem.title, centerX - getTextWidth(floatItem.title, mPaint) / 2, centerY + iconH / 2 + getTextHeight(floatItem.title, mPaint) / 2, mPaint);
-        }
-    }
-
-
-    public void startAnim() {
-        if (mItemList.size() == 0) {
-            return;
-        }
-        invalidate();
-    }
-
-
-    public void dismiss() {
-        if (!mAlphaAnim.isRunning()) {
-            mAlphaAnim.start();
-        }
-    }
-
-    private void removeView() {
-        ViewGroup vg = (ViewGroup) this.getParent();
-        if (vg != null) {
-            vg.removeView(this);
-        }
-    }
-
-    @Override
-    protected void onWindowVisibilityChanged(int visibility) {
-        if (visibility == GONE) {
-            if (mOnMenuClickListener != null) {
-                mOnMenuClickListener.dismiss();
-            }
-        }
-        super.onWindowVisibilityChanged(visibility);
-
-
-    }
-
-    public void setOnMenuClickListener(OnMenuClickListener onMenuClickListener) {
-        this.mOnMenuClickListener = onMenuClickListener;
-
-    }
-
-    public interface OnMenuClickListener {
-        void onItemClick(int position, String title);
-
-        void dismiss();
-
-    }
-
-    private abstract class MyAnimListener implements Animator.AnimatorListener {
-        @Override
-        public void onAnimationStart(Animator animation) {
-
-        }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-
-        }
-
-        @Override
-        public void onAnimationRepeat(Animator animation) {
-
-        }
-    }
-
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        switch (event.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                for (int i = 0; i < mItemRectList.size(); i++) {
-                    if (mOnMenuClickListener != null && isPointInRect(new PointF(event.getX(), event.getY()), mItemRectList.get(i))) {
-                        mOnMenuClickListener.onItemClick(i, mItemList.get(i).title);
-                        return true;
-                    }
-                }
-                dismiss();
-        }
-        return false;
-    }
-
-    private boolean isPointInRect(PointF pointF, RectF targetRect) {
-        return pointF.x >= targetRect.left && pointF.x <= targetRect.right && pointF.y >= targetRect.top && pointF.y <= targetRect.bottom;
-    }
-
-
-    public static class Builder {
-        private Context mContext;
-        private List<FloatItem> mFloatItems = new ArrayList<>();
-        private int mBgColor = Color.TRANSPARENT;
-        private int mStatus = STATUS_LEFT;
-        private boolean circleBg = false;
-        private int mMenuBackgroundColor = -1;
-        private boolean mDrawNum = false;
-
-
-        public Builder(Context activity) {
-            mContext = activity;
-        }
-
-        public Builder drawNum(boolean drawNum) {
-            mDrawNum = drawNum;
-            return this;
-        }
-
-
-        public Builder setMenuBackgroundColor(int mMenuBackgroundColor) {
-            this.mMenuBackgroundColor = mMenuBackgroundColor;
-            return this;
-        }
-
-
-        public Builder setCircleBg(boolean circleBg) {
-            this.circleBg = circleBg;
-            return this;
-        }
-
-        public Builder setStatus(int status) {
-            mStatus = status;
-            return this;
-        }
-
-        public Builder setFloatItems(List<FloatItem> floatItems) {
-            this.mFloatItems = floatItems;
-            return this;
-        }
-
-
-        public Builder addItem(FloatItem floatItem) {
-            mFloatItems.add(floatItem);
-            return this;
-        }
-
-        public Builder addItems(List<FloatItem> list) {
-            mFloatItems.addAll(list);
-            return this;
-        }
-
-        public Builder setBackgroundColor(int color) {
-            mBgColor = color;
-            return this;
-        }
-
-        public FloatMenuView create() {
-            FloatMenuView floatMenuView = new FloatMenuView(mContext, mStatus);
-            floatMenuView.setItemList(mFloatItems);
-            floatMenuView.setBackgroundColor(mBgColor);
-            floatMenuView.setCircleBg(circleBg);
-            floatMenuView.startAnim();
-            floatMenuView.drawNum(mDrawNum);
-            floatMenuView.setMenuBackgroundColor(mMenuBackgroundColor);
-            return floatMenuView;
-        }
-
-    }
-
-
-    private int dip2px(float dipValue) {
-        final float scale = getContext().getResources().getDisplayMetrics().density;
-        return (int) (dipValue * scale + 0.5f);
-    }
-
-    private int sp2px(float spValue) {
-        final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
-        return (int) (spValue * fontScale + 0.5f);
-    }
-
-    private float getTextHeight(String text, Paint paint) {
-        Rect rect = new Rect();
-        paint.getTextBounds(text, 0, text.length(), rect);
-        return rect.height() / 1.1f;
-    }
-
-    private float getTextWidth(String text, Paint paint) {
-        return paint.measureText(text);
-    }
-}

+ 208 - 0
library_support/src/main/java/cn/yyxx/support/ui/scaleprogress/ScaleLoadingView.java

@@ -0,0 +1,208 @@
+package cn.yyxx.support.ui.scaleprogress;
+
+import android.animation.Animator;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author #Suyghur,
+ * Created on 2021/3/2
+ */
+public class ScaleLoadingView extends View {
+
+    private float mDefaultSize = 0f;
+    private int mBarColor = Color.GREEN;
+    private int startColor = 0;
+    private int endColor = 0;
+    private Paint mPaint;
+    private List<DataBean> mDataBeanList = null;
+    private int mBarCount = 5;
+    private float mBarDivideSize = 0f;
+    private long mPerBarTime = 300L;
+
+    public ScaleLoadingView(Context context, int viewSize, int divideSize, int count, int startColor, int endColor) {
+        super(context);
+        this.mDefaultSize = viewSize;
+        this.mBarDivideSize = divideSize;
+        this.mBarCount = count;
+        this.startColor = startColor;
+        this.endColor = endColor;
+        initView(context);
+    }
+
+//    public ScaleLoadingView(Context context, @Nullable AttributeSet attrs) {
+//        this(context, attrs, 0);
+//    }
+//
+//    public ScaleLoadingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+//        super(context, attrs, defStyleAttr);
+//        initView(context);
+//    }
+
+    private void initView(Context context) {
+//        mDefaultSize = DensityUtils.dip2px(context, 60f);
+//        mBarDivideSize = DensityUtils.dip2px(context, 5f);
+        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPaint.setStyle(Paint.Style.FILL);
+//        mPaint.setColor(mBarColor);
+        LinearGradient linearGradient = new LinearGradient(0, 0, 180, 0, startColor, endColor, Shader.TileMode.MIRROR);
+        mPaint.setShader(linearGradient);
+        if (mDataBeanList == null) {
+            mDataBeanList = new ArrayList<>();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        int viewSize = measureMinSize(widthMeasureSpec, heightMeasureSpec, Math.round(mDefaultSize));
+        setMeasuredDimension(viewSize, viewSize);
+    }
+
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        for (DataBean bean : mDataBeanList) {
+            bean.valueAnimator.cancel();
+        }
+
+        mDataBeanList.clear();
+
+        for (int i = 0; i < mBarCount; i++) {
+            float totalDivideSize = (mBarCount - 1) * mBarDivideSize;
+            if (totalDivideSize >= w) {
+                return;
+            }
+
+            float barWidth = (w - totalDivideSize) / mBarCount;
+            RectF rectF = new RectF();
+            rectF.left = i * (barWidth + mBarDivideSize);
+            rectF.top = h / 3.0f;
+            rectF.right = rectF.left + barWidth;
+            rectF.bottom = h - rectF.top;
+
+            mDataBeanList.add(new DataBean(rectF, mBarCount <= 1 ? 0 : mPerBarTime / (mBarCount - 1) * i));
+        }
+        for (DataBean bean : mDataBeanList) {
+            bean.valueAnimator.start();
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        for (DataBean bean : mDataBeanList) {
+            canvas.drawRect(bean.rectF, mPaint);
+        }
+        postInvalidateDelayed(10);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        for (DataBean bean : mDataBeanList) {
+            bean.valueAnimator.cancel();
+            bean.valueAnimator.start();
+        }
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+//        LogUtils.d(" --- onDetachedFromWindow ---");
+        if (mDataBeanList != null) {
+//            LogUtils.d(" --- onDetachedFromWindow size : " + mDataBeanList.size() + " ---");
+//            for (int i = 0; i < mDataBeanList.size(); i++) {
+//                LogUtils.d("cancel valueAnimator " + i);
+//                if (mDataBeanList.get(i).valueAnimator != null) {
+//                    mDataBeanList.get(i).valueAnimator.cancel();
+//                    mDataBeanList.get(i).valueAnimator = null;
+//                }
+//
+//            }
+            for (DataBean bean : mDataBeanList) {
+                if (bean.valueAnimator != null) {
+                    bean.valueAnimator.cancel();
+                    bean.valueAnimator = null;
+                }
+            }
+            mDataBeanList.clear();
+            mDataBeanList = null;
+        }
+    }
+
+    private int measureMinSize(int widthMeasureSpec, int heightMeasureSpec, int defaultSize) {
+        int wMode = MeasureSpec.getMode(widthMeasureSpec);
+        int hMode = MeasureSpec.getMode(heightMeasureSpec);
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        int height = MeasureSpec.getSize(heightMeasureSpec);
+        if (wMode == MeasureSpec.AT_MOST || wMode == MeasureSpec.UNSPECIFIED) {
+            width = defaultSize;
+        }
+        if (hMode == MeasureSpec.AT_MOST || hMode == MeasureSpec.UNSPECIFIED) {
+            height = defaultSize;
+        }
+        return Math.min(width, height);
+    }
+
+    private class DataBean {
+        RectF rectF;
+        ValueAnimator valueAnimator;
+
+        DataBean(final RectF rectF, long delay) {
+            this.valueAnimator = ValueAnimator.ofFloat(0.0f, 100.0f);
+            valueAnimator.setRepeatCount(1);
+            valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
+            valueAnimator.setDuration(mPerBarTime);
+            valueAnimator.setInterpolator(new AccelerateInterpolator());
+            valueAnimator.setStartDelay(delay);
+
+            valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    float v = getHeight() / 3.0f;
+                    float min = v / 2.0f;
+                    rectF.top = getHeight() / 2.0f - (min + v * animation.getAnimatedFraction());
+                    rectF.bottom = getHeight() - rectF.top;
+                }
+            });
+
+            valueAnimator.addListener(new Animator.AnimatorListener() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (valueAnimator != null) {
+                        valueAnimator.setStartDelay(mBarCount <= 1 ? 0 : (mPerBarTime / (mBarCount - 1)) + 500);
+                        valueAnimator.start();
+                    }
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+
+                }
+
+                @Override
+                public void onAnimationRepeat(Animator animation) {
+
+                }
+            });
+            this.rectF = rectF;
+        }
+    }
+}