Browse Source

Merge branch 'master' of http://116.62.119.248:10082/cheng_zq/EffectDemo into lwz_

LAPTOP-K69FCNBP\crius 2 years ago
parent
commit
2d39d36a71

+ 1 - 0
.idea/misc.xml

@@ -13,6 +13,7 @@
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_progress.xml" value="0.22" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_quxian.xml" value="0.13645833333333332" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_sequential_drag.xml" value="0.12092391304347826" />
+        <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_songe.xml" value="0.20364583333333333" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_sound.xml" value="0.1234375" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_spine.xml" value="0.13333333333333333" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_stars.xml" value="0.12" />

+ 1 - 0
app/src/main/AndroidManifest.xml

@@ -106,6 +106,7 @@
             android:screenOrientation="landscape" />
         <activity android:name=".yzs.YZSConfigActivity"/>
         <activity android:name=".yzs.YZSDemoActivity"/>
+        <activity android:name=".activity.SongLyricActivity"/>
 
     </application>
 

+ 6 - 1
app/src/main/java/com/xunao/effectdemo/activity/MainActivity.java

@@ -25,7 +25,7 @@ public class MainActivity extends Activity {
 
 	Button btn1,btn2,btn3,btn4,btn5,btn6,btn7,btn8,
 			btn9,btn10,btn11,btn12,btn13, btn14,btn15,btn16,
-			btn17;
+			btn17,btn18;
 	Intent intent;
 
 	@Override
@@ -131,5 +131,10 @@ public class MainActivity extends Activity {
 			intent = new Intent(MainActivity.this, YZSDemoActivity.class);
 			startActivity(intent);
 		});
+		btn18 = findViewById(R.id.btn_18);
+		btn18.setOnClickListener(v->{
+			intent = new Intent(MainActivity.this, SongLyricActivity.class);
+			startActivity(intent);
+		});
 	}
 }

+ 3 - 2
app/src/main/java/com/xunao/effectdemo/activity/QuxianActivity.java

@@ -125,10 +125,11 @@ public class QuxianActivity extends Activity {
 				// 离的坐标点和切线,pos会自动填充上坐标,这个方法很重要。
 				mPathMeasure.getPosTan(value, mCurrentPosition, null);//mCurrentPosition此时就是中间距离点的坐标值
 				Log.e("MyTag","获取坐标:"+mCurrentPosition[0]);
-				// 移动的商品图片(动画图片)的坐标设置为该中间点的坐标
+
 				view2.setTranslationX(mCurrentPosition[0]);
 				view2.setTranslationY(mCurrentPosition[1]);
-				view2.setRotation((float) ((500-mCurrentPosition[1])/580)*360);
+				// 此处为设置旋转的代码
+//				view2.setRotation((float) ((500-mCurrentPosition[1])/580)*360);
 
 
 			}

+ 70 - 0
app/src/main/java/com/xunao/effectdemo/activity/SongLyricActivity.kt

@@ -0,0 +1,70 @@
+package com.xunao.effectdemo.activity
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import com.xunao.effectdemo.R
+import kotlinx.android.synthetic.main.activity_songe.*
+import kotlin.math.min
+
+/**
+ * author : 程中强
+ * e-mail : 740479946@qq.com
+ * date : 2022/9/613:50
+ * desc :
+ * version: 1.0
+ */
+class SongLyricActivity : AppCompatActivity() {
+
+    private val lyric = "你发如雪\n" +
+            "凄美了离别\n" +
+            "我焚香感动了谁\n" +
+            "邀明月让回忆皎洁\n" +
+            "爱在月光下完美\n" +
+            "你发如雪\n" +
+            "纷飞了眼泪\n" +
+            "我等待苍老了谁\n" +
+            "红尘醉微醺的岁月\n" +
+            "我用无悔\n" +
+            "刻永世爱你的碑"
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_songe)
+
+        // 设置歌词
+        text.text = lyric
+
+        start.setOnClickListener {
+            val lyricList = lyric.split("\n")
+            var startIndex = 0
+            var delayTime = 0L
+//            text.startPlayLine(
+//                0,
+//                lyric.length,
+//                5000
+//            )
+            lyricList.forEach {
+                val startIndexTemp = startIndex
+                val duration = (1500 + Math.random() * 500).toLong()
+                text.postDelayed(
+                    {
+                        text.startPlayLine(
+                            startIndexTemp,
+                            min(lyric.length, startIndexTemp + it.length + 1), // 因为有个换行符,所以 + 1
+                            duration
+                        )
+                    },
+                    delayTime
+                )
+                delayTime += duration + 50
+                startIndex += it.length + 1
+            }
+        }
+
+        end.setOnClickListener {
+            text.stopPlay()
+        }
+
+
+    }
+}

