From 57fe689f1862ad0fda96b2e9eb054be6a7c9425d Mon Sep 17 00:00:00 2001
From: Runt <qingingrunt2010@qq.com>
Date: Wed, 04 May 2022 12:53:14 +0000
Subject: [PATCH] 歌词显示时间控制

---
 app/src/main/res/values/themes.xml                                         |   10 
 app/src/main/java/com/auto/lyric/base/activities/BaseTitleBarActivity.java |    3 
 app/src/main/java/com/auto/lyric/data/SendText.java                        |   14 +
 app/src/main/java/com/auto/lyric/data/TextBean.java                        |   14 +
 app/src/main/java/com/auto/lyric/service/FloatingWindowService.java        |  156 ++++++++++-
 app/src/main/java/com/auto/lyric/base/activities/BaseActivity.java         |   13 -
 app/src/main/java/com/auto/lyric/MainActivity.java                         |   77 +++--
 app/src/main/java/com/auto/lyric/data/LyricObject.java                     |   11 
 app/src/main/res/layout/float_view.xml                                     |   23 +
 app/src/main/res/layout/activity_main.xml                                  |    1 
 app/src/main/java/com/auto/lyric/data/LyricServer.java                     |  143 +++++++++++
 app/src/main/java/com/auto/lyric/widgets/Sentence.java                     |    5 
 app/src/main/java/com/auto/lyric/widgets/LyricView.java                    |  310 ++++++++++++++---------
 13 files changed, 584 insertions(+), 196 deletions(-)

diff --git a/app/src/main/java/com/auto/lyric/MainActivity.java b/app/src/main/java/com/auto/lyric/MainActivity.java
index 462bbc8..121b6f9 100644
--- a/app/src/main/java/com/auto/lyric/MainActivity.java
+++ b/app/src/main/java/com/auto/lyric/MainActivity.java
@@ -1,27 +1,26 @@
 package com.auto.lyric;
 
 import android.content.Intent;
-import android.graphics.PixelFormat;
 import android.net.Uri;
 import android.os.Build;
-import android.os.Handler;
-import android.os.Message;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.WindowManager;
-
-import androidx.annotation.NonNull;
+import android.widget.Toast;
 
 import com.auto.lyric.base.activities.BaseActivity;
+import com.auto.lyric.data.LyricServer;
+import com.auto.lyric.data.TextBean;
 import com.auto.lyric.databinding.ActivityMainBinding;
-import com.auto.lyric.databinding.FloatViewBinding;
 import com.auto.lyric.service.AutoInputService;
 import com.auto.lyric.service.FloatingWindowService;
 import com.auto.lyric.vm.MainViewModel;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.regex.Pattern;
 
 public class MainActivity extends BaseActivity<ActivityMainBinding, MainViewModel> {
 
@@ -33,10 +32,38 @@
         Intent floatService  = new Intent(getApplicationContext(), FloatingWindowService.class);
         binding.button.setOnClickListener(v -> {
 
+            if(binding.edit.getText().toString().trim().length() == 0){
+                Toast.makeText(this,"请输入文本", Toast.LENGTH_SHORT).show();
+                return;
+            }
+            ArrayList<TextBean> arrayList = new ArrayList<>();//解析的文本数据
+            SimpleDateFormat msFormat = new SimpleDateFormat("mm:ss.SSS");
+            String[] strings = binding.edit.getText().toString().split("\n");
+            for(String text : strings){
+                int index = text.indexOf("]");
+                if(index < 8 ){
+                    continue;
+                }
+                String regex = "(?<=\\])";
+                Pattern compile = Pattern.compile(regex);
+                String[] split = compile.split(text,2);
+                long wait = 0;
+                try {
+                    wait = 28800000 + msFormat.parse(split[0].replace("[","").replace("]","")).getTime();
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+                arrayList.add(new TextBean(wait,split[1]));
+            }
+            if(arrayList.size() == 0){
+                return;
+            }
+
+            LyricServer.read(Arrays.asList(strings));
             //申请权限
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                 //开启悬浮窗
-               /* if(!Settings.canDrawOverlays(getApplicationContext())) {
+                if(!Settings.canDrawOverlays(getApplicationContext())) {
                     //启动Activity让用户授权
                     Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                     intent.setData(Uri.parse("package:" + getPackageName()));
@@ -47,10 +74,8 @@
                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
                     startActivity(intent);
                 }else{//开启监听服务
-                    //startService(floatService);
-                }*/
-                startService(floatService);
-                //showFloatView();
+                    startService(floatService);
+                }
             }
         });
     }
@@ -93,27 +118,5 @@
         return false;
     }
 
