6 次代碼提交 48754abcf8 ... fc9732a70a

作者 SHA1 備註 提交日期
  LAPTOP-K69FCNBP\crius fc9732a70a Merge branch 'master' of http://116.62.119.248:10082/cheng_zq/EffectDemo into lwz_ 2 年之前
  LAPTOP-K69FCNBP\crius fd0b655130 选择题重写 2 年之前
  czq f74abfc6cf 修改地图逻辑 2 年之前
  czq 6762062546 单词泛红控件修改完成;视频控件修改拖动逻辑 2 年之前
  czq 44d59860d3 Merge branch 'master' into czq 2 年之前
  czq e2710a8f89 单词泛红控件修改 2 年之前

+ 17 - 0
.idea/deploymentTargetDropDown.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="deploymentTargetDropDown">
+    <runningDeviceTargetSelectedWithDropDown>
+      <Target>
+        <type value="RUNNING_DEVICE_TARGET" />
+        <deviceKey>
+          <Key>
+            <type value="VIRTUAL_DEVICE_PATH" />
+            <value value="C:\Users\crius\.android\avd\Nexus_7_API_31.avd" />
+          </Key>
+        </deviceKey>
+      </Target>
+    </runningDeviceTargetSelectedWithDropDown>
+    <timeTargetWasSelectedWithDropDown value="2022-09-26T08:19:12.505635600Z" />
+  </component>
+</project>

+ 1 - 0
.idea/misc.xml

@@ -26,6 +26,7 @@
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_web.xml" value="0.1816123188405797" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/demo_activity.xml" value="0.18020833333333333" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/item_word_sound.xml" value="0.10190217391304347" />
+        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/drawable/drag_error_bg.xml" value="0.174" />
         <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_map_challenge.xml" value="0.36886005560704355" />
       </map>
     </option>

+ 18 - 0
app/src/main/java/com/xunao/effectdemo/Utils.java

@@ -5,6 +5,8 @@ package com.xunao.effectdemo;
  * @描述       工具类
  */
 
+import static com.blankj.utilcode.util.ScreenUtils.getScreenDensityDpi;
+
 import android.content.Context;
 import android.view.Display;
 import android.view.WindowManager;
@@ -18,4 +20,20 @@ public class Utils {
         int w = display.getWidth();
         return w;
     }
