Browse Source

1.游戏结果弹窗页面游戏分数添加动效

王鹏鹏 2 years ago
parent
commit
4c50729cce

+ 2 - 2
.idea/misc.xml

@@ -490,7 +490,7 @@
         <entry key="..\:/workspace/hcp-pads/baselib/src/main/res/layout/dialog_loading.xml" value="0.23697916666666666" />
         <entry key="..\:/workspace/hcp-pads/baselib/src/main/res/layout/dialog_message.xml" value="0.176" />
         <entry key="..\:/workspace/hcp-pads/baselib/src/main/res/layout/dialog_tips.xml" value="0.536" />
-        <entry key="..\:/workspace/hcp-pads/baselib/src/main/res/layout/fragment_task.xml" value="0.6" />
+        <entry key="..\:/workspace/hcp-pads/baselib/src/main/res/layout/fragment_task.xml" value="0.2" />
         <entry key="..\:/workspace/hcp-pads/baselib/src/main/res/layout/rv_empty.xml" value="0.23697916666666666" />
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/drawable/bg_full_game_text.xml" value="0.151" />
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/drawable/bg_game_back.xml" value="0.151" />
@@ -520,7 +520,7 @@
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/activity_game_settlement.xml" value="0.536" />
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/activity_main.xml" value="0.23697916666666666" />
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/activity_play_game.xml" value="0.3953084274543875" />
-        <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/dialog_completion_training.xml" value="0.264" />
+        <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/dialog_completion_training.xml" value="0.6" />
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/dialog_count_down.xml" value="0.5676056338028169" />
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/dialog_exit_game.xml" value="0.2" />
         <entry key="..\:/workspace/hcp-pads/game/src/main/res/layout/dialog_game_loading.xml" value="0.23697916666666666" />

+ 16 - 11
game/src/main/java/com/yingyangfly/game/dialog/CompletionTrainingDialog.kt

@@ -1,12 +1,12 @@
 package com.yingyangfly.game.dialog
 
 import android.annotation.SuppressLint
+import android.content.Context
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import androidx.appcompat.widget.AppCompatImageView
-import androidx.appcompat.widget.AppCompatTextView
 import androidx.fragment.app.DialogFragment
 import com.bumptech.glide.Glide
 import com.gyf.immersionbar.BarHide
@@ -14,6 +14,7 @@ import com.gyf.immersionbar.ktx.immersionBar
 import com.yingyangfly.baselib.ext.setOnSingleClickListener
 import com.yingyangfly.baselib.utils.ViewTool
 import com.yingyangfly.game.R