-    private void showFloatView(){
-
-
-        //View view = LayoutInflater.from(this).inflate(R.layout.float_view,null);
-        FloatViewBinding binding = FloatViewBinding.inflate(getLayoutInflater());
-        WindowManager manager = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE);
-        WindowManager.LayoutParams params = new WindowManager.LayoutParams();
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-        }else {
-            params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
-        }
-        params.format = PixelFormat.RGBA_8888;
-        params.gravity = Gravity.CENTER;
-        params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-        params.width = WindowManager.LayoutParams.MATCH_PARENT;
-        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
-        binding.btnBack.setOnClickListener(v ->{
-            stopService(new Intent(this,this.getClass()));
-        });
-        manager.addView(binding.getRoot(),params);
-    }
 
 }
\ No newline at end of file
diff --git a/app/src/main/java/com/auto/lyric/base/activities/BaseActivity.java b/app/src/main/java/com/auto/lyric/base/activities/BaseActivity.java
index 83b2702..df0058d 100644
--- a/app/src/main/java/com/auto/lyric/base/activities/BaseActivity.java
+++ b/app/src/main/java/com/auto/lyric/base/activities/BaseActivity.java
@@ -243,19 +243,6 @@
                         InputMethodManager.HIDE_NOT_ALWAYS);
         }
     }
