Browse Source

1.优化首页UI

王鹏鹏 2 years ago
parent
commit
cc6552c685

+ 2 - 0
home/src/main/java/com/yingyangfly/home/activity/HomeActivity.kt

@@ -199,6 +199,8 @@ class HomeActivity : BaseMVVMActivity<ActivityHomeBinding, HomeViewModel>() {
         }, success = {
             if (it != null) {
                 binding.data = it
+                binding.tvBrainPowerValue.setEnableAnim(true)
+                binding.tvBrainPowerValue.setNumberString(it.mentalPower)
             }
         })
     }

+ 201 - 0
home/src/main/java/com/yingyangfly/home/widget/NumberAnimTextView.java

@@ -0,0 +1,201 @@
+package com.yingyangfly.home.widget;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TypeEvaluator;
+import android.animation.ValueAnimator;
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.TextView;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+
+/**
+ * 数字增加动画的 TextView
+ *
+ * @author bakumon
+ * @date 16-11-26
+ */
+@SuppressLint("AppCompatCustomView")
+public class NumberAnimTextView extends TextView {
+
+    /**
+     * 起始值 默认 0
+     */
+    private String mNumStart = "0";
+    /**
+     * 结束值
+     */
+    private String mNumEnd;
+    /**
+     * 动画总时间 默认 2000 毫秒
+     */
+    private long mDuration = 2000;
+    /**
+     * 前缀
+     */
+    private String mPrefixString = "";
+    /**
+     * 后缀
+     */
+    private String mPostfixString = "";
+    /**
+     * 是否开启动画
+     */
+    private boolean mIsEnableAnim = true;
+    /**
+     * 是否是整数
+     */
+    private boolean isInt;
+    private ValueAnimator animator;
+
+    public NumberAnimTextView(Context context) {
+        super(context);
+    }
+
+    public NumberAnimTextView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public NumberAnimTextView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+    }
+
+    public void setNumberString(String number) {
+        setNumberString("0", number);
+    }
+
+    public void setNumberString(String numberStart, String numberEnd) {
+        mNumStart = numberStart;
+        mNumEnd = numberEnd;
+        if (checkNumString(numberStart, numberEnd)) {
+            // 数字合法 开始数字动画
+            start();
+        } else {
+            // 数字不合法 直接调用 setText 设置最终值
+            setText(mPrefixString + numberEnd + mPostfixString);
+        }
+    }
+
+    public void setEnableAnim(boolean enableAnim) {
+        mIsEnableAnim = enableAnim;
+    }
+
+    public void setDuration(long mDuration) {
+        this.mDuration = mDuration;
+    }
+
+    public void setPrefixString(String mPrefixString) {
+        this.mPrefixString = mPrefixString;
+    }
+
+    public void setPostfixString(String mPostfixString) {
+        this.mPostfixString = mPostfixString;
+    }
+
+    /**
+     * 校验数字的合法性
+     *
+     * @param numberStart  开始的数字
+     * @param numberEnd    结束的数字
+     * @return 合法性
+     */
+    private boolean checkNumString(String numberStart, String numberEnd) {
+
+        String regexInteger = "-?\\d*";
+        isInt = numberEnd.matches(regexInteger) && numberStart.matches(regexInteger);
+        if (isInt) {
+            return true;
+        }
+        String regexDecimal = "-?[1-9]\\d*.\\d*|-?0.\\d*[1-9]\\d*";
+        if ("0".equals(numberStart)) {
+            if (numberEnd.matches(regexDecimal)) {
+                return true;
+            }
+        }
+        if (numberEnd.matches(regexDecimal) && numberStart.matches(regexDecimal)) {
+            return true;
+        }
+        return false;
+    }
+
+    private void start() {
+        if (!mIsEnableAnim) {
+            // 禁止动画
+            setText(mPrefixString + format(new BigDecimal(mNumEnd)) + mPostfixString);
+            return;
+        }
+        animator = ValueAnimator.ofObject(new BigDecimalEvaluator(), new BigDecimal(mNumStart), new BigDecimal(mNumEnd));
+        animator.setDuration(mDuration);
+        animator.setInterpolator(new AccelerateDecelerateInterpolator());
+        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator valueAnimator) {
+                BigDecimal value = (BigDecimal) valueAnimator.getAnimatedValue();
+                setText(mPrefixString + format(value) + mPostfixString);
+            }
+        });
+        animator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                setText(mPrefixString + mNumEnd + mPostfixString);
+            }
+        });
+        animator.start();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        if (animator != null) {
+            animator.cancel();
+        }
+    }
+
+    /**
+     * 格式化 BigDecimal ,小数部分时保留两位小数并四舍五入
+     *
+     * @param bd  BigDecimal
+     * @return 格式化后的 String
+     */
+    private String format(BigDecimal bd) {
+        StringBuilder pattern = new StringBuilder();
+        if (isInt) {
+            pattern.append("#,###");
+        } else {
+            int length = 0;
+            String[] s1 = mNumStart.split("\\.");
+            String[] s2 = mNumEnd.split("\\.");
+            String[] s = s1.length > s2.length ? s1 : s2;
+            if (s.length > 1) {
+                // 小数部分
+                String decimals = s[1];
+                if (decimals != null) {
+                    length = decimals.length();
+                }
+            }
+            pattern.append("#,##0");
+            if (length > 0) {
+                pattern.append(".");
+                for (int i = 0; i < length; i++) {
+                    pattern.append("0");
+                }
+            }
+        }
+        DecimalFormat df = new DecimalFormat(pattern.toString());
+        return df.format(bd);
+    }
+
+    private static class BigDecimalEvaluator implements TypeEvaluator {
+        @Override
+        public Object evaluate(float fraction, Object startValue, Object endValue) {
+            BigDecimal start = (BigDecimal) startValue;
+            BigDecimal end = (BigDecimal) endValue;
+            BigDecimal result = end.subtract(start);
+            return result.multiply(new BigDecimal(fraction)).add(start);
+        }
+    }
+}

+ 2 - 2
home/src/main/res/layout/activity_home.xml

@@ -442,11 +442,11 @@
                         android:textColor="@android:color/white"
                         android:textSize="@dimen/divider_24px" />
 
-                    <androidx.appcompat.widget.AppCompatTextView
+                    <com.yingyangfly.home.widget.NumberAnimTextView
+                        android:id="@+id/tvBrainPowerValue"
                         android:layout_width="wrap_content"
                         android:layout_height="wrap_content"
                         android:layout_marginTop="@dimen/divider_9px"
-                        android:text="@{data.mentalPower}"
                         android:textColor="@android:color/white"
                         android:textSize="@dimen/divider_42px"
                         android:textStyle="bold" />