+
+    /**
+     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
+     */
+    public static int px2dip(Context context, float pxValue) {
+        final float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    /**
+     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
+     */
+    public static int dip2px(Context context, float dpValue) {
+        final float scale = context.getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
 }

+ 341 - 66
app/src/main/java/com/xunao/effectdemo/activity/DragActivity.java

@@ -1,20 +1,32 @@
 package com.xunao.effectdemo.activity;
 
+import static com.blankj.utilcode.util.ScreenUtils.getScreenHeight;
+import static com.blankj.utilcode.util.ScreenUtils.getScreenWidth;
+
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.core.content.res.ResourcesCompat;
 
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.app.Activity;
 import android.content.ClipData;
+import android.content.Context;
 import android.content.Intent;
+import android.graphics.Color;
 import android.os.Bundle;
 import android.os.SystemClock;
 import android.util.Log;
+import android.util.TypedValue;
 import android.view.DragEvent;
+import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
 import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
 import android.view.animation.TranslateAnimation;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -24,13 +36,46 @@ import android.widget.TextView;
 
 import com.xunao.effectdemo.R;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.Timer;
+import java.util.TimerTask;
+
 public class DragActivity extends Activity{
 
     private static final String RED = "RED";
 
+    RelativeLayout select_rl;
+    RelativeLayout rl_bg;
+    TextView tv_content;
+
+    //进行滑动的TextView
+    private TextView moveTextView;
+    List<String> selectList;
+    private int answerSize = 0;
+    private int halfAnswerSize = 0;
+    private int selectRootWidth = 0;
+    private int selectRootHeight = 0;
+    //选项位置的集合。初始的显示位置。用于后续拖动松手后,选项做回归动画
+    private List<String> selectInitialLocationList;
+    //分隔符
+    private String SeparateSymbol = "-";
+    //认为的最小滑动值。超过这个值,就认为是滑动;如果没有超过,就是认为是点击
+    private int reputeMixMoveValue = 10;
+    //按下时候的x,y坐标
+    private float downX = 0;
+    private float downY = 0;
+    //当前点击或者按住了哪个选项
+    private int currentOptionPosition = -1;
+    //移动、滑动时候,当前位置的x,y坐标
+    private float moveCurrentX;
+    private float moveCurrentY;
+
     private String selectedContent = "";
     private final String correctAnswer = "选项2";
     private int wrongNum = 0;
+    Timer timer = new Timer();
 
 
     @Override
@@ -38,74 +83,304 @@ public class DragActivity extends Activity{
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_drag);
 
-        TextView ll_red = findViewById(R.id.ll_red);
-        TextView tv1 = findViewById(R.id.tv_1);
-        TextView tv2 = findViewById(R.id.tv_2);
-
-        tv1.setOnLongClickListener(v -> {
-            selectedContent = tv1.getText().toString();
-//                Intent intent = new Intent();
-//                ClipData clipData = ClipData.newIntent("label", intent);
-            View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
-            v.startDrag(null, shadowBuilder, tv1, 0);
-            //震动反馈
-            v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
-            return true;
-        });
-
-        tv2.setOnLongClickListener(v -> {
-            selectedContent = tv2.getText().toString();
-//                Intent intent = new Intent();
-//                ClipData clipData = ClipData.newIntent("label", intent);
-            View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
-            v.startDrag(null, shadowBuilder, tv2, 0);
-            //震动反馈
-            v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
-            return true;
-        });
-
-        ll_red.setOnDragListener((v, event) -> {
-            String simpleName = v.getClass().getSimpleName();
-            Log.w(RED, "view name:" + simpleName);
-
-            int action = event.getAction();
-            switch (action) {
-                case DragEvent.ACTION_DRAG_STARTED:
-                    Log.i(RED, "开始拖拽");
-//                        tv1.setVisibility(View.INVISIBLE);
-                    break;
-                case DragEvent.ACTION_DRAG_ENDED:
-                    Log.i(RED, "结束拖拽");
-//                        tv1.setVisibility(View.VISIBLE);
-                    break;
-                case DragEvent.ACTION_DRAG_ENTERED:
-                    Log.i(RED, "拖拽的view进入监听的view时");
-                    break;
-                case DragEvent.ACTION_DRAG_EXITED:
-                    Log.i(RED, "拖拽的view离开监听的view时");
-                    break;
-                case DragEvent.ACTION_DRAG_LOCATION:
-                    float x = event.getX();
-                    float y = event.getY();
-                    Log.i(RED, "拖拽的view在RED中的位置:x =" + x + ",y=" + y);
-                    break;
-                case DragEvent.ACTION_DROP:
-                    if(correctAnswer.equals(selectedContent)){
-                        Log.i(RED, "释放拖拽的view");
-                        TextView localState = (TextView) event.getLocalState();
-                        ((ViewGroup) localState.getParent()).removeView(localState);
-                        ll_red.setText(selectedContent);
-                        ll_red.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_success_bg,null));
-                    }else{
-                        wrongNum = wrongNum + 1;
-                        if(wrongNum >= 2){
-                            tv2.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_hint_bg,null));
-                        }
+        tv_content = findViewById(R.id.tv_content);
+        select_rl = findViewById(R.id.select_rl);
+        rl_bg = findViewById(R.id.rl_bg);
+        initData();
+    }
+
+    void initData(){
+        selectInitialLocationList = new ArrayList<>();
+        // 选项集合
+        List<String> selectList = new ArrayList<>();
+        selectList.add("选项1");
+        selectList.add("选项2");
+        selectList.add("选项3");
+        this.selectList = selectList;
+
+        answerSize = dp2px(50);
+        halfAnswerSize = answerSize / 2;
+
+        ViewTreeObserver.OnGlobalLayoutListener listener = new ViewTreeObserver.OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+
+                View view = new View(DragActivity.this);
+                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+                params.width = getScreenWidth()/2;
+                params.height = getScreenHeight();
+                view.setLayoutParams(params);
+                view.setBackgroundColor(getResources().getColor(R.color.textGrayColor));
+                rl_bg.addView(view);
+
+                select_rl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+
+                handleSelect();
+
+            }
+        };
+        select_rl.getViewTreeObserver().addOnGlobalLayoutListener(listener);
+    }
+
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+       switch (event.getAction()){
+           case MotionEvent.ACTION_DOWN:
+               if (moveTextView != null) {
+                   break;
+               }
+               currentOptionPosition = -1;
+               downX = event.getX();
+               downY = event.getY();
+               //指定当前滑动的TextView
+               for (int i = 0; i < selectInitialLocationList.size(); i++) {
+
+                   float x1 = Float.parseFloat(selectInitialLocationList.get(i).split(SeparateSymbol)[0]);
+                   float x2 = x1 + answerSize*4;
+
+                   float y1 = Float.parseFloat(selectInitialLocationList.get(i).split(SeparateSymbol)[1]);
+                   float y2 = y1 + answerSize;
+
+                   //x1、y1,是选项左上角的坐标。x2、y2,是选项右下角的坐标
+
+                   if (downX > x1 && downX < x2 && downY > y1 && downY < y2) {
+                       if(select_rl.getChildAt(i).getVisibility() == View.VISIBLE){
+                           //拿到当前选择的这个选项的view
+                           moveTextView = (TextView) select_rl.getChildAt(i);
+                           //记下现在选的,是第几个选项
+                           currentOptionPosition = i;
+                           Log.e("按下", currentOptionPosition + "");
+                           break;
+                       }
+                   }
+               }
+               break;
+           case MotionEvent.ACTION_MOVE:
+               if (moveTextView == null) {
+                   return false;
+               }
+               moveCurrentX = event.getX();
+               moveCurrentY = event.getY();
+
+               if (Math.abs(moveCurrentX - downX) > reputeMixMoveValue && Math.abs(moveCurrentY - downY) > reputeMixMoveValue) {
+
+                   //这里,按下的坐标,要减去选项的一半,让选项的中间,跟着手指动。否则,就是选项的左上角,跟着手指移动,不美观
+
+                   moveTextView.setX(moveCurrentX - halfAnswerSize);
+                   moveTextView.setY(moveCurrentY - halfAnswerSize);
+               }
+               break;
+           case MotionEvent.ACTION_UP:
+           case MotionEvent.ACTION_CANCEL:
+               if (moveTextView == null) {
+                   return false;
+               }
+               // 当移动到答案框内时
+                if(moveCurrentX > tv_content.getX() && moveCurrentX < tv_content.getX() + tv_content.getWidth() &&
+                    moveCurrentY >tv_content.getY() && moveCurrentY < tv_content.getY() + tv_content.getHeight()){
+                    // 正确答案
+                    if(selectList.get(currentOptionPosition).equals(correctAnswer)){
+                        tv_content.setText(selectList.get(currentOptionPosition));
+                        tv_content.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_success_bg, null));
+                        moveTextView = null;
+                        select_rl.getChildAt(currentOptionPosition).setVisibility(View.INVISIBLE);
+                    }else{  // 错误答案
+                        // 先抖一抖再回去
+                        wrongAnimator();
                     }