-    /**
-     * 状态栏高度
-     * @return
-     */
-    public int getStatusBarHeight() {
-        int result = 0;
-        int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
-        if (resId > 0) {
-            result = getResources().getDimensionPixelOffset(resId);
-        }
-        return result;
-    }
-
 
     long mExitTime= 0 ;
     /**
diff --git a/app/src/main/java/com/auto/lyric/base/activities/BaseTitleBarActivity.java b/app/src/main/java/com/auto/lyric/base/activities/BaseTitleBarActivity.java
index 68fffeb..3ea2dda 100644
--- a/app/src/main/java/com/auto/lyric/base/activities/BaseTitleBarActivity.java
+++ b/app/src/main/java/com/auto/lyric/base/activities/BaseTitleBarActivity.java
@@ -8,6 +8,7 @@
 import androidx.viewbinding.ViewBinding;
 
 import com.auto.lyric.base.model.BaseViewModel;
+import com.auto.lyric.util.DeviceUtil;
 import com.auto.lyric.widgets.TitleBarView;
 
 
@@ -54,7 +55,7 @@
     public void setStatusBarTransparent(boolean isBlack) {
         super.setStatusBarTransparent(isBlack);
         final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) titleBarView.getLayoutParams();
-        layoutParams.topMargin = layoutParams.topMargin+getStatusBarHeight();
+        layoutParams.topMargin = layoutParams.topMargin+ DeviceUtil.getStatusBarHeight(this);
         titleBarView.setLayoutParams(layoutParams);
 
     }
diff --git a/app/src/main/java/com/auto/lyric/data/LyricObject.java b/app/src/main/java/com/auto/lyric/data/LyricObject.java
new file mode 100644
index 0000000..d8379d7
--- /dev/null
+++ b/app/src/main/java/com/auto/lyric/data/LyricObject.java
@@ -0,0 +1,11 @@
+package com.auto.lyric.data;
+
+/**
+ * Created by Runt (qingingrunt2010@qq.com) on 2022/5/2.
+ */
+public class LyricObject {
+    public int begintime; // 开始时间
+    public int endtime; // 结束时间
+    public int timeline; // 单句歌词用时
+    public String lrc; // 单句歌词
+}
diff --git a/app/src/main/java/com/auto/lyric/data/LyricServer.java b/app/src/main/java/com/auto/lyric/data/LyricServer.java
new file mode 100644
index 0000000..8b8ef7e
--- /dev/null
+++ b/app/src/main/java/com/auto/lyric/data/LyricServer.java
@@ -0,0 +1,143 @@
+package com.auto.lyric.data;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Created by Runt (qingingrunt2010@qq.com) on 2022/5/4.
+ */
+public class LyricServer {
+
+
+    private static TreeMap<Integer, LyricObject> lrc_map = new TreeMap<>();
+
+    public static TreeMap<Integer, LyricObject> getLrc_map() {
+        return lrc_map;
+    }
+
+
+    /**
+     * 读取歌词文件
+     * @param file 歌词的路径
+     *
+     */
+    public static void read(String file) {
+        TreeMap<Integer, LyricObject> lrc_read =new TreeMap<Integer, LyricObject>();
+        String data = "";
+        try {
+            File saveFile=new File(file);
+            // System.out.println("是否有歌词文件"+saveFile.isFile());
+            if(!saveFile.isFile()){
+                return;
+            }
+            //System.out.println("bllrc==="+blLrc);
+            FileInputStream stream = new FileInputStream(saveFile);//  context.openFileInput(file);
+
+            BufferedReader br = new BufferedReader(new InputStreamReader(stream,"GB2312"));
+            while ((data = br.readLine()) != null) {
+                readText(data,lrc_read);
+            }
+            stream.close();
+        } catch (FileNotFoundException e) {
+        } catch (IOException e) {
+        }
+        data ="";
+        initLrc(lrc_read);
+
+    }
+
+    public static void read(List<String> texts){
+        TreeMap<Integer, LyricObject> lrc_read =new TreeMap<Integer, LyricObject>();
+        for(String str : texts){
+            readText(str,lrc_read);
+        }
+        initLrc(lrc_read);
+    }
+
+    private static void readText(String text,TreeMap<Integer, LyricObject> lrc_read){
+        Pattern pattern = Pattern.compile("\\d{2}");
+        // System.out.println("++++++++++++>>"+data);
+        /*text = text.replace("[","");//将前面的替换成后面的
+        text = text.replace("]","@");
+        String splitdata[] = text.split("@");//分隔*/
+        String regex = "(?<=\\])";
+        Pattern compile = Pattern.compile(regex);
+        String[] splitdata = compile.split(text,2);//分隔
+        if(text.endsWith("]") || splitdata.length == 1){
+
+            String str = text;
+            str = str.replace("[","");
+            str = str.replace("]","");
+            str = str.replace(":",".");
+            str = str.replace(".","@");
+            String timedata[] =str.split("@");
+            Matcher matcher = pattern.matcher(timedata[0]);
+            if(timedata.length==3 && matcher.matches()){
+                int m = Integer.parseInt(timedata[0]);  //分
+                int s = Integer.parseInt(timedata[1]);  //秒
+                int ms = Integer.parseInt(timedata[2]); //毫秒
+                int currTime = (m*60+s)*1000+ms*10;
+                LyricObject item1= new LyricObject();
+                item1.begintime = currTime;
+                item1.lrc       = "";
+                lrc_read.put(currTime,item1);
+            }
+        } else{
+            String lrcContenet = splitdata[1];
+            String tmpstr = splitdata[0];
+            tmpstr = tmpstr.replace("[","");
+            tmpstr = tmpstr.replace("]","");
+            tmpstr = tmpstr.replace(":",".");
+            tmpstr = tmpstr.replace(".","@");
+            String timedata[] =tmpstr.split("@");
+            Matcher matcher = pattern.matcher(timedata[0]);
+            if(timedata.length==3 && matcher.matches()){
+                int m = Integer.parseInt(timedata[0]);  //分
+                int s = Integer.parseInt(timedata[1]);  //秒
+                int ms = Integer.parseInt(timedata[2]); //毫秒
+                int currTime = (m*60+s)*1000+ms*10;
+                LyricObject item1= new LyricObject();
+                item1.begintime = currTime;
+                item1.lrc       = lrcContenet;
+                lrc_read.put(currTime,item1);// 将currTime当标签  item1当数据 插入TreeMap里
+            }
+        }
+    }
+
+    /*
+     * 遍历hashmap 计算每句歌词所需要的时间
+     */
+    private static void initLrc(TreeMap<Integer, LyricObject> lrc_read){
+        lrc_map.clear();
+        Iterator<Integer> iterator = lrc_read.keySet().iterator();
+        LyricObject oldval  = null;
+        int i =0;
+        for(Integer key : lrc_read.keySet()){
+            LyricObject val = lrc_read.get(key);
+            if (oldval == null) {
+                oldval = val;
+            } else {
+                LyricObject item1= new LyricObject();
+                item1  = oldval;
+                item1.timeline = val.begintime-oldval.begintime;
+                lrc_map.put(new Integer(i), item1);
+                i++;
+                oldval = val;
+            }
+            if (lrc_read.size() > i) {
+                lrc_map.put(new Integer(i), val);
+            }
+        }
+    }
+
+
+}
diff --git a/app/src/main/java/com/auto/lyric/data/SendText.java b/app/src/main/java/com/auto/lyric/data/SendText.java
new file mode 100644
index 0000000..311b12d
--- /dev/null
+++ b/app/src/main/java/com/auto/lyric/data/SendText.java
@@ -0,0 +1,14 @@
+package com.auto.lyric.data;
+
+import java.util.ArrayList;
+
+/**
+ * Created by Runt (qingingrunt2010@qq.com) on 2022/5/1.
+ */
+public class SendText {
+    public ArrayList<String> texts;//文本
+
+    public SendText(ArrayList<String> texts) {
+        this.texts = texts;
+    }
+}
diff --git a/app/src/main/java/com/auto/lyric/data/TextBean.java b/app/src/main/java/com/auto/lyric/data/TextBean.java
new file mode 100644
index 0000000..75a4891
--- /dev/null
+++ b/app/src/main/java/com/auto/lyric/data/TextBean.java
@@ -0,0 +1,14 @@
+package com.auto.lyric.data;
+
+/**
+ * Created by Runt (qingingrunt2010@qq.com) on 2022/5/1.
+ */
+public class TextBean {
+    public TextBean(long waitTime, String text) {
+        this.waitTime = waitTime;
+        this.text = text;
+    }
+
+    public long waitTime;//间隔时间
+    public String text;//文本
+}
diff --git a/app/src/main/java/com/auto/lyric/service/FloatingWindowService.java b/app/src/main/java/com/auto/lyric/service/FloatingWindowService.java
index 720e9e6..426ee8c 100644
--- a/app/src/main/java/com/auto/lyric/service/FloatingWindowService.java
+++ b/app/src/main/java/com/auto/lyric/service/FloatingWindowService.java
@@ -1,6 +1,9 @@
 package com.auto.lyric.service;
 
 import android.app.Service;