+ 137 - 0
app/src/main/java/com/xunao/effectdemo/view/SongLyricTextView.kt

@@ -0,0 +1,137 @@
+package com.xunao.effectdemo.view
+
+import android.animation.ValueAnimator
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Path
+import android.util.AttributeSet
+import android.view.animation.LinearInterpolator
+
+/**
+ * author : 程中强
+ * e-mail : 740479946@qq.com
+ * date : 2022/9/613:46
+ * desc : 歌词变色textview
+ * version: 1.0
+ */
+class SongLyricTextView @JvmOverloads constructor(
+    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
+) : androidx.appcompat.widget.AppCompatTextView(context, attrs, defStyleAttr) {
+
+    /**
+     * 文字为播放的颜色
+     * */
+    private val normalColor = Color.parseColor("#333333")
+
+    /**
+     * 文字播放的颜色
+     * */
+    private val playColor = Color.parseColor("#fec403")
+
+    /**
+     * 要变色的宽度
+     * */
+    private var consumeWidth: Float = 0f
+
+    /**
+     * 是否正在播放中
+     * */
+    private var isPlaying = false
+
+    private val mPaint = paint
+
+    /**
+     * 要变色的区域
+     * */
+    private val path = Path()
+
+    /**
+     * 负责变色动画类
+     * */
+    private val animator by lazy {
+        val animator = ValueAnimator.ofFloat(0f, 1f)
+        animator.interpolator = LinearInterpolator()
+        animator.addUpdateListener {
+            consumeWidth = it.animatedValue as Float
+            invalidate()
+        }
+        animator
+    }
+
+    override fun onDraw(canvas: Canvas) {
+        mPaint.color = normalColor
+        super.onDraw(canvas)
+
+        if (layout == null) {
+            invalidate()
+            return
+        }
+        // 是否是播放状态
+        if (isPlaying) {
+            path.reset()
+            val lineCount = layout.lineCount
+            val content = text.toString()
+            for (i in 0 until lineCount) {
+                // 计算一行文字的宽度
+                val lineWidth = mPaint.measureText(
+                    content.substring(layout.getLineStart(i), layout.getLineEnd(i))
+                )
+
+                if (lineWidth <= consumeWidth) {
+                    // 如果是之前已经变色区域,直接添加到path中
+                    consumeWidth -= lineWidth
+                    path.addRect(
+                        layout.getLineLeft(i),
+                        layout.getLineTop(i).toFloat(),
+                        layout.getLineRight(i),
+                        layout.getLineBottom(i).toFloat(),
+                        Path.Direction.CCW
+                    )
+                } else {
+                    // 如果该行正好是要变色的行,直接改变颜色
+                    // 把需要的consumeWidth放入path中
+                    path.addRect(
+                        layout.getLineLeft(i),
+                        layout.getLineTop(i).toFloat(),
+                        layout.getLineLeft(i) + consumeWidth,
+                        layout.getLineBottom(i).toFloat(),
+                        Path.Direction.CCW
+                    )
+                    break
+                }
+            }
+            // 设置需要绘制的区域,并着色
+            canvas.clipPath(path)
+            mPaint.color = playColor
+            layout.draw(canvas)
+        }
+    }
+
+    /**
+     * 开始播放
+     *
+     * @param startIndex 开始的文字的索引
+     * @param endIndex 结束的文字的索引
+     * @param duration 播放时长
+     * */
+    fun startPlayLine(startIndex: Int, endIndex: Int, duration: Long) {
+        isPlaying = true
+        if (startIndex == -1) return
+        val startWidth = mPaint.measureText(this.text.substring(0, startIndex))
+        val endWidth = startWidth + mPaint.measureText(this.text.substring(startIndex, endIndex))
+        animator.setFloatValues(startWidth, endWidth)
+        animator.duration = if (duration > 0) duration else 1000
+        animator.start()
+    }
+
+    /**
+     * 停止播放
+     * */
+    fun stopPlay() {
+        isPlaying = false
+        animator.cancel()
+        invalidate()
+    }
+
+}

+ 5 - 0
app/src/main/res/layout/activity_main.xml

@@ -108,6 +108,11 @@
             android:text="云知声"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>
+        <Button
+            android:id="@+id/btn_18"
+            android:text="单词泛红"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"/>
     </LinearLayout>
 
 </ScrollView>

+ 33 - 0
app/src/main/res/layout/activity_songe.xml

@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.xunao.effectdemo.view.SongLyricTextView
+        android:id="@+id/text"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:lineSpacingExtra="6dp"
+        android:text="Hello World!"
+        android:textSize="16sp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <Button
+        android:id="@+id/start"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="开始播放" />
+
+    <Button
+        android:id="@+id/end"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:text="结束播放" />
+
+</LinearLayout>