-                    break;
+                }else {
+                    //说明没有放到答案框,就做回归动画
+                    moveAnimator(0, 0, 0, 0, 0, -1);
+                }
+               break;
+           default:
+               break;
+       }
+       return true;
+    }
+
+    //处理选项。计算选项,摆放选项的位置
+    private void handleSelect() {
+
+        selectRootWidth = select_rl.getWidth();
+        selectRootHeight = select_rl.getHeight();
+
+        //移除之前的子控件(避免数据造成冲突)
+        select_rl.removeAllViews();
+
+        float x = 0;
+        float y = 0;
+
+        for (int i = 0; i < selectList.size(); i++) {
+
+            String option = selectList.get(i);
+
+            TextView tvAnswer = createSelectTv(option);
+
+            x = getScreenWidth()*3/5;
+            y = getScreenHeight()/4 + dp2px(80) * i;
+
+            //这里的setX、setY,是指选项(正方形)左上角的坐标位置
+            tvAnswer.setX(x);
+            tvAnswer.setY(y);
+
+            //保存这个选项的坐标位置
+            selectInitialLocationList.add(x + SeparateSymbol + y);
+
+            select_rl.addView(tvAnswer);
+        }
+
+    }
+
+    /**
+     * 创建选项TextView
+     *
+     * @param str textView上要展示的内容
+     * @return
+     */
+    private TextView createSelectTv(String str) {
+
+        TextView tv = new TextView(this);
+
+        tv.setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_default_bg,null));
+
+        tv.setText(str);
+
+        tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
+
+        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
+                ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        params.width = answerSize*4;
+        params.height = answerSize;
+        tv.setLayoutParams(params);
+        tv.setGravity(Gravity.CENTER);
+
+        return tv;
+    }
+
+    // 抖一抖动画
+    private void wrongAnimator(){
+        wrongNum = wrongNum + 1;
+        Animation anim = AnimationUtils.loadAnimation(DragActivity.this, R.anim.myanim);
+        tv_content.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.drag_error_bg, null));
+        tv_content.setText(selectList.get(currentOptionPosition));
+        tv_content.startAnimation(anim);
+        moveTextView.setVisibility(View.GONE);
+        //抖完后回去
+        timer.schedule(new TimerTask() {
+            @Override
+            public void run() {
+                runOnUiThread(() -> {
+                    tv_content.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.drag_default_bg, null));
+                    tv_content.setText("");
+                    moveAnimator(0, 0, 0, 0, 0, -1);
+                });
             }