+import android.content.ClipData;
+import android.content.ClipboardManager;
+import android.content.Context;
 import android.content.Intent;
 import android.graphics.PixelFormat;
 import android.os.Build;
@@ -13,14 +16,21 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
+import android.widget.Toast;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.core.view.LayoutInflaterFactory;
 
 import com.auto.lyric.R;
+import com.auto.lyric.data.LyricServer;
 import com.auto.lyric.databinding.FloatViewBinding;
 import com.auto.lyric.util.DeviceUtil;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
 
 /**
  * 全局悬浮窗
@@ -31,9 +41,29 @@
     private WindowManager manager;
     private WindowManager.LayoutParams params;
     FloatViewBinding binding;
-    Handler handler;
     final String TAG = "FloatingWindowService";
+    final int THREAD_STOP = 0, THREAD_START = 1 , KEYBOARD_SEND = 100,UPDATE_TIME = 200;
+    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+    SimpleDateFormat msFormat = new SimpleDateFormat("mm:ss.SSS");
+    boolean pause;
+    int progress;
 
+    Handler handler;
+
+    Timer timer;
+    ServiceTask task;
+    class ServiceTask extends TimerTask{
+        @Override
+        public void run() {
+            int index = binding.lyric.getIndex(progress+=10);
+            binding.lyric.setOffsetY(220 - index * (binding.lyric.getSIZEWORD() + 44));
+            binding.lyric.invalidate();
+            handler.sendEmptyMessage(UPDATE_TIME);
+            if(index == LyricServer.getLrc_map().size()-1){
+                handler.sendEmptyMessage(THREAD_STOP);
+            }
+        }
+    };
     @Override
     public void onCreate() {
         super.onCreate();
@@ -47,19 +77,14 @@
         }else {
             params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
         }
+        binding.btnBack.setEnabled(false);
+        binding.btnFast.setEnabled(false);
+        binding.btnPause.setEnabled(false);
         params.format = PixelFormat.RGBA_8888;
         params.gravity = Gravity.LEFT | Gravity.TOP;
         params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
         params.width = WindowManager.LayoutParams.MATCH_PARENT;
         params.height = DeviceUtil.convertDpToPixel(200,getBaseContext());
-        handler = new Handler(this.getMainLooper()){
-            @Override
-            public void handleMessage(@NonNull Message msg) {
-                binding.lyric.setText(msg.obj.toString());
-                int offset = binding.lyric.getLineCount() * binding.lyric.getLineHeight();
-
-            }
-        };
         binding.close.setOnClickListener(v ->{
             stopService(new Intent(this,this.getClass()));
             stopService(new Intent(this,AutoInputService.class));
@@ -75,14 +100,58 @@
                     || event.getAction() == MotionEvent.ACTION_UP){
                     params.y = (int) event.getRawY() - DeviceUtil.getStatusBarHeight(getBaseContext()) - startY;
                     manager.updateViewLayout(binding.getRoot(), params);
-                    Log.e(TAG,"ACTION_MOVE V:"+params.y);
+                    //Log.e(TAG,"ACTION_MOVE V:"+params.y);
                 }
-                Log.e(TAG,"onTouch event:"+event);
-                Log.e(TAG,"onTouch getRawY:"+event.getRawY());
+//                Log.e(TAG,"onTouch event:"+event);
+//                Log.e(TAG,"onTouch getRawY:"+event.getRawY());
                 return true;
             }
         });
 
+        binding.btnPause.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                if(pause){
+                    pause = false;
+                    binding.btnPause.setText("暂停");
+                    binding.btnBack.setEnabled(true);
+                    binding.btnFast.setEnabled(true);
+                    start();
+                }else{
+                    pause = true;
+                    binding.btnPause.setText("继续");
+                    binding.btnBack.setEnabled(false);
+                    binding.btnFast.setEnabled(false);
+                    timer.cancel();
+                }
+            }
+        });
+        binding.btnFast.setOnClickListener(v -> progress+=700);
+        binding.btnBack.setOnClickListener(v -> progress-=700);
+        binding.btnStart.setOnClickListener(v -> {
+            try {
+                if(new Date().getTime() > dateFormat.parse("2022-09-30 04:00:00").getTime()){
+                    Toast.makeText(getApplicationContext(),"软件使用时间已过期", Toast.LENGTH_SHORT).show();
+                    return;
+                }
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+            if(binding.btnStart.getText().equals("开启")){
+                progress = 0 ;
+                start();
+                startService(new Intent(this,AutoInputService.class));
+            }else{
+                binding.btnStart.setText("开启");
+                binding.btnBack.setEnabled(false);
+                binding.btnFast.setEnabled(false);
+                binding.btnPause.setEnabled(false);
+                progress = 0 ;
+                timer.cancel();
+                stopService(new Intent(this,AutoInputService.class));
+            }
+        });
+        initHandler();
     }
 
     @Nullable
@@ -91,10 +160,41 @@
         return null;
     }
 
+    private void initHandler(){
+        handler = new Handler(this.getMainLooper()){
+            @Override
+            public void handleMessage(@NonNull Message msg) {
+                super.handleMessage(msg);
+                if(msg.what == THREAD_START){//开始
+                    AutoInputService.flag = true;
+                    binding.btnPause.performClick();
+                }else if(msg.what == THREAD_STOP){//停止
+                    AutoInputService.flag = false;
+                    binding.btnStart.performClick();
+
+                }else if(msg.what == KEYBOARD_SEND){//发送文本
+                    copy(msg.obj.toString());
+                    Intent intent = new Intent();
+                    intent.setAction(AutoInputService.class.getName());
+                    intent.putExtra("action",AutoInputService.ACTION_PASTE);
+                    sendBroadcast(intent);
+                    intent.putExtra("action",AutoInputService.ACTION_SEND);
+                    sendBroadcast(intent);
+                }else if(msg.what == -1){//显示在输入框中
+
+                    //Toast.makeText(getBaseContext(),"上一句--"+msg.obj,Toast.LENGTH_SHORT).show();
+                }else if(msg.what == UPDATE_TIME){
+                    binding.timer.setText(msFormat.format(progress));
+                }
+            }
+        };
+    }
+
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         Log.e(TAG,"onStartCommand flags:"+flags+" startId:"+startId+ " intent:"+intent);
         manager.addView(binding.getRoot(),params);
+        binding.lyric.setTextSize();
         return super.onStartCommand(intent, flags, startId);
     }
 
@@ -102,7 +202,35 @@
     public void onDestroy() {
         super.onDestroy();
         Log.e(TAG,"onDestroy ");
+        timer.cancel();
         manager.removeView(binding.getRoot());
-
     }
+
+    /**
+     * 开始
+     */
+    private void start(){
+        timer = new Timer();
+        task = new ServiceTask();
+        timer.schedule(task,0,10);
+        binding.btnStart.setText("停止");
+        binding.btnPause.setText("暂停");
+        binding.btnBack.setEnabled(true);
+        binding.btnFast.setEnabled(true);
+        binding.btnPause.setEnabled(true);
+    }
+
+
+
+    //复制
+    private void copy(String data) {
+        // 获取系统剪贴板
+        ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
+        // 创建一个剪贴数据集,包含一个普通文本数据条目(需要复制的数据),其他的还有
+        ClipData clipData = ClipData.newPlainText(null, data);
+        // 把数据集设置(复制)到剪贴板
+        clipboard.setPrimaryClip(clipData);
+    }
+
+
 }