+import com.yingyangfly.game.widget.NumberAnimTextView
 
 /**
  * 训练完成弹窗
@@ -21,12 +22,12 @@ import com.yingyangfly.game.R
 class CompletionTrainingDialog : DialogFragment() {
 
     private var imageSettlement: AppCompatImageView? = null
-    private var tvTotalScore: AppCompatTextView? = null
-    private var tvGameLevelScore: AppCompatTextView? = null
+    private var tvTotalScore: NumberAnimTextView? = null
+    private var tvGameLevelScore: NumberAnimTextView? = null
     private var totalScore: String = ""
     private var curLevelScore: String = ""
     private var btnDetermine: AppCompatImageView? = null
-
+    private var content: Context? = null
     var onDialogClickListener: ((bean: String) -> Unit)? = null
 
     fun setData(totalScore: String, curLevelScore: String) {
@@ -61,6 +62,7 @@ class CompletionTrainingDialog : DialogFragment() {
         val rootView = ViewTool.inflateFragmentPixels(
             activity, R.layout.dialog_completion_training, container, 1194, 834
         )
+        content = activity
         findId(rootView)
         initData()
         initListener()
@@ -72,17 +74,20 @@ class CompletionTrainingDialog : DialogFragment() {
         tvTotalScore = rootView.findViewById(R.id.tvTotalScore)
         tvGameLevelScore = rootView.findViewById(R.id.tvGameLevelScore)
         btnDetermine = rootView.findViewById(R.id.btnDetermine)
-
-        Glide.with(requireActivity())
-            .asGif()
-            .load(R.drawable.diban)
-            .into(imageSettlement!!)
+        if (content != null) {
+            Glide.with(content!!)
+                .asGif()
+                .load(R.drawable.diban)
+                .into(imageSettlement!!)
+        }
     }
 
     @SuppressLint("SetTextI18n")
     private fun initData() {
-        tvTotalScore?.text = "累计得分:" + totalScore + "分"
-        tvGameLevelScore?.text = "本关得分:" + curLevelScore + "分"
+        tvTotalScore?.setEnableAnim(true)
+        tvTotalScore?.setNumberString(totalScore)
+        tvGameLevelScore?.setEnableAnim(true)
+        tvGameLevelScore?.setNumberString(curLevelScore)
     }
 
     private fun initListener() {

+ 200 - 0
game/src/main/java/com/yingyangfly/game/widget/NumberAnimTextView.java

@@ -0,0 +1,200 @@
+package com.yingyangfly.game.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);
+    }
+
+    @SuppressLint("SetTextI18n")
+    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;
+    }
+
+    @SuppressLint("SetTextI18n")
+    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(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);
+        }
+    }
+}

+ 72 - 15
game/src/main/res/layout/dialog_completion_training.xml

@@ -24,33 +24,90 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent">
 
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/tvTotalScore"
+            <LinearLayout
+                android:id="@+id/totalScoreLayout"
                 android:layout_width="@dimen/divider_190px"
                 android:layout_height="@dimen/divider_58px"
                 android:layout_marginTop="@dimen/divider_311px"
-                android:fontFamily="@font/lcb"
                 android:gravity="center"
-                android:includeFontPadding="false"
-                android:textColor="@android:color/white"
-                android:textSize="@dimen/divider_28px"
+                android:orientation="horizontal"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toTopOf="parent" />
+                app:layout_constraintTop_toTopOf="parent">
 
-            <androidx.appcompat.widget.AppCompatTextView
-                android:id="@+id/tvGameLevelScore"
+                <androidx.appcompat.widget.AppCompatTextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/lcb"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:text="@string/cumulative_score"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/divider_28px" />
+
+                <com.yingyangfly.game.widget.NumberAnimTextView
+                    android:id="@+id/tvTotalScore"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/lcb"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/divider_28px" />
+
+                <androidx.appcompat.widget.AppCompatTextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/lcb"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:text="@string/scores"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/divider_28px" />
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:id="@+id/gameLevelScoreLayout"
                 android:layout_width="@dimen/divider_190px"
                 android:layout_height="@dimen/divider_58px"
                 android:layout_marginTop="@dimen/divider_8px"
-                android:fontFamily="@font/lcb"
                 android:gravity="center"
-                android:includeFontPadding="false"
-                android:textColor="@android:color/white"
-                android:textSize="@dimen/divider_28px"
+                android:orientation="horizontal"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@+id/tvTotalScore" />
+                app:layout_constraintTop_toBottomOf="@+id/totalScoreLayout">
+
+                <androidx.appcompat.widget.AppCompatTextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/lcb"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:text="@string/this_level_score"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/divider_28px" />
+
+                <com.yingyangfly.game.widget.NumberAnimTextView
+                    android:id="@+id/tvGameLevelScore"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/lcb"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/divider_28px" />
+
+                <androidx.appcompat.widget.AppCompatTextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:fontFamily="@font/lcb"
+                    android:gravity="center"
+                    android:includeFontPadding="false"
+                    android:text="@string/scores"
+                    android:textColor="@android:color/white"
+                    android:textSize="@dimen/divider_28px" />
+            </LinearLayout>
 
             <androidx.appcompat.widget.AppCompatImageView
                 android:id="@+id/btnDetermine"
@@ -62,7 +119,7 @@
                 android:scaleType="centerInside"
                 app:layout_constraintEnd_toEndOf="parent"
                 app:layout_constraintStart_toStartOf="parent"
-                app:layout_constraintTop_toBottomOf="@+id/tvGameLevelScore" />
+                app:layout_constraintTop_toBottomOf="@+id/gameLevelScoreLayout" />
 
         </androidx.constraintlayout.widget.ConstraintLayout>
 

+ 3 - 0
game/src/main/res/values/strings.xml

@@ -18,4 +18,7 @@
     <string name="game_score" tools:ignore="ResourceName">游戏得分</string>
     <string name="scale" tools:ignore="ResourceName">缩放</string>
     <string name="game_date" tools:ignore="ResourceName">时间</string>
+    <string name="cumulative_score" tools:ignore="ResourceName">累计得分:</string>
+    <string name="scores" tools:ignore="ResourceName">分</string>
+    <string name="this_level_score" tools:ignore="ResourceName">本关得分:</string>
 </resources>