-            return true;
-        });
+        }, 1200);
+    }
+
+    /**
+     * 回归动画
+     * type:
+     * 0、没有拖动到空格处,松开手后控件回到初始位置
+     * 1、拖动到空格处,松开手后,隐藏控件,静默回归
+     * 2、点击选项,控件移动到空缺的位置
+     * 3、点击选项,内容填充到空格处后,控件需要静默回归
+     */
+    private void moveAnimator(final int type, float sX, float sY, float eX, float eY, final int position) {
+
+        Log.e("type is ", type + "");
+        Log.e("currentOptionPosition ", currentOptionPosition + "");
+
+        if (currentOptionPosition == -1 || moveTextView == null) {
+            return;
+        }
+            moveTextView.setVisibility(View.VISIBLE);
+
+        try {
+
+            float startX = 0;
+            float startY = 0;
+            float endX = 0;
+            float endY = 0;
+
+            AnimatorSet animatorSet = new AnimatorSet();
+            ObjectAnimator translationX;
+            ObjectAnimator translationY;
+
+            String location = selectInitialLocationList.get(currentOptionPosition);
+            startX = moveTextView.getX();
+            startY = moveTextView.getY();
+
+            endX = Float.parseFloat(location.split(SeparateSymbol)[0]);
+            endY = Float.parseFloat(location.split(SeparateSymbol)[1]);
+
+            translationX = ObjectAnimator.ofFloat(
+                    moveTextView,
+                    "translationX",
+                    startX,
+                    endX
+            );
+
+            translationY = ObjectAnimator.ofFloat(
+                    moveTextView,
+                    "translationY",
+                    startY,
+                    endY
+            );
+
+            animatorSet.playTogether(translationX, translationY);
+
+            long durationTime = 1000;
+
+            animatorSet.setDuration(durationTime);
+
+            animatorSet.addListener(new Animator.AnimatorListener() {
+                @Override
+                public void onAnimationStart(Animator animator) {
+
+
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animator) {
+
+                        //抬起手后,释放滑动的TextView
+                        moveTextView = null;
+                        currentOptionPosition = -1;
+                        if(wrongNum > 2){
+                            for(int i = 0; i < select_rl.getChildCount(); i ++){
+                                if(((TextView) select_rl.getChildAt(i)).getText().equals(correctAnswer)){
+                                    ((TextView) select_rl.getChildAt(i)).setBackground(ResourcesCompat.getDrawable(getResources(),R.drawable.drag_hint_bg,null));
+                                }
+                            }
+                        }
+
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animator) {
+
+                }
+
+                @Override
+                public void onAnimationRepeat(Animator animator) {
+
+                }
+            });
+
+            animatorSet.start();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
 
+    private int dp2px(float dpValue) {
+        final float scale = getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
     }
 }

+ 11 - 7
app/src/main/java/com/xunao/effectdemo/activity/MapChallengeActivity.java

@@ -1,11 +1,11 @@
 package com.xunao.effectdemo.activity;
 
-import static com.blankj.utilcode.util.ScreenUtils.getScreenHeight;
-import static com.blankj.utilcode.util.ScreenUtils.getScreenWidth;
+import static com.blankj.utilcode.util.ScreenUtils.*;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.HorizontalScrollView;
@@ -30,6 +30,7 @@ import java.util.Map;
  * 地图闯关
  */
 public class MapChallengeActivity extends Activity {
+    private static final String TAG = "MapChallengeActivity";
     Button btnMap1, btnMap2, btnMap3, btnMap4, btnMap5, btnMap6;
 
     Intent intent;
@@ -58,8 +59,9 @@ public class MapChallengeActivity extends Activity {
     void initData(){
         getMap();
     }
-
+    private float scale = 0f;
     void initView(){
+        scale = (float) (getAppScreenHeight ()/1024.00);
         llMapBg = findViewById(R.id.ll_map_bg);
         rlMapBg = findViewById(R.id.rl_map_bg);
         btnMap1 = findViewById(R.id.btn_map_1);
@@ -122,10 +124,12 @@ public class MapChallengeActivity extends Activity {
                 .format(DecodeFormat.PREFER_RGB_565)
                 .into(child);
         child.setScaleType(ImageView.ScaleType.FIT_XY);
-        child.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,getScreenHeight()));
+        child.setLayoutParams(new ViewGroup.LayoutParams(getAppScreenHeight (),getAppScreenHeight ()));
         llMapBg.addView(child);
+        Log.i(TAG, getScreenHeight() + "---" + getScreenWidth());
     }
 
+
     private void addSmallBg(String url, double x, double y){
         ImageView child = new ImageView(this);
 //        Glide.with(this).asBitmap().load(url).into(new BitmapImageViewTarget(child){
@@ -140,9 +144,9 @@ public class MapChallengeActivity extends Activity {
                 .format(DecodeFormat.PREFER_RGB_565)
                 .into(child);
         child.setScaleType(ImageView.ScaleType.FIT_XY);
-        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(360,300);
-        layoutParams.leftMargin = (int)(x * getScreenWidth()*11);
-        layoutParams.topMargin = (int)(y * getScreenHeight());
+        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams((int) (scale*376), (int) (scale*306));
+        layoutParams.leftMargin = (int)(x * getAppScreenHeight ()*bkg_images.size());
+        layoutParams.topMargin = (int)(y * getAppScreenHeight ());
         child.setLayoutParams(layoutParams);
         rlMapBg.addView(child);
     }

+ 22 - 10
app/src/main/java/com/xunao/effectdemo/activity/NewSongLyricActivity.java

@@ -123,7 +123,11 @@ public class NewSongLyricActivity extends Activity {
 				setWord(wordList);
 
 				mediaPlayer.setOnPreparedListener(mp -> Log.i(TAG,"onPrepared:准备完成"));
-				mediaPlayer.setOnCompletionListener(mp -> Log.i(TAG,"OnCompletion:播放完成"));
+				mediaPlayer.setOnCompletionListener(mp -> {
+					textView.release();
+					handler.removeCallbacks(runnable);
+					playFinish();
+				});
 				try {
 					mediaPlayer.setDataSource(mediaBean.getResult().getList().getSteps_mp3url());
 					mediaPlayer.prepareAsync();// 开始在后台缓冲音频文件并返回
@@ -180,15 +184,7 @@ public class NewSongLyricActivity extends Activity {
 						if (num==beanList.size()){
 							num = 0;
 						}
-						if (timeBean.getTime()+timeBean.getStartTime()+canTime == timeBean.getEndTime()){
-							canTime =0;
-							normal = startIndex;
 
-						}else{
-							if (canTime==0){
-							}
-							canTime +=timeBean.getTime();
-						}
 
 						textView.startPlayLine(
 								startIndex,
@@ -196,7 +192,15 @@ public class NewSongLyricActivity extends Activity {
 								normal,1);
 						startIndex += timeBean.getWord().length();
 
-
+						if (timeBean.getTime()+timeBean.getStartTime()+canTime == timeBean.getEndTime()){
+							canTime =0;
+							normal = startIndex ;
+							Log.e("MyTag","结束标志:"+normal);
+						}else{
+							if (canTime==0){
+							}
+							canTime +=timeBean.getTime();
+						}
 						timeBean = beanList.get(num);
 					}
 					break;
@@ -211,6 +215,14 @@ public class NewSongLyricActivity extends Activity {
 		handler.post(runnable);
 	}
 
+	private void playFinish(){
+		time = 0;
+		startIndex = 0;
+		num = 0;
+		canTime = 0;
+		normal = 0;
+	}
+
 
 	Timer timer;
 	int time = 0;

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

@@ -35,7 +35,7 @@ public class RolePlayActivity extends Activity {
 
     private int currentTotal = 0;
 
-    private static final int DEFAULT_SPEED = 150; //默认/最慢速度
+    private static final int DEFAULT_SPEED = 300; //默认/最慢速度
     private static final int MIN_SPEED = 50;//最快速度
     private int currentSpeed = DEFAULT_SPEED;//当前速度
 
@@ -118,7 +118,7 @@ public class RolePlayActivity extends Activity {
             public void run() {
                 tryToStop();
             }
-        }, 2000);
+        }, 5000);
     }
 
     //改变加速状态
@@ -137,7 +137,7 @@ public class RolePlayActivity extends Activity {
         } else {//增速直至最快速度
             //第一圈不做加速
             if (currentTotal / roleList.size() > 0) {
-                currentSpeed -= 10;
+                currentSpeed -= 20;
             }
             if (currentSpeed < MIN_SPEED) {
                 currentSpeed = MIN_SPEED;

+ 29 - 10
app/src/main/java/com/xunao/effectdemo/view/SongLyricTextView.kt

@@ -6,6 +6,7 @@ import android.graphics.Canvas
 import android.graphics.Color
 import android.graphics.Path
 import android.util.AttributeSet
+import android.util.Log
 import android.view.animation.LinearInterpolator
 
 /**
@@ -34,6 +35,8 @@ class SongLyricTextView @JvmOverloads constructor(
      * */
     private var consumeWidth: Float = 0f
 
+    private var normalWidth:Float = 0f;
+
     /**
      * 是否正在播放中
      * */
@@ -56,6 +59,7 @@ class SongLyricTextView @JvmOverloads constructor(
         animator.interpolator = LinearInterpolator()
         animator.addUpdateListener {
             consumeWidth = it.animatedValue as Float
+            normalWidth = oldStartWidth
             invalidate()
         }
         animator
@@ -74,27 +78,32 @@ class SongLyricTextView @JvmOverloads constructor(
             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) {
+                if (lineWidth < consumeWidth) {
                     // 如果是之前已经变色区域,直接添加到path中
+                    if (normalWidth<lineWidth&&normalWidth>0){
+                        path.addRect(
+                            layout.getLineLeft(i)+normalWidth,
+                            layout.getLineTop(i).toFloat(),
+                            layout.getLineRight(i),
+                            layout.getLineBottom(i).toFloat(),
+                            Path.Direction.CCW
+                        )
+                        normalWidth = 0f;
+                    }
                     consumeWidth -= lineWidth
-//                    path.addRect(
-//                        layout.getLineLeft(i),
-//                        layout.getLineTop(i).toFloat(),
-//                        layout.getLineRight(i),
-//                        layout.getLineBottom(i).toFloat(),
-//                        Path.Direction.CCW
-//                    )
+                    if (normalWidth>0f)normalWidth -= lineWidth
+//                    if(oldStartWidth<0f) oldStartWidth = 0f
                 } else {
                     // 如果该行正好是要变色的行,直接改变颜色
                     // 把需要的consumeWidth放入path中
                     path.addRect(
-                        layout.getLineLeft(i),
+                        layout.getLineLeft(i)+normalWidth,
                         layout.getLineTop(i).toFloat(),
                         layout.getLineLeft(i) + consumeWidth,
                         layout.getLineBottom(i).toFloat(),
@@ -201,4 +210,14 @@ class SongLyricTextView @JvmOverloads constructor(
 //        invalidate()
     }
 
+    /**
+     * 重置
+     */
+    fun release(){
+        isPlaying = false
+        isNormal = false
+        animator.cancel()
+        invalidate()
+    }
+
 }

+ 2 - 2
app/src/main/java/com/xunao/effectdemo/view/VideoPreviewPlay.java

@@ -183,9 +183,9 @@ public class VideoPreviewPlay extends StandardGSYVideoPlayer {
 		mProgressBar.setOnTouchListener(new OnTouchListener() {
 			@Override
 			public boolean onTouch(View view, MotionEvent motionEvent) {
-				if(isFinish){
+				if(!isFinish){
 					soundPoolUtil.playSoundWithRedId(R.raw.buyao);
-					Toast toast = Toast.makeText(context,"触摸事件",Toast.LENGTH_SHORT);
+					Toast toast = Toast.makeText(context,"禁止拖动",Toast.LENGTH_SHORT);
 					toast.setGravity(Gravity.TOP,0,0);
 					toast.show();
 					return true;

+ 32 - 0
app/src/main/res/anim/myanim.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:interpolator="@anim/cycle" >
+
+    <translate
+        android:duration="300"
+        android:fromXDelta="0"
+        android:fromYDelta="0"
+        android:toXDelta="-10"
+        android:toYDelta="-10" />
+    <translate
+        android:duration="300"
+        android:fromXDelta="0"
+        android:fromYDelta="0"
+        android:startOffset="300"
+        android:toXDelta="10"
+        android:toYDelta="-10" />
+    <translate
+        android:duration="300"
+        android:fromXDelta="0"
+        android:fromYDelta="0"
+        android:startOffset="600"
+        android:toXDelta="-10"
+        android:toYDelta="10" />
+    <translate
+        android:duration="300"
+        android:fromXDelta="0"
+        android:fromYDelta="0"
+        android:startOffset="900"
+        android:toXDelta="10"
+        android:toYDelta="10" />
+</set>

+ 6 - 0
app/src/main/res/drawable/drag_error_bg.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="@color/colorWhite" />
+    <stroke android:width="1dp" android:color="@color/qmui_config_color_red"/>
+    <corners android:radius="4dp" />
+</shape>

+ 22 - 39
app/src/main/res/layout/activity_drag.xml

@@ -1,46 +1,29 @@
 <?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"
-    xmlns:tools="http://schemas.android.com/tools"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:gravity="center"
-        android:background="@color/textGrayColor"
-        android:layout_weight="1">
-        <TextView
-            android:id="@+id/ll_red"
-            android:layout_width="200dp"
-            android:layout_height="40dp"
-            android:gravity="center"
-            android:background="@drawable/drag_default_bg"/>
-    </LinearLayout>
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+    <RelativeLayout
+        android:id="@+id/rl_bg"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
 
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
+    <TextView
+        android:id="@+id/tv_content"
+        android:layout_width="200dp"
+        android:layout_height="50dp"
+        android:layout_margin="15dp"
+        android:layout_centerVertical="true"
         android:gravity="center"
-        android:orientation="vertical"
-        android:layout_weight="1">
+        android:background="@drawable/drag_default_bg"
+        android:textSize="30dp" />
 
-        <TextView
-            android:id="@+id/tv_1"
-            android:layout_width="200dp"
-            android:layout_height="40dp"
-            android:gravity="center"
-            android:background="@drawable/drag_default_bg"
-            android:layout_marginBottom="20dp"
-            android:text="选项1"/>
+    <!--展示选项的区域-->
+    <RelativeLayout
+        android:id="@+id/select_rl"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
 
-        <TextView
-            android:id="@+id/tv_2"
-            android:layout_width="200dp"
-            android:layout_height="40dp"
-            android:gravity="center"
-            android:background="@drawable/drag_default_bg"
-            android:text="选项2"/>
+    </RelativeLayout>
 
-    </LinearLayout>
-</LinearLayout>
+</RelativeLayout>

+ 2 - 1
app/src/main/res/layout/activity_songe.xml

@@ -41,10 +41,11 @@
         android:id="@+id/end"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="结束播放" />
+        android:text="暂停播放" />
 
     <Button
         android:id="@+id/test"
+        android:visibility="gone"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:text="测试数据" />