diff --git a/app/src/main/java/com/auto/lyric/widgets/LyricView.java b/app/src/main/java/com/auto/lyric/widgets/LyricView.java
index 47c4f82..864d1f2 100644
--- a/app/src/main/java/com/auto/lyric/widgets/LyricView.java
+++ b/app/src/main/java/com/auto/lyric/widgets/LyricView.java
@@ -1,151 +1,209 @@
 package com.auto.lyric.widgets;
 
-import android.app.Activity;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.Typeface;
-import android.media.MediaPlayer;
-import android.os.Bundle;
-import android.os.Handler;
 import android.util.AttributeSet;
-import android.widget.TextView;
+import android.util.Log;
+import android.view.MotionEvent;
 
-import com.auto.lyric.R;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import com.auto.lyric.data.LyricObject;
+import com.auto.lyric.data.LyricServer;
+import com.auto.lyric.util.DeviceUtil;
 
 /**
  * 歌词
  * Created by Runt (qingingrunt2010@qq.com) on 2022/4/30.
  */
 public class LyricView extends androidx.appcompat.widget.AppCompatTextView {
-    private Paint mPaint;
-    private float mX;
-    private Paint mPathPaint;
-    public int index = 0;
-    private List<Sentence>  list;
-    public float mTouchHistoryY;
-    private int mY;
-    private float middleY;//
-    private static final int DY = 40; //
-    public LyricView(Context context) {
+
+
+    private float mX;       //屏幕X轴的中点,此值固定,保持歌词在X中间显示
+    private float offsetY;      //歌词在Y轴上的偏移量,此值会根据歌词的滚动变小
+    private float touchY;   //当触摸歌词View时,保存为当前触点的Y轴坐标
+    private int lrcIndex=0; //保存歌词TreeMap的下标
+    private  int SIZEWORD=0;//显示歌词文字的大小值
+    private  int INTERVAL=45;//歌词每行的间隔
+    Paint paint=new Paint();//画笔,用于画不是高亮的歌词
+    Paint paintHL=new Paint();  //画笔,用于画高亮的歌词,即当前唱到这句歌词
+
+    public LyricView(Context context){
         super(context);
         init();
     }
-    public LyricView(Context context, AttributeSet attr) {
-        super(context, attr);
+
+    public LyricView(Context context, AttributeSet attrs) {
+        super(context, attrs);
         init();
     }
-    public LyricView(Context context, AttributeSet attr, int i) {
-        super(context, attr, i);
-        init();
-    }
-    private void init() {
-        setFocusable(true);
-        if(list==null){
-            list=new ArrayList<Sentence>();
-            Sentence sen=new Sentence(0," ");
-            list.add(0, sen);
-        }
-        //
-        mPaint = new Paint();
-        mPaint.setAntiAlias(true);
-        mPaint.setTextSize(24);
-        mPaint.setColor(Color.BLACK);
-        mPaint.setAlpha(80);
-        mPaint.setTypeface(Typeface.SERIF);
-        //
-        mPathPaint = new Paint();
-        mPathPaint.setAntiAlias(true);
-        mPathPaint.setColor(Color.RED);
-        mPathPaint.setTextSize(24);
-        mPathPaint.setTypeface(Typeface.SANS_SERIF);
-    }
+
+    /* (non-Javadoc)
+     * @see android.view.View#onDraw(android.graphics.Canvas)
+     */
+    @Override
     protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        canvas.drawColor(0xEFeffff);
-        Paint p = mPaint;
-        Paint p2 = mPathPaint;
-        p.setTextAlign(Paint.Align.LEFT);
-        if (index == -1)
-            return;
-        p2.setTextAlign(Paint.Align.LEFT);
-        //
-        canvas.drawText(list.get(index).getName(), mX, middleY, p2);
-        float tempY = middleY;
-        //
-        for (int i = index - 1; i  >= 0; i--) {
-            tempY = tempY - DY;
-            if (tempY < 0) {
-                break;
-            }
-            canvas.drawText(list.get(i).getName(), mX, tempY, p);
-        }
-        tempY = middleY;
-        //
-        for (int i = index + 1; i < list.size(); i++) {
-            //
-            tempY = tempY + DY;
-            if (tempY  > mY) {
-                break;
-            }
-            canvas.drawText(list.get(i).getName(), mX, tempY, p);
-        }
-    }
-    protected void onSizeChanged(int w, int h, int ow, int oh) {
-        super.onSizeChanged(w, h, ow, oh);
-        mX = w * 0.3f;
-        mY = h;
-        middleY = h * 0.5f;
-    }
-    public long updateIndex(int index) {
-        if (index == -1)
-            return -1;
-        this.index=index;
-        return index;
-    }
-    public List<Sentence>  getList() {
-        return list;
-    }
-    public void setList(List<Sentence>  list) {
-        this.list = list;
-    }
-    public void updateUI(){
-        new Thread(new updateThread()).start();
-    }
-    class updateThread implements Runnable {
-        long time = 300;
-        int i=0;
-        public void run() {
-            while (true) {
-                long sleeptime = updateIndex(i);
-                time += sleeptime;
-                mHandler.post(mUpdateResults);
-                if (sleeptime == -1)
-                    return;
-                try {
-                    Thread.sleep(time);
-                    i++;
-                    if(i==getList().size())
-                    {
-                        i=0;
-                        time = 300;
-                    }
-                } catch (InterruptedException e) {
-                    e.printStackTrace();
+        if(LyricServer.getLrc_map().size() > 0){
+            paintHL.setTextSize(SIZEWORD);
+            paint.setTextSize(SIZEWORD);
+            LyricObject temp= LyricServer.getLrc_map().get(lrcIndex);
+            canvas.drawText(temp.lrc, mX, offsetY+(SIZEWORD+INTERVAL)*lrcIndex, paintHL);
+            // 画当前歌词之前的歌词
+            for(int i=lrcIndex-1;i>=0;i--){
+                temp=LyricServer.getLrc_map().get(i);
+                if(offsetY+(SIZEWORD+INTERVAL)*i<0){
+                    break;
                 }
+                canvas.drawText(temp.lrc, mX, offsetY+(SIZEWORD+INTERVAL)*i, paint);
+            }
+            // 画当前歌词之后的歌词
+            for(int i=lrcIndex+1;i<LyricServer.getLrc_map().size();i++){
+                temp=LyricServer.getLrc_map().get(i);
+                if(offsetY+(SIZEWORD+INTERVAL)*i>600){
+                    break;
+                }
+                canvas.drawText(temp.lrc, mX, offsetY+(SIZEWORD+INTERVAL)*i, paint);
             }
         }
-    }
-    Handler mHandler = new Handler();
-    Runnable mUpdateResults = new Runnable() {
-        public void run() {
-            invalidate(); //
+        else{
+            paint.setTextSize(25);
+            canvas.drawText("找不到歌词", mX, 310, paint);
         }
-    };
+        super.onDraw(canvas);
+    }
+
+    /* (non-Javadoc)
+     * @see android.view.View#onTouchEvent(android.view.MotionEvent)
+     */
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        // TODO Auto-generated method stub
+        float tt=event.getY();
+        switch(event.getAction()){
+            case MotionEvent.ACTION_DOWN:
+                break;
+            case MotionEvent.ACTION_MOVE:
+                touchY=tt-touchY;
+                offsetY=offsetY+touchY;
+                Log.e("LyricView","offsety:"+offsetY);
+                invalidate();
+                break;
+            case MotionEvent.ACTION_UP:
+                break;
+        }
+        touchY=tt;
+        return true;
+    }
+
+    public void init(){
+        offsetY=320;
+
+        paint=new Paint();
+        paint.setTextAlign(Paint.Align.CENTER);
+        paint.setColor(Color.GREEN);
+        paint.setAntiAlias(true);
+        paint.setDither(true);
+        paint.setAlpha(180);
+
+
+        paintHL=new Paint();
+        paintHL.setTextAlign(Paint.Align.CENTER);
+
+        paintHL.setColor(Color.RED);
+        paintHL.setAntiAlias(true);
+        paintHL.setAlpha(255);
+    }
+
+    /**
+     * 根据歌词里面最长的那句来确定歌词字体的大小
+     */
+    public void setTextSize(){
+        if(LyricServer.getLrc_map().size() == 0){
+            return;
+        }
+        int max=LyricServer.getLrc_map().get(0).lrc.length();
+        for(int i=1;i<LyricServer.getLrc_map().size();i++){
+            LyricObject lrcStrLength=LyricServer.getLrc_map().get(i);
+            if(max<lrcStrLength.lrc.length()){
+                max=lrcStrLength.lrc.length();
+            }
+        }
+        SIZEWORD = DeviceUtil.convertDpToPixel(320/max,getContext());
+
+    }
+
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        mX = w * 0.5f;
+        super.onSizeChanged(w, h, oldw, oldh);
+    }
+
+    /**
+     *  歌词滚动的速度
+     *
+     * @return 返回歌词滚动的速度
+     */
+    public Float SpeedLrc(){
+        float speed=0;
+        if(offsetY+(SIZEWORD+INTERVAL)*lrcIndex>220){
+            speed=((offsetY+(SIZEWORD+INTERVAL)*lrcIndex-220)/20);
+
+        } else if(offsetY+(SIZEWORD+INTERVAL)*lrcIndex < 120){
+            Log.i("speed", "speed is too fast!!!");
+            speed = 0;
+        }
+        //      if(speed<0.2){
+        //          speed=0.2f;
+        //      }
+        return speed;
+    }
+
+    /**
+     * 按当前的歌曲的播放时间,从歌词里面获得那一句
+     * @param time 当前歌曲的播放时间
+     * @return 返回当前歌词的索引值
+     */
+    public int getIndex(int time){
+        int index=0;
+        for(int i=0;i<LyricServer.getLrc_map().size();i++){
+            LyricObject temp=LyricServer.getLrc_map().get(i);
+            if(temp.begintime<time){
+                ++index;
+            }
+        }
+        lrcIndex = index-1;
+        if(lrcIndex<0){
+            lrcIndex=0;
+        }
+        return lrcIndex;
+    }
+
+
+    /**
+     * @return the offsetY
+     */
+    public float getOffsetY() {
+        return offsetY;
+    }
+
+    /**
+     * @param offsetY the offsetY to set
+     */
+    public void setOffsetY(float offsetY) {
+        this.offsetY = offsetY;
+    }
+
+    /**
+     * @return 返回歌词文字的大小
+     */
+    public int getSIZEWORD() {
+        return SIZEWORD;
+    }
+
+    /**
+     * 设置歌词文字的大小
+     * @param sIZEWORD the sIZEWORD to set
+     */
+    public void setSIZEWORD(int sIZEWORD) {
+        SIZEWORD = sIZEWORD;
+    }
 }
diff --git a/app/src/main/java/com/auto/lyric/widgets/Sentence.java b/app/src/main/java/com/auto/lyric/widgets/Sentence.java
index f2cdf69..ae137c4 100644
--- a/app/src/main/java/com/auto/lyric/widgets/Sentence.java
+++ b/app/src/main/java/com/auto/lyric/widgets/Sentence.java
@@ -6,19 +6,24 @@
 public class Sentence {
     private String name;
     private int index;
+
     public Sentence(int index,String name){
         this.name=name;
         this.index=index;
     }
+
     public String getName() {
         return name;
     }
+
     public void setName(String name) {
         this.name = name;
     }
+
     public int getIndex() {
         return index;
     }
+
     public void setIndex(int index) {
         this.index = index;
     }
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index fdf1f7a..5fb776e 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -16,6 +16,7 @@
         android:padding="10dp"
         android:gravity="left"
         android:scrollbars="vertical"
+        android:textCursorDrawable="@null"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintLeft_toLeftOf="parent" />
diff --git a/app/src/main/res/layout/float_view.xml b/app/src/main/res/layout/float_view.xml
index df671b9..18f7eee 100644
--- a/app/src/main/res/layout/float_view.xml
+++ b/app/src/main/res/layout/float_view.xml
@@ -64,5 +64,28 @@
         android:textColor="@color/black"
         app:layout_constraintTop_toBottomOf="@id/lyric"
         app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintLeft_toRightOf="@id/btn_pause"
+        app:layout_constraintRight_toLeftOf="@id/btn_start" />
+
+    <Button
+        android:id="@+id/btn_start"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="开启"
+        android:textColor="@color/black"
+        app:layout_constraintTop_toBottomOf="@id/lyric"
+        app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintRight_toRightOf="parent"/>
+
+    <TextView
+        android:id="@+id/timer"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textColor="@color/white"
+        android:text="0.000"
+        android:textSize="15sp"
+        app:layout_constraintLeft_toLeftOf="parent"
+        app:layout_constraintRight_toRightOf="parent"
+        android:layout_marginTop="10dp"
+        app:layout_constraintTop_toTopOf="parent" />
 </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index c80f365..f7a09d4 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -2,12 +2,12 @@
     <!-- Base application theme. -->
     <style name="Theme.AutoLyric" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
         <!-- Primary brand color. -->
-        <item name="colorPrimary">@color/white</item>
-        <item name="colorPrimaryVariant">@color/color_gray</item>
-        <item name="colorOnPrimary">@color/white</item>
+        <item name="colorPrimary">@color/black</item>
+        <item name="colorPrimaryVariant">@color/gray_normal</item>
+        <item name="colorOnPrimary">@color/gray_pressed</item>
         <!-- Secondary brand color. -->
-        <item name="colorSecondary">@color/white</item>
-        <item name="colorSecondaryVariant">@color/color_gray</item>
+        <item name="colorSecondary">@color/gray_normal</item>
+        <item name="colorSecondaryVariant">@color/gray_pressed</item>
         <item name="colorOnSecondary">@color/black</item>
         <!-- Status bar color. -->
         <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>

--
Gitblit v1.9.1