From 98a4bd87adc3b48885c9a58ac6b37eb25c883132 Mon Sep 17 00:00:00 2001
From: muqing <1966944300@qq.com>
Date: Wed, 21 Feb 2024 18:20:05 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG=EF=BC=8C=E6=9B=B4?=
=?UTF-8?q?=E6=96=B0UI?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.idea/deploymentTargetDropDown.xml | 17 -
.idea/gradle.xml | 1 -
.idea/inspectionProfiles/Project_Default.xml | 2 +
.idea/kotlinc.xml | 6 +
.idea/misc.xml | 3 +
README.md | 2 +-
app/build.gradle | 16 +-
.../main/java/com/muqingbfq/MediaPlayer.java | 6 +-
.../java/com/muqingbfq/activity_search.java | 88 +-
app/src/main/java/com/muqingbfq/api/url.java | 10 +-
app/src/main/java/com/muqingbfq/bfq.java | 230 +++--
app/src/main/java/com/muqingbfq/bfqkz.java | 3 +-
.../com/muqingbfq/clean/fragment_clean.java | 7 +-
.../java/com/muqingbfq/fragment/Media.java | 7 +-
.../main/java/com/muqingbfq/fragment/gd.java | 2 +-
.../com/muqingbfq/fragment/gd_adapter.java | 23 +-
.../main/java/com/muqingbfq/fragment/mp3.java | 2 +-
.../java/com/muqingbfq/fragment/wode.java | 18 +-
app/src/main/java/com/muqingbfq/home.java | 49 +-
app/src/main/java/com/muqingbfq/main.java | 20 +-
.../mq/BluetoothMusicController.java | 1 -
.../muqingbfq/mq/FloatingLyricsService.java | 23 +-
.../com/muqingbfq/mq/FragmentActivity.java | 14 +-
app/src/main/java/com/muqingbfq/mq/gj.java | 2 +-
app/src/main/java/com/muqingbfq/mq/llq.java | 23 +-
app/src/main/java/com/muqingbfq/sz.java | 86 +-
.../main/java/com/muqingbfq/view/Edit.java | 38 +-
app/src/main/res/drawable/chahao.xml | 4 +-
app/src/main/res/drawable/like.xml | 4 +-
.../src/main/res/drawable}/lrc_play.png | Bin
app/src/main/res/drawable/progress.xml | 24 +
app/src/main/res/drawable/sousuo.xml | 4 +-
app/src/main/res/drawable/start.xml | 7 +-
app/src/main/res/layout-land/activity_bfq.xml | 11 +-
app/src/main/res/layout/activity_bfq.xml | 253 +++---
app/src/main/res/layout/activity_gd.xml | 2 +-
app/src/main/res/layout/activity_llq.xml | 37 +-
app/src/main/res/layout/activity_mp3.xml | 2 +-
app/src/main/res/layout/activity_search.xml | 52 +-
app/src/main/res/layout/activity_sz.xml | 51 +-
.../main/res/layout/activity_sz_setlrc.xml | 26 +-
app/src/main/res/layout/fragment_gd.xml | 35 +-
app/src/main/res/layout/view_button.xml | 1 +
.../res/mipmap-hdpi/ic_launcher_round.webp | Bin 2344 -> 0 bytes
app/src/main/res/mipmap-hdpi/logo.png | Bin 2304 -> 0 bytes
app/src/main/res/values/attrs.xml | 34 +-
app/src/main/res/values/colors.xml | 8 +
app/src/main/res/values/dimens.xml | 20 +-
app/src/main/res/values/strings.xml | 6 +
build.gradle | 14 +
lrcview/.gitignore | 1 -
lrcview/build.gradle | 22 -
lrcview/src/main/AndroidManifest.xml | 5 -
.../main/java/me/wcy/lrcview/LrcEntry.java | 117 ---
.../main/java/me/wcy/lrcview/LrcUtils.java | 244 -----
.../src/main/java/me/wcy/lrcview/LrcView.java | 841 ------------------
lrcview/src/main/res/values/attrs.xml | 24 -
lrcview/src/main/res/values/colors.xml | 8 -
lrcview/src/main/res/values/dimens.xml | 11 -
lrcview/src/main/res/values/strings.xml | 3 -
settings.gradle | 2 +-
61 files changed, 708 insertions(+), 1864 deletions(-)
delete mode 100644 .idea/deploymentTargetDropDown.xml
create mode 100644 .idea/kotlinc.xml
rename {lrcview/src/main/res/drawable-xxhdpi => app/src/main/res/drawable}/lrc_play.png (100%)
create mode 100644 app/src/main/res/drawable/progress.xml
delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
delete mode 100644 app/src/main/res/mipmap-hdpi/logo.png
delete mode 100644 lrcview/.gitignore
delete mode 100644 lrcview/build.gradle
delete mode 100644 lrcview/src/main/AndroidManifest.xml
delete mode 100644 lrcview/src/main/java/me/wcy/lrcview/LrcEntry.java
delete mode 100644 lrcview/src/main/java/me/wcy/lrcview/LrcUtils.java
delete mode 100644 lrcview/src/main/java/me/wcy/lrcview/LrcView.java
delete mode 100644 lrcview/src/main/res/values/attrs.xml
delete mode 100644 lrcview/src/main/res/values/colors.xml
delete mode 100644 lrcview/src/main/res/values/dimens.xml
delete mode 100644 lrcview/src/main/res/values/strings.xml
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
deleted file mode 100644
index ed66926..0000000
--- a/.idea/deploymentTargetDropDown.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 2b21421..d170b6e 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -12,7 +12,6 @@
-
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index 6553ed7..2823ce9 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -15,6 +15,8 @@
+
+
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..2b8a50f
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index f6cd62a..932c4df 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -46,4 +46,7 @@
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index a7664c5..cccd036 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@
* 在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流
- * [邮件]()
+ * [邮件]()
* QQ:1966944300
* 后台源码-Github: [网易云音乐 API](https://github.com/Binaryify/NeteaseCloudMusicApi)
diff --git a/app/build.gradle b/app/build.gradle
index 1264524..3e5de3f 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,5 +1,6 @@
plugins {
id 'com.android.application'
+ id 'kotlin-android'
}
android {
signingConfigs {
@@ -18,8 +19,7 @@ android {
//noinspection ExpiredTargetSdkVersion,OldTargetApi
targetSdk 31
versionCode 1
- versionName "1.9.9"
-
+ versionName "2.0.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@@ -39,11 +39,15 @@ android {
outputFileName = "Cloud_music-${variant.name}-v${variant.versionName}.apk"
}
}
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
viewBinding {
enabled = true
}
}
dependencies {
+ implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.9.0'
@@ -54,6 +58,7 @@ dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
//图片处理
implementation 'com.github.bumptech.glide:glide:4.16.0'
+
implementation "androidx.palette:palette:1.0.0"
// 废弃的歌词组件
// implementation 'com.github.wangchenyan:lrcview:2.2.1'
@@ -65,6 +70,9 @@ dependencies {
implementation 'com.mpatric:mp3agic:0.9.1'
// 沉浸式状态栏
- api project(path: ':StatusBarUtil')
- api project(path: ':lrcview')
+ implementation project(path: ':StatusBarUtil')
+// api project(path: ':lrcview')
+ //歌词组件库
+ api "com.github.cy745:EaseView:e11c3208a9"
+ api "androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03"
}
\ No newline at end of file
diff --git a/app/src/main/java/com/muqingbfq/MediaPlayer.java b/app/src/main/java/com/muqingbfq/MediaPlayer.java
index acf7e44..73dbbe1 100644
--- a/app/src/main/java/com/muqingbfq/MediaPlayer.java
+++ b/app/src/main/java/com/muqingbfq/MediaPlayer.java
@@ -24,7 +24,6 @@ import java.io.IOException;
public class MediaPlayer extends android.media.MediaPlayer {
// 每秒更新一次进度
-
@SuppressLint("UnsafeOptInUsageError")
public MediaPlayer() {
setOnErrorListener((mediaPlayer, i, i1) -> {
@@ -88,8 +87,11 @@ public class MediaPlayer extends android.media.MediaPlayer {
bfqkz.xm = mp3;
main.handler.post(() -> {
bfui();
- bfqkz.notify.tzl();
+ if (bfqkz.notify != null) {
+ bfqkz.notify.tzl();
+ }
});
+
new Thread() {
@Override
public void run() {
diff --git a/app/src/main/java/com/muqingbfq/activity_search.java b/app/src/main/java/com/muqingbfq/activity_search.java
index 587b05e..d2ec39c 100644
--- a/app/src/main/java/com/muqingbfq/activity_search.java
+++ b/app/src/main/java/com/muqingbfq/activity_search.java
@@ -14,13 +14,13 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
-import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import androidx.annotation.NonNull;
+import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
@@ -30,6 +30,7 @@ import com.google.android.flexbox.FlexDirection;
import com.google.android.flexbox.FlexWrap;
import com.google.android.flexbox.FlexboxLayoutManager;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.search.SearchView;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.muqingbfq.databinding.ActivitySearchBinding;
@@ -37,7 +38,6 @@ import com.muqingbfq.fragment.search;
import com.muqingbfq.mq.FragmentActivity;
import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj;
-import com.muqingbfq.mq.wl;
import com.muqingbfq.view.Edit;
import org.json.JSONArray;
@@ -55,14 +55,20 @@ public class activity_search extends FragmentActivity {
public static void start(Activity context, View view) {
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
- view, "view");
+ view, "edit");
context.startActivity(new Intent(context, activity_search.class), options.toBundle());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getViewBinding().getRoot());
- FlexboxLayoutManager manager = new FlexboxLayoutManager(this);
+ setToolbar();
+ FlexboxLayoutManager manager = new FlexboxLayoutManager(this){
+ @Override
+ public boolean canScrollVertically() {
+ return false;
+ }
+ };
//设置主轴排列方式
manager.setFlexDirection(FlexDirection.ROW);
//设置是否换行
@@ -70,16 +76,6 @@ public class activity_search extends FragmentActivity {
manager.setAlignItems(AlignItems.STRETCH);
binding.listRecycler.setLayoutManager(manager);
binding.listRecycler.setAdapter(new SearchRecordAdapter());
-
- binding.editview.setOnEditorActionListener((v, actionId, event) -> {
- if (actionId == EditorInfo.IME_ACTION_SEARCH) {
- String str = v.getText().toString();
- if (!str.equals("")) {
- start(str);
- }
- }
- return false;
- });
binding.deleat.setOnClickListener(v -> new MaterialAlertDialogBuilder(
activity_search.this)
.setTitle("删除")
@@ -109,20 +105,17 @@ public class activity_search extends FragmentActivity {
if (null != v) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
- binding.editview.setText(list.get(i));//把选择的选项内容展示在EditText上
+ binding.toolbar.setText(list.get(i));//把选择的选项内容展示在EditText上
dismiss();//如果已经选择了,隐藏起来
- start(binding.editview.getText().toString());
-
+ start(binding.toolbar.getText().toString());
});
Object o = new Object();
- binding.editview.addTextChangedListener(new Edit.TextWatcher() {
+ binding.searchview.getEditText().addTextChangedListener(new Edit.TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
-
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
- binding.editview.iskong();
if (TextUtils.isEmpty(s)) {
listPopupWindow.setVisibility(View.GONE);
return;
@@ -135,7 +128,8 @@ public class activity_search extends FragmentActivity {
@Override
public void run() {
synchronized (o) {
- String hq = wl.hq("/search/suggest?keywords=" + s + "&type=mobile");
+ String hq = com.muqingbfq.mq.wl.
+ hq("/search/suggest?keywords=" + s + "&type=mobile");
try {
JSONArray jsonArray = new JSONObject(hq).getJSONObject("result")
.getJSONArray("allMatch");
@@ -153,18 +147,46 @@ public class activity_search extends FragmentActivity {
}
}.start();
}
-
@Override
public void afterTextChanged(Editable s) {
}
});
- gj.tcjp(binding.editview.editText);
+/* if (binding.toolbar.collapse(contextualToolbar, binding.barlayout)) {
+ // Clear selection.
+ return;
+ }*/
+ binding.searchview.inflateMenu(R.menu.search);
+ binding.searchview.setOnMenuItemClickListener(
+ menuItem -> {
+ binding.searchview.hide();
+ start(binding.searchview.getText().toString());
+ return true;
+ });
+
+ binding.searchview.addTransitionListener(
+ (searchView, previousState, newState) -> {
+ if (newState == SearchView.TransitionState.HIDDEN) {
+ binding.toolbar.setText(searchView.getText());
+ }
+ });
+ binding.searchview
+ .getEditText()
+ .setOnEditorActionListener(
+ (v, actionId, event) -> {
+ binding.toolbar.setText(binding.searchview.getText());
+ binding.searchview.hide();
+ start(binding.searchview.getText().toString());
+ return false;
+ });
+ binding.toolbar.setOnMenuItemClickListener(item -> {
+ //搜索
+ start(binding.toolbar.getText().toString());
+ return true;
+ });
}
public void dismiss() {
- binding.editview.clearFocus();
- listPopupWindow.setVisibility(View.GONE);
- gj.ycjp(binding.editview.editText);
+ binding.searchview.hide();
}
private void addSearchRecord(String name) {
@@ -204,13 +226,17 @@ public class activity_search extends FragmentActivity {
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
+ if (binding.searchFragment.getVisibility() == View.VISIBLE) {
+ binding.searchFragment.setVisibility(View.GONE);
+ return false;
+ }
if (itemId == android.R.id.home) {
ActivityCompat.finishAfterTransition(this);
return false;
} else if (itemId == 0) {
- start(binding.editview.getText().toString());
+ start(binding.toolbar.getText().toString());
}
- return super.onOptionsItemSelected(item);
+ return true;
}
public void start(String name) {
@@ -269,7 +295,7 @@ public class activity_search extends FragmentActivity {
String keyword = json_list.get(position);
holder.recordTextView.setText(keyword);
holder.recordTextView.setOnClickListener(v -> {
- binding.editview.setText(keyword);
+ binding.toolbar.setText(keyword);
start(keyword);
});
holder.recordTextView.setOnLongClickListener(view -> {
@@ -308,6 +334,10 @@ public class activity_search extends FragmentActivity {
}
private void end() {
+ if (binding.searchview.isShowing()) {
+ binding.searchview.hide();
+ return;
+ }
if (binding.searchRecycler.getVisibility() == View.VISIBLE) {
binding.searchRecycler.setVisibility(View.GONE);
return;
diff --git a/app/src/main/java/com/muqingbfq/api/url.java b/app/src/main/java/com/muqingbfq/api/url.java
index 367ccc7..d727bcf 100644
--- a/app/src/main/java/com/muqingbfq/api/url.java
+++ b/app/src/main/java/com/muqingbfq/api/url.java
@@ -1,12 +1,10 @@
package com.muqingbfq.api;
-import android.content.Intent;
-
import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.Mp3File;
import com.muqingbfq.MP3;
import com.muqingbfq.fragment.Media;
-import com.muqingbfq.login.user_logs;
+import com.muqingbfq.home;
import com.muqingbfq.main;
import com.muqingbfq.mq.gj;
import com.muqingbfq.mq.wj;
@@ -55,9 +53,9 @@ public class url extends Thread {
if (json.getInt("code") == -460) {
String message = json.getString("message");
main.handler.post(() -> {
- gj.ts(main.application, message);
- main.application.startActivity(new Intent(main.application
- , user_logs.class));
+ gj.ts(home.activity, message);
+ home.activity.startActivity(new android.content.Intent(home.activity
+ , com.muqingbfq.login.user_logs.class));
});
return null;
}
diff --git a/app/src/main/java/com/muqingbfq/bfq.java b/app/src/main/java/com/muqingbfq/bfq.java
index 42c3c9d..aea640f 100644
--- a/app/src/main/java/com/muqingbfq/bfq.java
+++ b/app/src/main/java/com/muqingbfq/bfq.java
@@ -3,6 +3,7 @@ package com.muqingbfq;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
@@ -10,7 +11,10 @@ import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
+import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
@@ -18,13 +22,12 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
+import android.view.animation.LinearInterpolator;
+import android.widget.SeekBar;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
-import androidx.core.graphics.ColorUtils;
import androidx.palette.graphics.Palette;
import com.bumptech.glide.Glide;
@@ -33,7 +36,6 @@ import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
-import com.google.android.material.slider.Slider;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mpatric.mp3agic.ID3v2;
@@ -56,6 +58,23 @@ public class bfq extends AppCompatActivity
public MP3 mp3;
public boolean isplay = true;
GestureDetector gestureDetector;
+ int seekbarH = 0;
+
+ private void lrc(View v) {
+ // 隐藏view2并显示view1的动画效果
+ v.animate()
+ .alpha(0.0f)
+ .setDuration(500)
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ v.setVisibility(View.GONE);
+ binding.cardview.setVisibility(View.VISIBLE);
+ binding.cardview.setAlpha(0.0f);
+ binding.cardview.animate().alpha(1.0f).setDuration(500).setListener(null);
+ }
+ });
+ }
@SuppressLint("ClickableViewAccessibility")
private void setLrc() {
@@ -66,48 +85,66 @@ public class bfq extends AppCompatActivity
if (!gj.isTablet(this)) {
layoutParams.height = (int) (main.k / 1.3f);
layoutParams.width = (int) (main.k / 1.3f);
- binding.fragmentBfq.setOnTouchListener((v, event) -> bfq.super.onTouchEvent(event));
+ binding.lrcView.setOnClickListener(this::lrc);
- binding.lrcView.setOnTapListener((view, x, y) -> {
-
- // 隐藏view2并显示view1的动画效果
- view.animate()
- .alpha(0.0f)
- .setDuration(500)
- .setListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- view.setVisibility(View.GONE);
- binding.cardview.setVisibility(View.VISIBLE);
- binding.cardview.setAlpha(0.0f);
- binding.cardview.animate().alpha(1.0f).setDuration(500).setListener(null);
- }
- });
- });
+ binding.lrcView.setOnSingerClickListener(() -> lrc(binding.lrcView));
+// binding.lrcView.setTextGravity(GRAVITY_LEFT)
+ binding.lrcView.setNormalTextSize(80f);
+ binding.lrcView.setCurrentTextSize(100f);
+ binding.lrcView.setTranslateTextScaleValue(0.8f);
+ binding.lrcView.setHorizontalOffset(-50f);
+ binding.lrcView.setHorizontalOffsetPercent(0.5f);
+ binding.lrcView.setItemOffsetPercent(0.5f);
+ binding.lrcView.setIsDrawTranslation(true);
+ binding.lrcView.setIsEnableBlurEffect(true);
} else {
layoutParams.height = (int) (main.g / 2.0f);
layoutParams.width = (int) (main.g / 2.0f);
}
binding.cardview.setLayoutParams(layoutParams);
- binding.lrcView.
- setDraggable(true, (a, time) -> {
- bfqkz.mt.seekTo((int) time);
- return false;
- });
- binding.tdt.addOnChangeListener((slider, value, fromUser) ->
- setTime_b(bfq_an.getTime((long) value)));
- binding.tdt.addOnSliderTouchListener(new Slider.OnSliderTouchListener() {
+
+ binding.lrcView.setDraggable(true, time -> {
+ bfqkz.mt.seekTo((int) time);
+ return false;
+ });
+ binding.tdt.setThumb(null);
+ binding.tdt.post(() -> seekbarH = binding.tdt.getHeight());
+ binding.tdt.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
- public void onStartTrackingTouch(@NonNull Slider slider) {
- // 拖动条移动中
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ // 当进度发生变化时执行操作
+ setTime_b(bfq_an.getTime(progress));
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ // 当开始拖动滑块时执行操作
+ // 创建 ValueAnimator 对象,实现进度条高度的平滑过渡
+ ValueAnimator animator = ValueAnimator.ofInt(seekbarH,
+ seekbarH + 30);
+ animator.addUpdateListener(animation -> {
+ seekBar.getLayoutParams().height = (int) animation.getAnimatedValue();
+ seekBar.requestLayout();
+ });
+ animator.setDuration(200); // 设置动画持续时间为 200 毫秒
+ animator.start(); // 开始执行动画
isplay = false;
}
@Override
- public void onStopTrackingTouch(@NonNull Slider slider) {
- // 播放音乐到指定位置
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ // 当停止拖动滑块时执行操作
isplay = true;
- bfqkz.mt.seekTo((int) slider.getValue());
+ // 创建 ValueAnimator 对象,实现恢复进度条高度的平滑过渡
+ ValueAnimator animator = ValueAnimator.ofInt(seekbarH + 30,
+ seekbarH);
+ animator.addUpdateListener(animation -> {
+ seekBar.getLayoutParams().height = (int) animation.getAnimatedValue();
+ seekBar.requestLayout();
+ });
+ animator.setDuration(200); // 设置动画持续时间为 200 毫秒
+ animator.start(); // 开始执行动画
+ bfqkz.mt.seekTo(seekBar.getProgress());
}
});
}
@@ -120,17 +157,39 @@ public class bfq extends AppCompatActivity
context.startActivity(intent);
}
+ ObjectAnimator rotateAnimation;
+
+ private void Animation() {
+ if (bfqkz.mt.isPlaying()) {
+ if (rotateAnimation.isPaused()) {
+ rotateAnimation.resume();
+ } else {
+ rotateAnimation.start();
+ }
+ } else {
+ rotateAnimation.pause();
+ }
+ }
@SuppressLint("ClickableViewAccessibility")
@Override
protected void UI(@Nullable Bundle savedInstanceState) {
gestureDetector = new GestureDetector(this, this);
setLrc();
+ rotateAnimation = ObjectAnimator.ofFloat(binding.cardview
+ , "rotation", 0f, 360f);
+ rotateAnimation.setDuration(30000); // 设置动画持续时间,单位为毫秒
+ rotateAnimation.setRepeatCount(ObjectAnimator.INFINITE); // 设置重复次数为无限
+ rotateAnimation.setInterpolator(new LinearInterpolator()); // 设置插值器,这里使用线性插值器
+ rotateAnimation.start();
binding.kg.setOnClickListener(v -> {
if (bfqkz.mt.isPlaying()) {
bfqkz.mt.pause();
+ setbf(false);
} else {
bfqkz.mt.start();
+ setbf(true);
}
+ Animation();
});
binding.xyq.setOnClickListener(v -> bfq_an.xyq());
binding.syq.setOnClickListener(v -> bfq_an.syq());
@@ -178,6 +237,21 @@ public class bfq extends AppCompatActivity
Intent intent = getIntent();
mp3 = (MP3) intent.getSerializableExtra("MP3");
new thread().start();
+ binding.fragmentBfq.setOnTouchListener((v, event) -> {
+ gestureDetector.onTouchEvent(event);
+ if (event.getAction() == MotionEvent.ACTION_UP) {
+ if (binding.getRoot().getRootView().getTranslationY() > (main.g / 2.0f)) {
+ finish();
+ return true;
+ }
+ ObjectAnimator animator = ObjectAnimator.ofFloat(binding.getRoot().getRootView()
+ , "y", binding.getRoot().getRootView().getTranslationY(), 0);
+ animator.setDuration(500);
+ animator.start();
+ }
+ return true;
+ });
+
}
private class toolbar implements View.OnClickListener {
@@ -211,28 +285,12 @@ public class bfq extends AppCompatActivity
if (mp3 != null) {
sx();
}
- if (bfqkz.mt != null && bfqkz.mt.isPlaying()) {
- binding.kg.setImageResource(R.drawable.bf);
- }
+ setbf(bfqkz.mt.isPlaying());
+ Animation();
});
main.handler.post(runnable);
- }
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- gestureDetector.onTouchEvent(event);
- if (event.getAction() == MotionEvent.ACTION_UP) {
- if (binding.getRoot().getRootView().getTranslationY() > (main.g / 2.0f)) {
- finish();
- return true;
- }
- ObjectAnimator animator = ObjectAnimator.ofFloat(binding.getRoot().getRootView()
- , "y", binding.getRoot().getRootView().getTranslationY(), 0);
- animator.setDuration(500);
- animator.start();
}
- return super.onTouchEvent(event);
}
public void sx() {
@@ -269,12 +327,12 @@ public class bfq extends AppCompatActivity
}
public void setlike(boolean bool) {
- int color = R.color.text;
if (bool) {
- color = android.R.color.holo_red_dark;
+ binding.like.setImageTintList(ContextCompat.
+ getColorStateList(binding.getRoot().getContext(), android.R.color.holo_red_dark));
+ } else {
+ binding.like.setImageTintList(ColorStateList.valueOf(ColorTint));
}
- binding.like.setImageTintList(ContextCompat.
- getColorStateList(binding.getRoot().getContext(), color));
islike = bool;
}
@@ -299,6 +357,7 @@ public class bfq extends AppCompatActivity
setImageBitmap();
}
if (bfqkz.mt.isPlaying() != isPlaying) {
+
setbf(bfqkz.mt.isPlaying());
}
if (bfqkz.like_bool != islike) {
@@ -307,7 +366,7 @@ public class bfq extends AppCompatActivity
if (!Objects.equals(bfqkz.lrc, lrc)) {
lrc = bfqkz.lrc;
String[] strings = Media.loadLyric();
- binding.lrcView.loadLrc(strings[0], strings[1]);
+ binding.lrcView.loadLyric(strings[0], strings[1]);
}
main.handler.postDelayed(this, 1000); // 每秒更新一次进度
}
@@ -362,7 +421,6 @@ public class bfq extends AppCompatActivity
@NonNull DataSource dataSource,
boolean isFirstResource) {
color(resource);
-
return false;
}
}).into(binding.cardview.imageView);
@@ -373,23 +431,47 @@ public class bfq extends AppCompatActivity
Palette.from(bitmap)
.maximumColorCount(10)
.generate(palette -> {
+// 获取图片中有活力的亮色
+ int dominantSwatch = palette.getLightVibrantColor(Color.WHITE);
+// 获取图片中柔和的亮色
int lightMutedColor = palette.getLightMutedColor(Color.GRAY);
GradientDrawable gradientDrawable = new GradientDrawable(
GradientDrawable.Orientation.BOTTOM_TOP, // 渐变方向:从上到下
- new int[]{Color.BLACK, lightMutedColor} // 渐变颜色数组
+ new int[]{lightMutedColor, dominantSwatch} // 渐变颜色数组
);
-// 设置渐变背景的形状为矩形
+ int vibrantColor = palette.getVibrantColor(Color.BLACK);
+ setTint(vibrantColor);
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
-// trackColorInactive
-// 创建颜色列表
- ColorStateList trackInactiveTintList = ColorStateList
- .valueOf(ColorUtils.blendARGB(lightMutedColor
- , Color.WHITE, 0.5f));
- binding.tdt.setTrackInactiveTintList(trackInactiveTintList);
binding.getRoot().setBackground(gradientDrawable);
});
}
+ private int ColorTint = Color.WHITE;
+ private void setTint(int color) {
+ this.ColorTint = color;
+ ColorStateList colorStateList = ColorStateList.valueOf(color);
+ binding.kg.setImageTintList(colorStateList);
+ binding.syq.setImageTintList(colorStateList);
+ binding.xyq.setImageTintList(colorStateList);
+ binding.bfqListMp3.setImageTintList(colorStateList);
+ binding.control.setImageTintList(colorStateList);
+ binding.like.setImageTintList(colorStateList);
+ binding.download.setImageTintList(colorStateList);
+ binding.image2.setImageTintList(colorStateList);
+ binding.name.setTextColor(color);
+ binding.zz.setTextColor(color);
+ binding.timeA.setTextColor(color);
+ binding.timeB.setTextColor(color);
+
+ Drawable progressDrawable = binding.tdt.getProgressDrawable();
+ LayerDrawable layerDrawable = (LayerDrawable) progressDrawable;
+ Drawable progress = layerDrawable.findDrawableByLayerId(android.R.id.progress);
+ progress.setColorFilter(color, PorterDuff.Mode.SRC_IN);
+// 设置进度条背景的颜色
+/* Drawable background = layerDrawable.findDrawableByLayerId(android.R.id.background);
+ background.setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN);*/
+ }
+
@Override
public void finish() {
super.finish();
@@ -405,19 +487,15 @@ public class bfq extends AppCompatActivity
}
public void setMax(int max) {
- binding.tdt.setValueTo(Math.max(0, max));
+ binding.tdt.setMax(Math.max(0, max));
}
public void Progress(int progress) {
- if (binding.tdt.getValueTo() < progress) {
- return;
- // 处理超出范围的情况
- }
- binding.tdt.setValue(progress);
- binding.lrcView.updateTime(progress);
+ int min = Math.min(progress, binding.tdt.getMax());
+ binding.tdt.setProgress(min);
+ binding.lrcView.updateTime(min, true);
}
-
@Override
public boolean onDown(@NonNull MotionEvent e) {
return false;
@@ -471,9 +549,9 @@ public class bfq extends AppCompatActivity
@Override
public boolean onScroll(@NonNull MotionEvent e1, @NonNull MotionEvent e2,
float distanceX, float distanceY) {
- if (binding.lrcView.getVisibility() == View.VISIBLE) {
+/* if (binding.lrcView.getVisibility() == View.VISIBLE) {
return false;
- }
+ }*/
float y = binding.getRoot().getRootView().getTranslationY() - distanceY;
y = Math.max(0, y);
//移动的距离
diff --git a/app/src/main/java/com/muqingbfq/bfqkz.java b/app/src/main/java/com/muqingbfq/bfqkz.java
index 621fd52..91e6a26 100644
--- a/app/src/main/java/com/muqingbfq/bfqkz.java
+++ b/app/src/main/java/com/muqingbfq/bfqkz.java
@@ -25,7 +25,8 @@ import java.util.ArrayList;
import java.util.List;
public class bfqkz extends MediaBrowserServiceCompat {
- public static MediaPlayer mt = new MediaPlayer();
+ public final static MediaPlayer mt = new MediaPlayer();
+
public static List list = new ArrayList<>();
//保存原始list顺序
public static List list_baocun = new ArrayList<>();
diff --git a/app/src/main/java/com/muqingbfq/clean/fragment_clean.java b/app/src/main/java/com/muqingbfq/clean/fragment_clean.java
index 742a4c9..45d825c 100644
--- a/app/src/main/java/com/muqingbfq/clean/fragment_clean.java
+++ b/app/src/main/java/com/muqingbfq/clean/fragment_clean.java
@@ -28,12 +28,11 @@ import java.util.List;
public class fragment_clean extends FragmentActivity {
List list = new ArrayList<>();
List list_box = new ArrayList<>();
- ActivityCleanBinding binding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- binding = ActivityCleanBinding.inflate(getLayoutInflater());
- setContentView(binding.getRoot());
+ setContentView();
+ setToolbar();
UI();
}
@@ -117,7 +116,7 @@ public class fragment_clean extends FragmentActivity {
}
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
} else if (item == menu_deleat) {
diff --git a/app/src/main/java/com/muqingbfq/fragment/Media.java b/app/src/main/java/com/muqingbfq/fragment/Media.java
index 5384f0d..702c0a0 100644
--- a/app/src/main/java/com/muqingbfq/fragment/Media.java
+++ b/app/src/main/java/com/muqingbfq/fragment/Media.java
@@ -1,5 +1,6 @@
package com.muqingbfq.fragment;
+import com.dirror.lyricviewx.LyricViewX;
import com.muqingbfq.mq.gj;
import org.json.JSONObject;
@@ -17,12 +18,10 @@ public class Media {
a = jsonObject.getJSONObject("lrc").getString("lyric");
b = jsonObject.getJSONObject("tlyric").getString("lyric");
} catch (Exception e) {
- gj.sc("Media loadLyric "+e);
+ gj.sc("Media loadLyric " + e);
}
- me.wcy.lrcview.LrcView.Lrc(a, b);
+ LyricViewX.lrc(a, b);
return new String[]{a, b};
-// bfq.lrcView.getLrc();
-// bfq.lrcView.loadLrc(a, b);
}
}
diff --git a/app/src/main/java/com/muqingbfq/fragment/gd.java b/app/src/main/java/com/muqingbfq/fragment/gd.java
index 94ff125..b3d8562 100644
--- a/app/src/main/java/com/muqingbfq/fragment/gd.java
+++ b/app/src/main/java/com/muqingbfq/fragment/gd.java
@@ -50,7 +50,7 @@ public class gd extends com.muqingbfq.mq.FragmentActivity {
public static void start(Activity context, String[] str, View view) {
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
- view, "view");
+ view, "text");
Intent intent = new Intent(context, gd.class);
intent.putExtra("id", str[0]);
intent.putExtra("name", str[1]);
diff --git a/app/src/main/java/com/muqingbfq/fragment/gd_adapter.java b/app/src/main/java/com/muqingbfq/fragment/gd_adapter.java
index 1accde9..0a1a156 100644
--- a/app/src/main/java/com/muqingbfq/fragment/gd_adapter.java
+++ b/app/src/main/java/com/muqingbfq/fragment/gd_adapter.java
@@ -10,7 +10,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
-import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -41,20 +40,24 @@ public class gd_adapter extends Fragment {
List list = new ArrayList<>();
List listmp3 = new ArrayList<>();
FragmentGdBinding binding;
+
+ public void toolbar() {
+// binding.bar.setupWithDrawer
+ ((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
+ androidx.drawerlayout.widget.DrawerLayout drawerLayout = requireActivity().findViewById(R.id.chct);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ requireActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
+ drawerLayout.addDrawerListener(toggle);
+ toggle.syncState();
+ }
+
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentGdBinding.inflate(getLayoutInflater(), container, false);
//初始化工具栏
-
- ((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
- DrawerLayout drawerLayout = requireActivity().findViewById(R.id.chct);
- ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
- getActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
- drawerLayout.addDrawerListener(toggle);
- toggle.syncState();
-
+ toolbar();
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
binding.recyclerview1.setHasFixedSize(true);
@@ -122,7 +125,7 @@ public class gd_adapter extends Fragment {
});
mp3list();
- binding.editView.setOnClickListener(v -> activity_search.start(getActivity(),v));
+ binding.toolbar.setOnClickListener(v -> activity_search.start(getActivity(), v));
return binding.getRoot();
}
diff --git a/app/src/main/java/com/muqingbfq/fragment/mp3.java b/app/src/main/java/com/muqingbfq/fragment/mp3.java
index bfc5040..050554c 100644
--- a/app/src/main/java/com/muqingbfq/fragment/mp3.java
+++ b/app/src/main/java/com/muqingbfq/fragment/mp3.java
@@ -54,7 +54,7 @@ public class mp3 extends FragmentActivity {
public static void start(Activity context, String[] str, View view) {
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
- view, "view");
+ view, "text");
Intent intent = new Intent(context, mp3.class);
intent.putExtra("id", str[0]);
intent.putExtra("name", str[1]);
diff --git a/app/src/main/java/com/muqingbfq/fragment/wode.java b/app/src/main/java/com/muqingbfq/fragment/wode.java
index 0a05611..44a2a11 100644
--- a/app/src/main/java/com/muqingbfq/fragment/wode.java
+++ b/app/src/main/java/com/muqingbfq/fragment/wode.java
@@ -71,18 +71,22 @@ public class wode extends Fragment {
@SuppressLint("StaticFieldLeak")
public static baseadapter adaper;
+ public void toolbar() {
+ ((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
+ DrawerLayout drawerLayout = requireActivity().findViewById(R.id.chct);
+ ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+ requireActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
+ drawerLayout.addDrawerListener(toggle);
+ toggle.syncState();
+ }
+
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
binding = FragmentWdBinding.inflate(inflater, container, false);
//初始化工具栏
- ((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
- DrawerLayout drawerLayout = getActivity().findViewById(R.id.chct);
- ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
- getActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
- drawerLayout.addDrawerListener(toggle);
- toggle.syncState();
+ toolbar();
name = binding.text1;
binding.appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isCollapsed = false; // 标记是否处于折叠状态
@@ -146,7 +150,7 @@ public class wode extends Fragment {
getContext().startActivity(a);
break;
case "排行榜":
- gd.start(getActivity(), new String[]{data, s}, holder.itemView);
+ gd.start(getActivity(), new String[]{data, s}, holder.textView);
break;
case "API":
EditViewDialog editViewDialog = new EditViewDialog(getContext(), "更换接口API")
diff --git a/app/src/main/java/com/muqingbfq/home.java b/app/src/main/java/com/muqingbfq/home.java
index 5016d80..e5779ab 100644
--- a/app/src/main/java/com/muqingbfq/home.java
+++ b/app/src/main/java/com/muqingbfq/home.java
@@ -1,5 +1,7 @@
package com.muqingbfq;
+import android.annotation.SuppressLint;
+import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -14,6 +16,7 @@ import android.view.MenuItem;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
+import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
@@ -27,12 +30,17 @@ import java.util.List;
public class home extends com.muqingbfq.mq.AppCompatActivity {
public MediaBrowserCompat mBrowser;
+ @SuppressLint("StaticFieldLeak")
+ public static Context activity;
+
@Override
protected ActivityHomeBinding getViewBindingObject(LayoutInflater layoutInflater) {
return ActivityHomeBinding.inflate(layoutInflater);
}
+
@Override
protected void onCreate(Bundle savedInstanceState) {
+ activity = this;
setTheme(R.style.Theme_muqing);
super.onCreate(savedInstanceState);
setContentView(getViewBinding().getRoot());
@@ -72,31 +80,25 @@ public class home extends com.muqingbfq.mq.AppCompatActivity list = new ArrayList<>();
- public Adaper(@NonNull FragmentActivity fragmentActivity) {
- super(fragmentActivity);
- list.add(new gd_adapter());
- list.add(new wode());
- }
- @NonNull
- @Override
- public Fragment createFragment(int position) {
- return list.get(position);
- }
-
- @Override
- public int getItemCount() {
- return list.size();
- }
- }
-
+ List list = new ArrayList<>();
public void UI() {
- Adaper adapter = new Adaper(this);
- binding.viewPager.setAdapter(adapter);
+ list.clear();
+ list.add(new gd_adapter());
+ list.add(new wode());
+ binding.viewPager.setAdapter(new FragmentStateAdapter(this) {
+ @NonNull
+ @Override
+ public Fragment createFragment(int position) {
+ return list.get(position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return list.size();
+ }
+ });
binding.viewPager.setSaveEnabled(false);
-// 将 ViewPager2 绑定到 TabLayout
+// 将 ViewPager2 绑定到 TabLayou
binding.tablayout.setOnItemSelectedListener(item -> {
int itemId = item.getItemId();
if (itemId == R.id.a) {
@@ -132,6 +134,7 @@ public class home extends com.muqingbfq.mq.AppCompatActivity>>>>>>>>>>>>>>>>>>App切到后台");
new Thread(){
@Override
public void run() {
@@ -154,7 +142,6 @@ public class main extends Application {
} catch (InterruptedException e) {
e.printStackTrace();
}
-// gj.sc(count);
if (count != 0) {
return;
}
@@ -173,7 +160,6 @@ public class main extends Application {
@Override
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
}
-
@Override
public void onActivityDestroyed(@NonNull Activity activity) {
}
diff --git a/app/src/main/java/com/muqingbfq/mq/BluetoothMusicController.java b/app/src/main/java/com/muqingbfq/mq/BluetoothMusicController.java
index f198d42..fa8704c 100644
--- a/app/src/main/java/com/muqingbfq/mq/BluetoothMusicController.java
+++ b/app/src/main/java/com/muqingbfq/mq/BluetoothMusicController.java
@@ -18,7 +18,6 @@ public class BluetoothMusicController {
this.context = context;
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
-
intentFilter.addAction("android.intent.action.HEADSET_PLUG");
context.registerReceiver(new MyButtonClickReceiver(), intentFilter);
registerHeadsetReceiver();
diff --git a/app/src/main/java/com/muqingbfq/mq/FloatingLyricsService.java b/app/src/main/java/com/muqingbfq/mq/FloatingLyricsService.java
index 7d5ea7f..ff10fc4 100644
--- a/app/src/main/java/com/muqingbfq/mq/FloatingLyricsService.java
+++ b/app/src/main/java/com/muqingbfq/mq/FloatingLyricsService.java
@@ -17,6 +17,8 @@ import android.widget.ImageView;
import androidx.annotation.Nullable;
+import com.dirror.lyricviewx.LyricEntry;
+import com.dirror.lyricviewx.LyricViewX;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.muqingbfq.R;
@@ -27,10 +29,6 @@ import com.muqingbfq.main;
import java.io.File;
import java.lang.reflect.Type;
-
-import me.wcy.lrcview.LrcEntry;
-import me.wcy.lrcview.LrcView;
-
public class FloatingLyricsService extends Service implements View.OnClickListener, View.OnTouchListener {
private WindowManager windowManager;
private View layout;
@@ -39,26 +37,17 @@ public class FloatingLyricsService extends Service implements View.OnClickListen
@Override
public void run() {
int index = 0;
- for (int i = 0; i < LrcView.mLrcEntryList.size(); i++) {
- LrcEntry lineLrc = LrcView.mLrcEntryList.get(i);
+ for (int i = 0; i < LyricViewX.lyricEntryList.size(); i++) {
+ LyricEntry lineLrc = LyricViewX.lyricEntryList.get(i);
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
index = i;
} else {
break;
}
}
- if (index < LrcView.mLrcEntryList.size()) {
+ if (index < LyricViewX.lyricEntryList.size()) {
String text;
- if (LrcView.mLrcEntryList.size() <= 3) {
- for (LrcEntry a : LrcView.mLrcEntryList) {
- if (a.time == 5940000 && a.text.equals("纯音乐,请欣赏")) {
- text = "纯音乐,请欣赏";
- binding.lrcView.setText(text);
- return;
- }
- }
- }
- LrcEntry currentLrc = LrcView.mLrcEntryList.get(index);
+ LyricEntry currentLrc = LyricViewX.lyricEntryList.get(index);
text = currentLrc.text;
if (currentLrc.secondText != null) {
text += "\n" + currentLrc.secondText;
diff --git a/app/src/main/java/com/muqingbfq/mq/FragmentActivity.java b/app/src/main/java/com/muqingbfq/mq/FragmentActivity.java
index feaaf8e..44a6cf8 100644
--- a/app/src/main/java/com/muqingbfq/mq/FragmentActivity.java
+++ b/app/src/main/java/com/muqingbfq/mq/FragmentActivity.java
@@ -5,6 +5,7 @@ import android.view.MenuItem;
import android.view.View;
import androidx.annotation.NonNull;
+import androidx.appcompat.widget.Toolbar;
import androidx.viewbinding.ViewBinding;
import com.jaeger.library.StatusBarUtil;
@@ -29,13 +30,19 @@ public abstract class FragmentActivity
return super.onOptionsItemSelected(item);
}
public void setToolbar() {
- setSupportActionBar(findViewById(R.id.toolbar));
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ View viewById = findViewById(R.id.toolbar);
+ if (viewById != null) {
+ setSupportActionBar((Toolbar) viewById);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ }
}
-
@Override
public void setContentView(int view) {
super.setContentView(view);
+ }
+ public void setContentView() {
+ binding = getViewBindingObject(getLayoutInflater());
+ setContentView(binding.getRoot());
setToolbar();
}
@@ -43,6 +50,5 @@ public abstract class FragmentActivity
public void setContentView(View view) {
StatusBarUtil.setTransparent(this);
super.setContentView(view);
- setToolbar();
}
}
diff --git a/app/src/main/java/com/muqingbfq/mq/gj.java b/app/src/main/java/com/muqingbfq/mq/gj.java
index 5f07518..ee9d6fa 100644
--- a/app/src/main/java/com/muqingbfq/mq/gj.java
+++ b/app/src/main/java/com/muqingbfq/mq/gj.java
@@ -67,7 +67,7 @@ public class gj {
if (a == null) {
a = "null";
}
- Log.d("云音乐", a.toString());
+ Log.d("打印", a.toString());
floating.addtext(a.toString());
}
diff --git a/app/src/main/java/com/muqingbfq/mq/llq.java b/app/src/main/java/com/muqingbfq/mq/llq.java
index b0e8089..c61f948 100644
--- a/app/src/main/java/com/muqingbfq/mq/llq.java
+++ b/app/src/main/java/com/muqingbfq/mq/llq.java
@@ -12,6 +12,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
@@ -41,27 +42,26 @@ import okhttp3.Response;
public class llq extends AppCompatActivity {
WebView web;
-
@Override
protected ActivityLlqBinding getViewBindingObject(LayoutInflater layoutInflater) {
return ActivityLlqBinding.inflate(layoutInflater);
}
-
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void UI(@Nullable Bundle savedInstanceState) {
Intent intent = getIntent();
setSupportActionBar(binding.toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- web = findViewById(R.id.webview);
+ web = binding.webview;
web.getSettings().setJavaScriptEnabled(true);
+ web.getSettings().setDomStorageEnabled(true);
+// 禁用缓存
+ web.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
web.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
- String title = view.getTitle();
- setTitle(title);
- setSubtitle(url);
+ setTitle(web.getTitle());
// 在这里获取到了网页的标题
}
});
@@ -162,15 +162,9 @@ public class llq extends AppCompatActivity {
});
loadUrl(intent.getStringExtra("url"));
}
-
- private void setSubtitle(String url) {
- binding.toolbar.setSubtitle(url);
- }
-
private void loadUrl(String url) {
web.loadUrl(url);
}
-
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
@@ -180,13 +174,11 @@ public class llq extends AppCompatActivity {
gj.ts(this, "权限已授予,请重新执行文件下载操作");
}
}
-
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.llq, menu);
return super.onCreateOptionsMenu(menu);
}
-
@Override
public void onBackPressed() {
if (web.canGoBack()) {
@@ -195,8 +187,6 @@ public class llq extends AppCompatActivity {
finish();
}
}
-
-
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int itemId = item.getItemId();
@@ -213,4 +203,5 @@ public class llq extends AppCompatActivity {
}
return super.onOptionsItemSelected(item);
}
+
}
diff --git a/app/src/main/java/com/muqingbfq/sz.java b/app/src/main/java/com/muqingbfq/sz.java
index 1d2fdf4..bf2d486 100644
--- a/app/src/main/java/com/muqingbfq/sz.java
+++ b/app/src/main/java/com/muqingbfq/sz.java
@@ -17,18 +17,20 @@ import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
-import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import com.colorpicker.ColorPickerView;
import com.colorpicker.builder.ColorPickerDialogBuilder;
+import com.dirror.lyricviewx.LyricEntry;
+import com.dirror.lyricviewx.LyricViewX;
import com.google.android.material.materialswitch.MaterialSwitch;
import com.google.android.material.slider.Slider;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
+import com.muqingbfq.databinding.ActivitySzBinding;
import com.muqingbfq.databinding.ActivitySzSetlrcBinding;
+import com.muqingbfq.mq.AppCompatActivity;
import com.muqingbfq.mq.FloatingLyricsService;
import com.muqingbfq.mq.wj;
@@ -36,48 +38,40 @@ import java.io.File;
import java.lang.reflect.Type;
import java.util.Locale;
-import me.wcy.lrcview.LrcEntry;
-import me.wcy.lrcview.LrcView;
-
-public class sz extends AppCompatActivity {
+public class sz extends AppCompatActivity {
@Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_sz);
- Toolbar toolbar = findViewById(R.id.toolbar);
- setSupportActionBar(toolbar);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- toolbar.setTitle(getString(R.string.sz));
- UI();
- kaifazhe();
+ protected ActivitySzBinding getViewBindingObject(LayoutInflater layoutInflater) {
+ return ActivitySzBinding.inflate(layoutInflater);
}
+ @Override
+ protected void UI(Bundle bundle) {
+ setSupportActionBar(binding.toolbar);
+ getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ setTitle(getString(R.string.sz));
+ kaifazhe();
- @SuppressLint("ApplySharedPref")
- private void UI() {
- MaterialSwitch a1 = findViewById(R.id.switch_a1);
- MaterialSwitch a2 = findViewById(R.id.switch_a2);
SharedPreferences theme = getSharedPreferences("theme", MODE_PRIVATE);
@SuppressLint("CommitPrefEdits") SharedPreferences.Editor edit = theme.edit();
int i = theme.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
if (i == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
- a1.setChecked(true);
- a2.setEnabled(false);
+ binding.switchA1.setChecked(true);
+ binding.switchA2.setEnabled(false);
} else {
- a1.setChecked(false);
- a2.setEnabled(true);
- a2.setChecked(i == AppCompatDelegate.MODE_NIGHT_YES);
+ binding.switchA1.setChecked(false);
+ binding.switchA2.setEnabled(true);
+ binding.switchA2.setChecked(i == AppCompatDelegate.MODE_NIGHT_YES);
}
- a1.setOnCheckedChangeListener((compoundButton, b) -> {
+ binding.switchA1.setOnCheckedChangeListener((compoundButton, b) -> {
if (b) {
// 跟随系统设置切换颜色模式
int ms = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
AppCompatDelegate.setDefaultNightMode(ms);
edit.putInt("theme", ms);
- edit.commit();
+ edit.apply();
}
- a2.setEnabled(!b);
+ binding.switchA2.setEnabled(!b);
});
- a2.setOnCheckedChangeListener((compoundButton, b) -> {
+ binding.switchA2.setOnCheckedChangeListener((compoundButton, b) -> {
if (compoundButton.isEnabled()) {
int ms;
if (b) {
@@ -91,8 +85,6 @@ public class sz extends AppCompatActivity {
}
});
}
-
-
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
@@ -100,7 +92,6 @@ public class sz extends AppCompatActivity {
}
return super.onOptionsItemSelected(item);
}
-
ActivityResultLauncher intent = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
@@ -108,9 +99,9 @@ public class sz extends AppCompatActivity {
com.muqingbfq.mq.floating.start(sz.this);
}
});
-
public void kaifazhe() {
- MaterialSwitch materialSwitch = findViewById(R.id.switch_kfz);
+/* MaterialSwitch materialSwitch = findViewById(R.id
+ .switch_kfz);
materialSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
if (b) {
if (!Settings.canDrawOverlays(this)) {
@@ -123,10 +114,8 @@ public class sz extends AppCompatActivity {
} else {
com.muqingbfq.mq.floating.end(sz.this);
}
- });
+ });*/
}
-
-
public static class setlrc extends Fragment implements Slider.OnSliderTouchListener,
Slider.OnChangeListener {
ActivityResultLauncher LyricsService =
@@ -142,26 +131,17 @@ public class sz extends AppCompatActivity {
public void run() {
if (bfqkz.mt.isPlaying()) {
int index = 0;
- for (int i = 0; i < LrcView.mLrcEntryList.size(); i++) {
- LrcEntry lineLrc = LrcView.mLrcEntryList.get(i);
+ for (int i = 0; i < LyricViewX.lyricEntryList.size(); i++) {
+ LyricEntry lineLrc = LyricViewX.lyricEntryList.get(i);
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
index = i;
} else {
break;
}
}
- if (index < LrcView.mLrcEntryList.size()) {
+ if (index < LyricViewX.lyricEntryList.size()) {
String text;
- if (LrcView.mLrcEntryList.size() <= 3) {
- for (LrcEntry a : LrcView.mLrcEntryList) {
- if (a.time == 5940000 && a.text.equals("纯音乐,请欣赏")) {
- text = "纯音乐,请欣赏";
- binding.lrctext.setText(text);
- return;
- }
- }
- }
- LrcEntry currentLrc = LrcView.mLrcEntryList.get(index);
+ LyricEntry currentLrc = LyricViewX.lyricEntryList.get(index);
text = currentLrc.text;
if (currentLrc.secondText != null) {
text += "\n" + currentLrc.secondText;
@@ -207,11 +187,11 @@ public class sz extends AppCompatActivity {
binding.lrctext.setTextColor(selectedColor);
FloatingLyricsService.baocun(setup);
})
- .setNegativeButton("取消",null)
+ .setNegativeButton("取消", null)
.build()
.show());
binding.textSlide1.setText(String.valueOf(setup.size));
- binding.textSlide2.setText(String.format(Locale.US,"%.2f",setup.Alpha));
+ binding.textSlide2.setText(String.format(Locale.US, "%.2f", setup.Alpha));
if (setup.i != 0) {
binding.switchA1.setChecked(true);
}
@@ -282,10 +262,10 @@ public class sz extends AppCompatActivity {
setup.size,
getResources().getDisplayMetrics()));
binding.textSlide1.setText(String.valueOf(setup.size));
- }else if (slider == binding.slide2) {
+ } else if (slider == binding.slide2) {
setup.Alpha = value;
binding.lrctext.setAlpha(value);
- binding.textSlide2.setText(String.format(Locale.US,"%.2f", value));
+ binding.textSlide2.setText(String.format(Locale.US, "%.2f", value));
}
}
}
diff --git a/app/src/main/java/com/muqingbfq/view/Edit.java b/app/src/main/java/com/muqingbfq/view/Edit.java
index 4e2db27..de9bf46 100644
--- a/app/src/main/java/com/muqingbfq/view/Edit.java
+++ b/app/src/main/java/com/muqingbfq/view/Edit.java
@@ -9,6 +9,8 @@ import android.text.NoCopySpan;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
+import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
@@ -19,6 +21,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
+import com.google.android.material.textfield.TextInputLayout;
import com.muqingbfq.R;
public class Edit extends LinearLayout {
@@ -44,6 +47,8 @@ public class Edit extends LinearLayout {
public EditText editText;
private void initView() {
+ TextInputLayout layout = new TextInputLayout(getContext());
+// layout.clearIconDrawable
setGravity(Gravity.CENTER_VERTICAL);
setBackgroundResource(R.drawable.ui_editview);
setPadding(30, 0, 30, 0);
@@ -52,28 +57,29 @@ public class Edit extends LinearLayout {
editText.setHint("搜索");
editText.setSingleLine(true);
editText.setBackground(null);
+ editText.setTransitionName("edit");
+ Drawable startIcon = ContextCompat.getDrawable(getContext(), R.drawable.sousuo);
+ startIcon.setTint(ContextCompat.getColor(getContext(),
+ R.color.text_tm));
+ Drawable endIcon = ContextCompat.getDrawable(getContext(), R.drawable.chahao);
+ editText.setCompoundDrawablesRelativeWithIntrinsicBounds(startIcon, null, endIcon, null);
editText.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
+// editText.passwordToggleEnabled
addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence var1, int var2, int var3, int var4) {
-
}
-
@Override
public void onTextChanged(CharSequence var1, int var2, int var3, int var4) {
iskong();
}
-
@Override
public void afterTextChanged(Editable var1) {
-
}
});
ImageView imageView = new ImageView(getContext());
imageView.setImageResource(R.drawable.sousuo);
- imageView.setImageTintList(ContextCompat.getColorStateList(getContext(),
- R.color.text_tm));
addView(imageView, (int) TypedValue.applyDimension(TypedValue.
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics())
, (int) TypedValue.applyDimension(TypedValue.
@@ -106,23 +112,15 @@ public class Edit extends LinearLayout {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.Edit);
boolean isEnabled = a.getBoolean(R.styleable.Edit_Enabled, true);
if (!isEnabled) {
- removeView(editText);
removeView(imageView);
removeView(chahao);
- TextView textView = new TextView(getContext());
- textView.setTextColor(editText.getHintTextColors());
- textView.setText("搜索");
- // 将 px 值转换为 sp
- float v = TypedValue.applyDimension(
- TypedValue.COMPLEX_UNIT_PX,
- editText.getTextSize(),
- getResources().getDisplayMetrics()
- ) / getResources().getDisplayMetrics().scaledDensity;
- textView.setTextSize(v);
- setGravity(Gravity.CENTER);
- addView(textView);
- textView.setPadding(26, 26, 26, 26);
+// editText.setGravity(Gravity.CENTER);
+ editText.setFocusable(false);
+ editText.setFocusableInTouchMode(false);
+// editText.setEnabled(false);
+ editText.setClickable(false);
+
}
a.recycle();
}
diff --git a/app/src/main/res/drawable/chahao.xml b/app/src/main/res/drawable/chahao.xml
index bea8b18..6798919 100644
--- a/app/src/main/res/drawable/chahao.xml
+++ b/app/src/main/res/drawable/chahao.xml
@@ -2,8 +2,8 @@
xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="24"
android:viewportHeight="24"
- android:width="128dp"
- android:height="128dp">
+ android:width="26dp"
+ android:height="26dp">
diff --git a/app/src/main/res/drawable/like.xml b/app/src/main/res/drawable/like.xml
index bd91a72..220de45 100644
--- a/app/src/main/res/drawable/like.xml
+++ b/app/src/main/res/drawable/like.xml
@@ -1,8 +1,8 @@
+ android:width="26dp"
+ android:height="26dp">
diff --git a/lrcview/src/main/res/drawable-xxhdpi/lrc_play.png b/app/src/main/res/drawable/lrc_play.png
similarity index 100%
rename from lrcview/src/main/res/drawable-xxhdpi/lrc_play.png
rename to app/src/main/res/drawable/lrc_play.png
diff --git a/app/src/main/res/drawable/progress.xml b/app/src/main/res/drawable/progress.xml
new file mode 100644
index 0000000..370d3ba
--- /dev/null
+++ b/app/src/main/res/drawable/progress.xml
@@ -0,0 +1,24 @@
+
+ -
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/sousuo.xml b/app/src/main/res/drawable/sousuo.xml
index 5a0f98b..69327ab 100644
--- a/app/src/main/res/drawable/sousuo.xml
+++ b/app/src/main/res/drawable/sousuo.xml
@@ -1,7 +1,7 @@
-
- -
+
-
+ android:src="@mipmap/icon"
+ android:scaleType="center"/>
diff --git a/app/src/main/res/layout-land/activity_bfq.xml b/app/src/main/res/layout-land/activity_bfq.xml
index d5abfe4..5a96f0d 100644
--- a/app/src/main/res/layout-land/activity_bfq.xml
+++ b/app/src/main/res/layout-land/activity_bfq.xml
@@ -71,7 +71,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
-
-
+ android:layout_weight="1" />
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ app:layout_constraintTop_toBottomOf="@id/toolbar" />
-
+ app:layout_constraintTop_toBottomOf="@id/toolbar" />
+ app:layout_constraintEnd_toEndOf="parent">
-
+ android:singleLine="true"
+ android:text="@string/name"
+ android:textColor="@color/tint_image"
+ android:textSize="26sp"
+ android:textStyle="bold" />
-
-
-
-
-
-
+
+
+
+
+
+
+
+ app:layout_constraintBottom_toTopOf="@+id/layout2"
+ tools:ignore="MissingConstraints">
-
-
-
-
-
-
-
+ app:layout_constraintStart_toStartOf="parent">
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_gd.xml b/app/src/main/res/layout/activity_gd.xml
index 3d0bfd8..659ed78 100644
--- a/app/src/main/res/layout/activity_gd.xml
+++ b/app/src/main/res/layout/activity_gd.xml
@@ -14,7 +14,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="26sp"
- android:transitionName="view"
+ android:transitionName="text"
android:textColor="@color/text"/>
diff --git a/app/src/main/res/layout/activity_llq.xml b/app/src/main/res/layout/activity_llq.xml
index d4fb2b3..b0f96b5 100644
--- a/app/src/main/res/layout/activity_llq.xml
+++ b/app/src/main/res/layout/activity_llq.xml
@@ -1,22 +1,31 @@
-
-
-
+ android:layout_height="wrap_content"
+ android:fitsSystemWindows="true">
+
+
+
+
+
+
-
\ No newline at end of file
+ android:layout_height="match_parent"
+ app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_mp3.xml b/app/src/main/res/layout/activity_mp3.xml
index d46fad8..ac19edc 100644
--- a/app/src/main/res/layout/activity_mp3.xml
+++ b/app/src/main/res/layout/activity_mp3.xml
@@ -8,7 +8,6 @@
@@ -22,6 +21,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/text"
+ android:transitionName="text"
android:textSize="26sp" />
-
-
+
+
+
-
-
+ app:defaultMarginsEnabled="true"
+ app:hideNavigationIcon="false"
+ app:navigationIcon="@drawable/end"
+ android:transitionName="edit"
+ android:hint="@string/search"/>
+
@@ -60,21 +76,15 @@
android:name="com.muqingbfq.fragment.search"
android:visibility="gone"
tools:layout="@layout/fragment_search" />
-
-
-
-
+
diff --git a/app/src/main/res/layout/activity_sz.xml b/app/src/main/res/layout/activity_sz.xml
index 0529ba3..45df15e 100644
--- a/app/src/main/res/layout/activity_sz.xml
+++ b/app/src/main/res/layout/activity_sz.xml
@@ -4,8 +4,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
android:fitsSystemWindows="true"
+ android:orientation="vertical"
tools:context=".sz">
+ android:layout_height="match_parent"
+ android:layout_marginHorizontal="10dp">
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+ android:layout_marginTop="6dp"
+ android:layout_marginBottom="6dp"
+ android:text="主题"/>
+ android:textSize="20sp"
+ android:text="跟随系统模式来选择" />
-
-
-
-
-
-
-
-
-
-
+
-
+ app:cardUseCompatPadding="true"
+ app:contentPadding="10dp">
+ android:layout_height="wrap_content">
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_gd.xml b/app/src/main/res/layout/fragment_gd.xml
index 66da644..ca182da 100644
--- a/app/src/main/res/layout/fragment_gd.xml
+++ b/app/src/main/res/layout/fragment_gd.xml
@@ -8,23 +8,20 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
-
-
-
+ android:layout_height="wrap_content"
+ android:transitionName="edit"
+ app:layout_scrollFlags="exitUntilCollapsed"
+ android:hint="@string/search"/>
+ app:cardUseCompatPadding="true">
@@ -72,17 +66,14 @@
+ app:cardUseCompatPadding="true">
diff --git a/app/src/main/res/layout/view_button.xml b/app/src/main/res/layout/view_button.xml
index 6d99ef4..4f05f74 100644
--- a/app/src/main/res/layout/view_button.xml
+++ b/app/src/main/res/layout/view_button.xml
@@ -20,5 +20,6 @@
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:transitionName="text"
android:text="@string/app_name"/>
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
deleted file mode 100644
index 34a3d9006b8c926c47ba0835861566c8add6fb30..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2344
zcmV+@3D@>gNk&E>2><|BMM6+kP&iBz2><{uN5Byfm4<<|ZBqZTKdvDnCZMfL6Do*h
z)yQq@Eq~j#vw5EMvu)e9ZQGvtlWp6!ZQHhO+gm#&Z_}iI!SKwA=)VKEZ5&C?UcZ5+
z?jLAv+hjLKT=&I_f`u;$4O-{MGBP7_iZQ4=p
zd!I?(XI0FyZQHhO+cvsj+qTt(*tU~*?_UliNsXIbh!6;ZZ~F`ElqfvZ4D>vnhV)QJ
zOKjBzH8E{MHNR%~1GHl^jK!8Zn~W@)ahb8t%;?AAxCd|IZ%oA!RjV4Ss#cXmwG?;z
z=x1iyH7?Tkm@ynz;tMQP1QJUI0T$x(&}a70;+7TDKEwWa1PofHfMmH;7oAq*)T7<&kjF}@o@^-S~pC41vMZ9t=qLM}q0{SJUL^AyG=
zgse8-qZnSIA)y%pw~mjfNo@<^pP0jMd0(u3WZQMT72DF0Mvjt
zoHGINSBuwV<@kQ1aX=kJ{+W%r@Xl6Uz`RG?d0w9abz=F@;>I_il>;dFGoQ$>G#5S?
zo*Q8cNVzsT_MCH_q8o3|2+*{r@cKydP_fS8iV9UOwow6=BrO(kt!lvF`-A}o#&~Zc
z1if!5M+SCV&xP~dDW*L+Re7ScTHNBuA|+7#Nf=03;D;k1C=i1-a#LGktOn5Sc#fF5
zaQf&H1?ENWWp3OK035;yP|-i`QvihrdhVws2FTH`%8rOxJnF@q4iR^`RTkh^5=GNr
zuz8-x8#oHd+M?E0BS4-0PuVQDhf^Ti>Ln-U>F7-$1cX95QWrNM$U}`E3KNAEnfJp0
zKTVXNc_j!?{t_o%t=~dyRZ8qBIxVLBTz@@5R9avP-Rb_XC3#+Q1g|@9_=GS}bwk@S
zUTq`lw5ia`BtZKolKl>^I4Rvez{_eT05T-&vbM_ZJt%#*1U
zIG&V_^4)zuhlbVtLQ14aU-bnY{s#)aG_qJ|MmNAX5%1qVdvI|;ZiETYvEELY(2^q(
zm3du@DV%+8Tn;C|8oHg__A0H=;deW7c>3H
zX22rCMM%Y8|G`Bg>fr3YZAM+dWWFSVLga{PhnbtgC9<;w!MBgVNjEICfbEY%3KRMP
zM!(`oJcK_MQ(!^L9B-ZhTlxL~mNzCUOfAh2fZk^5BS40^eGXXYeuVN@6kxkA{J9=W>vbTY-?x=)+6}D653r|f;QRZg
zx#$3^0VrQ}hTCs%kMywFO7OoJDDw?@4kM&2^1(y!vFUxlzhP1l^CRX1>;Tbq@U7>P
z_vO`mpoIx`tAOvmQH*X8K>9gn76cn2%zUgJBAP#2+|qZu0h8G7{lqeyyyZ0mG|XH@
zuo`g98*PM;`s<$%d92-NQ8E}e&(32WK3yr+1op^wVRUX-gU{|q4xmqk
z#y&1w491;SGxz`pME&|)VDbL;VnviJdzCRVI}M=v4bntBeRIkVwA)+(?XL%sNVCWX
zZzd0LSSUZGgR$qJfhvXNv;0BtT18ozWJ>QbCTGnd_2HXC))4>e4NfLIb`-HtNORS8
z!@;<~Vg3u9si6ibdB>En9pRjm5>o)#F3zS*p!_UxiZ3Bcg_yP-f=kD5=>hMEN
zxHnM)>>EC|Y{gUjoHl3A@GxryWj-tz!uOxpRfRbG9(lZF#qnRP9$E5V_3l$4Jmt#V
z+XXR~uIN>XyWdAin>uGL#P00^VFSqy9!R);bGJgIDR9fG3NvX_mu`=@_S#Wq(AM!n
ziwjn@R!WrVl2k**e^qC$g%)f2Kx4Ki8~Y(~pDDkm?ilT_t
zWmTOdB}VwSAU4bb%H%^14FMS9i@H2`!-G(!*~){K5ObbNU&hhy*cF5sx##KRF-1
zt1@(i7WLI#pj)))+*sRKCLCg+Ep%RR@X4zlxcJuNZ~y+D)R@;^+FhB}oAUlhs=fXA
z!HXxaT5vFQfwmC0O!(RcS#A=vMeOT%7Yv6OXbJ70(@foG>b>CLwZ?2TKFR7c^_qlE
zA+(HZ>v$KjgU0SNSlYI>v8HdiuvsG@GKM&auX%A$T`p|0zO>DKj|D*l8(3DhZfW1Z
OF%|e5SU_`pNC5zRe2hQ<
diff --git a/app/src/main/res/mipmap-hdpi/logo.png b/app/src/main/res/mipmap-hdpi/logo.png
deleted file mode 100644
index ce1488957a2e956960949ef20236104438f255f4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2304
zcmV+b3IFzqP)Px-x=BPqRCr$PS`UmJWf7nG_Ia0FYHiU-%4wsbP?gqTH9d;g3jT&!R21_8T+j
z+jDPk_wBxacL(hxo4dUIzWL_&+u3jDn;C=?T<`?P4<`vY=>c<)0U}yttv$^c(`K!G
z9smvz0T90ifIWpmVf*0V;NR-eGou7}p0`>=2mszwkFize>=%*k?d|Qu
z0|Nv4%H)yu4*>ogUgP8AFLZQtEHK6_Kt%n!6cIlR0D2Xw=zLg2z7zz(_p(T6DFH;(4*;7|
zjCdLV?hui?f*=^pGBkSM^So0;q+3MRBI1YA<|5+dzVCm%n(menKt#U>fVUhE0J^3ITmJ`(_$%M{-`gqz9tME7#elA5=5Nm=_;9VBo*t*Ov-5`l@X^@%
z*D&)y_*+vvAm!-~F!MFD0Y2gh?*ae~mz{_m^X8o?B6=-J2zIVw=Iyf$Ue_-ci}M}F
zQ7>2)BcUq@g1xz4flBnXUPM+S;+X)@kpb{g5xD~Z?g@fm_iU2ky6zf8jPFJL%zSMo
z0h=~$Y8xLPUyq1a0l*vU1hUH*GqQE-)}Pclzu{>_q~{FX6GGX`%w1IpD3wZ|Fvj#H
z?Cy0Lgor-^fKU0p|M$8SG%(5Yyp1BVIrbVXNhP3EDqU%e$$F3f2>{O`;K;kC@HiH(MZi0%h~6){B(kz1=#
zl`OQr-uv~TP7**w8aH1QQ#i`Z7uUK-wedtGvHN#2^ZCtOqZVBg1bCjeMnvL)Les(P
zTCVG^Kt%O~39;68m&@fTN7PyXG&**I0M~WL5V0$w>|fT}uJFLn=psq;UDw^%#;GwD@`7C9Oq&s;7i~I0^Aqxpi`n<->^f)3?_q{8!?)#Ye?!0y+5iq5cHP=6btsp=f
z7yKxL*4lH*<+A3`=A1O00MGL}MdZmC(wmw2({m2}|2DDaz5e#QM5Lv-4<_KyviOly0(64sc{hrPmcgcoz7EEi
z%|k;&`?eCbxRC3*w<6-&1QHI4
z$S(n47c<}5N+J@Hr@EYWm}#*k)dPq~^NXt@woQo?r$vHkAc*M80I)s-q&6$-^;pHV
zvN(B~nMbk)B|LeZqInA~uIf{)MnLp*J1w!Bn}Eumpgnk70H8C==vwYGbG4e}YGaIU
zR-q_h?KZhnf5_SdiAW#F8I{SqnR!YhB@rok;c@uM%<}k#4I7qNYqzA7%WA8BSd5|04z4fEUx_Do`Z~MthGDK
z?sa#wIje#XUf~PA&}Rx3#s+kGIGZ(G39bxeR+IN^*4(kOOGlLx@N_!K0ldKh?Uv
zwN~5kRw3dQ5#?jdyfVd;%Gx57V#qdT*4EnknxyJRmvdr{lvk)}^8HRyt>t;gao#B+
z69rjB+X0Z5T)^Wmn
az<&X}e}Ie00XgCT0000
-
-
-
-
-
-
-
@@ -33,4 +26,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index f48e1a2..f99fc3e 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -19,4 +19,12 @@
#625B71
#FFCCCC
+
+ #F1F1F1
+
+ #A2A2A2
+ #000000
+ #343434
+ #809E9E9E
+ #809E9E9E
\ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index 2ddfcbd..939ca54 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -2,6 +2,17 @@
16dp
+
+
+ 36dp
+ 24dp
+ 4dp
+ 10dp
+ 24dp
+ 40dp
+ 36dp
+ 20dp
+
1000
16sp
12sp
@@ -11,13 +22,4 @@
1dp
30dp
40dp
-
- 36dp
- 24dp
- 4dp
- 10dp
- 24dp
- 40dp
- 36dp
- 20dp
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 23e0ea3..4f260fb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -44,4 +44,10 @@
- 男
- 女
+
+
+ - 跟随系统
+ - 浅色模式
+ - 深色模式
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 47d549f..b70fa50 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,4 +1,18 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.1.0' apply false
+ id 'org.jetbrains.kotlin.jvm' version '1.8.0'
+}
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
+}
+compileKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
+compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
}
diff --git a/lrcview/.gitignore b/lrcview/.gitignore
deleted file mode 100644
index 796b96d..0000000
--- a/lrcview/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/build
diff --git a/lrcview/build.gradle b/lrcview/build.gradle
deleted file mode 100644
index d8417cb..0000000
--- a/lrcview/build.gradle
+++ /dev/null
@@ -1,22 +0,0 @@
-apply plugin: 'com.android.library'
-apply plugin: 'maven-publish'
-
-android {
- namespace 'me.wcy.lrcview'
- compileSdk 34
- defaultConfig {
- minSdkVersion 23
- //noinspection ExpiredTargetSdkVersion
- targetSdk 31
- versionCode 1
- versionName "1.0"
- }
- compileOptions {
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
- }
-}
-dependencies {
- implementation 'androidx.appcompat:appcompat:1.6.1'
- implementation 'com.google.android.material:material:1.9.0'
-}
\ No newline at end of file
diff --git a/lrcview/src/main/AndroidManifest.xml b/lrcview/src/main/AndroidManifest.xml
deleted file mode 100644
index 05ecef7..0000000
--- a/lrcview/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/lrcview/src/main/java/me/wcy/lrcview/LrcEntry.java b/lrcview/src/main/java/me/wcy/lrcview/LrcEntry.java
deleted file mode 100644
index 0a5a764..0000000
--- a/lrcview/src/main/java/me/wcy/lrcview/LrcEntry.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2017 wangchenyan
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package me.wcy.lrcview;
-
-import android.text.Layout;
-import android.text.StaticLayout;
-import android.text.TextPaint;
-import android.text.TextUtils;
-
-/**
- * 一行歌词实体
- */
-public class LrcEntry implements Comparable {
- public long time;
- public String text, secondText;
- private StaticLayout staticLayout;
- /**
- * 歌词距离视图顶部的距离
- */
- private float offset = Float.MIN_VALUE;
- public static final int GRAVITY_CENTER = 0;
- public static final int GRAVITY_LEFT = 1;
- public static final int GRAVITY_RIGHT = 2;
-
- LrcEntry(long time, String text) {
- this.time = time;
- this.text = text;
- }
-
- LrcEntry(long time, String text, String secondText) {
- this.time = time;
- this.text = text;
- this.secondText = secondText;
- }
-
- void init(TextPaint paint, int width, int gravity) {
- Layout.Alignment align;
- switch (gravity) {
- case GRAVITY_LEFT:
- align = Layout.Alignment.ALIGN_NORMAL;
- break;
-
- default:
- case GRAVITY_CENTER:
- align = Layout.Alignment.ALIGN_CENTER;
- break;
-
- case GRAVITY_RIGHT:
- align = Layout.Alignment.ALIGN_OPPOSITE;
- break;
- }
- staticLayout = new StaticLayout(
- getShowText(), paint, width, align, 1f, 0f, false);
-
- offset = Float.MIN_VALUE;
- }
-
- long getTime() {
- return time;
- }
-
- StaticLayout getStaticLayout() {
- return staticLayout;
- }
-
- int getHeight() {
- if (staticLayout == null) {
- return 0;
- }
- return staticLayout.getHeight();
- }
-
- public float getOffset() {
- return offset;
- }
-
- public void setOffset(float offset) {
- this.offset = offset;
- }
-
- String getText() {
- return text;
- }
-
-
- void setSecondText(String secondText) {
- this.secondText = secondText;
- }
-
- public String getShowText() {
- if (!TextUtils.isEmpty(secondText)) {
- return text + "\n" + secondText;
- } else {
- return text;
- }
- }
-
- @Override
- public int compareTo(LrcEntry entry) {
- if (entry == null) {
- return -1;
- }
- return (int) (time - entry.getTime());
- }
-}
diff --git a/lrcview/src/main/java/me/wcy/lrcview/LrcUtils.java b/lrcview/src/main/java/me/wcy/lrcview/LrcUtils.java
deleted file mode 100644
index bd088b5..0000000
--- a/lrcview/src/main/java/me/wcy/lrcview/LrcUtils.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2017 wangchenyan
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package me.wcy.lrcview;
-
-import android.animation.ValueAnimator;
-import android.annotation.SuppressLint;
-import android.os.Build;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.lang.reflect.Field;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * 工具类
- */
-class LrcUtils {
- private static final Pattern PATTERN_LINE = Pattern.compile("((\\[\\d\\d:\\d\\d\\.\\d{2,3}\\])+)(.+)");
- private static final Pattern PATTERN_TIME = Pattern.compile("\\[(\\d\\d):(\\d\\d)\\.(\\d{2,3})\\]");
-
- /**
- * 从文件解析双语歌词
- */
- static List parseLrc(File[] lrcFiles) {
- if (lrcFiles == null || lrcFiles.length != 2 || lrcFiles[0] == null) {
- return null;
- }
-
- File mainLrcFile = lrcFiles[0];
- File secondLrcFile = lrcFiles[1];
- List mainEntryList = parseLrc(mainLrcFile);
- List secondEntryList = parseLrc(secondLrcFile);
-
- if (mainEntryList != null && secondEntryList != null) {
- for (LrcEntry mainEntry : mainEntryList) {
- for (LrcEntry secondEntry : secondEntryList) {
- if (mainEntry.getTime() == secondEntry.getTime()) {
- mainEntry.setSecondText(secondEntry.getText());
- }
- }
- }
- }
- return mainEntryList;
- }
-
- /**
- * 从文件解析歌词
- */
- private static List parseLrc(File lrcFile) {
- if (lrcFile == null || !lrcFile.exists()) {
- return null;
- }
-
- List entryList = new ArrayList<>();
- try {
- @SuppressLint({"NewApi", "LocalSuppress"})
- BufferedReader br = new BufferedReader(new InputStreamReader(
- Files.newInputStream(lrcFile.toPath()), StandardCharsets.UTF_8));
- String line;
- while ((line = br.readLine()) != null) {
- List list = parseLine(line);
- if (list != null && !list.isEmpty()) {
- entryList.addAll(list);
- }
- }
- br.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- Collections.sort(entryList);
- return entryList;
- }
-
- /**
- * 从文本解析双语歌词
- */
- static List parseLrc(String[] lrcTexts) {
- if (lrcTexts == null || lrcTexts.length != 2 || TextUtils.isEmpty(lrcTexts[0])) {
- return null;
- }
-
- String mainLrcText = lrcTexts[0];
- String secondLrcText = lrcTexts[1];
- List mainEntryList = parseLrc(mainLrcText);
- List secondEntryList = parseLrc(secondLrcText);
-
- if (mainEntryList != null && secondEntryList != null) {
- for (LrcEntry mainEntry : mainEntryList) {
- for (LrcEntry secondEntry : secondEntryList) {
- if (mainEntry.getTime() == secondEntry.getTime()) {
- mainEntry.setSecondText(secondEntry.getText());
- }
- }
- }
- }
- return mainEntryList;
- }
-
- /**
- * 从文本解析歌词
- */
- private static List parseLrc(String lrcText) {
- if (TextUtils.isEmpty(lrcText)) {
- return null;
- }
-
- if (lrcText.startsWith("\uFEFF")) {
- lrcText = lrcText.replace("\uFEFF", "");
- }
-
- List entryList = new ArrayList<>();
- String[] array = lrcText.split("\\n");
- for (String line : array) {
- List list = parseLine(line);
- if (list != null && !list.isEmpty()) {
- entryList.addAll(list);
- }
- }
-
- Collections.sort(entryList);
- return entryList;
- }
-
- /**
- * 获取网络文本,需要在工作线程中执行
- */
- static String getContentFromNetwork(String url, String charset) {
- String lrcText = null;
- try {
- URL _url = new URL(url);
- HttpURLConnection conn = (HttpURLConnection) _url.openConnection();
- conn.setRequestMethod("GET");
- conn.setConnectTimeout(10000);
- conn.setReadTimeout(10000);
- if (conn.getResponseCode() == 200) {
- InputStream is = conn.getInputStream();
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len;
- while ((len = is.read(buffer)) != -1) {
- bos.write(buffer, 0, len);
- }
- is.close();
- bos.close();
- lrcText = bos.toString(charset);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return lrcText;
- }
-
- /**
- * 解析一行歌词
- */
- private static List parseLine(String line) {
- if (TextUtils.isEmpty(line)) {
- return null;
- }
-
- line = line.trim();
- // [00:17.65]让我掉下眼泪的
- Matcher lineMatcher = PATTERN_LINE.matcher(line);
- if (!lineMatcher.matches()) {
- return null;
- }
-
- String times = lineMatcher.group(1);
- String text = lineMatcher.group(3);
- List entryList = new ArrayList<>();
-
- // [00:17.65]
- Matcher timeMatcher = PATTERN_TIME.matcher(times);
- while (timeMatcher.find()) {
- long min = Long.parseLong(timeMatcher.group(1));
- long sec = Long.parseLong(timeMatcher.group(2));
- String milString = timeMatcher.group(3);
- long mil = Long.parseLong(milString);
- // 如果毫秒是两位数,需要乘以10
- if (milString.length() == 2) {
- mil = mil * 10;
- }
- long time = min * DateUtils.MINUTE_IN_MILLIS + sec * DateUtils.SECOND_IN_MILLIS + mil;
- entryList.add(new LrcEntry(time, text));
- }
- return entryList;
- }
-
- /**
- * 转为[分:秒]
- */
- static String formatTime(long milli) {
- int m = (int) (milli / DateUtils.MINUTE_IN_MILLIS);
- int s = (int) ((milli / DateUtils.SECOND_IN_MILLIS) % 60);
- String mm = String.format(Locale.getDefault(), "%02d", m);
- String ss = String.format(Locale.getDefault(), "%02d", s);
- return mm + ":" + ss;
- }
-
- /**
- * 强制开启动画
- * Android 10 以后无法使用
- */
- static void resetDurationScale() {
- try {
- if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
- @SuppressLint("DiscouragedPrivateApi")
- Field mField = ValueAnimator.class.getDeclaredField("sDurationScale");
- mField.setAccessible(true);
- mField.setFloat(null, 1);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/lrcview/src/main/java/me/wcy/lrcview/LrcView.java b/lrcview/src/main/java/me/wcy/lrcview/LrcView.java
deleted file mode 100644
index 8eabeb9..0000000
--- a/lrcview/src/main/java/me/wcy/lrcview/LrcView.java
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * Copyright (C) 2017 wangchenyan
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-package me.wcy.lrcview;
-
-import android.animation.ValueAnimator;
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
-import android.os.Looper;
-import android.text.Layout;
-import android.text.StaticLayout;
-import android.text.TextPaint;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.animation.LinearInterpolator;
-import android.widget.Scroller;
-
-import androidx.annotation.NonNull;
-import androidx.core.content.ContextCompat;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-/**
- * 歌词
- * Created by wcy on 2015/11/9.
- *
- * @noinspection unused
- */
-@SuppressLint("StaticFieldLeak")
-public class LrcView extends View {
- private static final String TAG = "LrcView";
- private static final long ADJUST_DURATION = 100;
- private static final long TIMELINE_KEEP_TIME = 4 * DateUtils.SECOND_IN_MILLIS;
- public static List mLrcEntryList = new ArrayList<>();
- private TextPaint mLrcPaint = new TextPaint(), mTimePaint = new TextPaint();
- private Paint.FontMetrics mTimeFontMetrics;
- private Drawable mPlayDrawable;
- private float mDividerHeight;
- private long mAnimationDuration;
- private int mNormalTextColor;
- private float mNormalTextSize;
- private int mCurrentTextColor;
- private float mCurrentTextSize;
- private int mTimelineTextColor;
- private int mTimelineColor;
- private int mTimeTextColor;
- private int mDrawableWidth;
- private int mTimeTextWidth;
- private String mDefaultLabel;
- private float mLrcPadding;
- private OnPlayClickListener mOnPlayClickListener;
- private OnTapListener mOnTapListener;
- private ValueAnimator mAnimator;
- private GestureDetector mGestureDetector;
- private Scroller mScroller;
- private float mOffset;
- private int mCurrentLine;
- private Object mFlag;
- private boolean isShowTimeline;
- private boolean isTouching;
- private boolean isFling;
- /**
- * 歌词显示位置,靠左/居中/靠右
- */
- private int mTextGravity;
-
- /**
- * 播放按钮点击监听器,点击后应该跳转到指定播放位置
- */
- public interface OnPlayClickListener {
- /**
- * 播放按钮被点击,应该跳转到指定播放位置
- *
- * @param view 歌词控件
- * @param time 选中播放进度
- * @return 是否成功消费该事件,如果成功消费,则会更新UI
- */
- boolean onPlayClick(LrcView view, long time);
- }
-
- /**
- * 歌词控件点击监听器
- */
- public interface OnTapListener {
- /**
- * 歌词控件被点击
- *
- * @param view 歌词控件
- * @param x 点击坐标x,相对于控件
- * @param y 点击坐标y,相对于控件
- */
- void onTap(LrcView view, float x, float y);
- }
-
- public LrcView(Context context) {
- this(context, null);
- init(null);
- }
-
- public LrcView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- init(attrs);
- }
-
- public LrcView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- init(attrs);
- }
-
- private void init(AttributeSet attrs) {
- TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.LrcView);
- mCurrentTextSize = ta.getDimension(R.styleable.LrcView_lrcTextSize,
- getResources().getDimension(R.dimen.lrc_text_size));
- mNormalTextSize = ta.getDimension(R.styleable.LrcView_lrcNormalTextSize,
- getResources().getDimension(R.dimen.lrcNormalTextSize));
- if (mNormalTextSize == 0) {
- mNormalTextSize = mCurrentTextSize;
- }
-
- mDividerHeight = ta.getDimension(R.styleable.LrcView_lrcDividerHeight, getResources().getDimension(R.dimen.lrc_divider_height));
- int defDuration = getResources().getInteger(R.integer.lrc_animation_duration);
- mAnimationDuration = ta.getInt(R.styleable.LrcView_lrcAnimationDuration, defDuration);
- mAnimationDuration = (mAnimationDuration < 0) ? defDuration : mAnimationDuration;
- mNormalTextColor = ta.getColor(R.styleable.LrcView_lrcNormalTextColor,
- ContextCompat.getColor(getContext(), R.color.lrc_normal_text_color));
- mCurrentTextColor = ta.getColor(R.styleable.LrcView_lrcCurrentTextColor,
- ContextCompat.getColor(getContext(), R.color.lrc_current_text_color));
- mTimelineTextColor = ta.getColor(R.styleable.LrcView_lrcTimelineTextColor,
- ContextCompat.getColor(getContext(), R.color.lrc_timeline_text_color));
- mDefaultLabel = ta.getString(R.styleable.LrcView_lrcLabel);
- mDefaultLabel = TextUtils.isEmpty(mDefaultLabel) ? getContext().getString(R.string.lrc_label) : mDefaultLabel;
- mLrcPadding = ta.getDimension(R.styleable.LrcView_lrcPadding, 0);
- mTimelineColor = ta.getColor(R.styleable.LrcView_lrcTimelineColor,
- ContextCompat.getColor(getContext(), R.color.lrc_timeline_color));
- float timelineHeight = ta.getDimension(R.styleable.LrcView_lrcTimelineHeight, getResources().getDimension(R.dimen.lrc_timeline_height));
- mPlayDrawable = ta.getDrawable(R.styleable.LrcView_lrcPlayDrawable);
- mPlayDrawable = (mPlayDrawable == null) ?
- ContextCompat.getDrawable(getContext(), R.drawable.lrc_play) : mPlayDrawable;
- mTimeTextColor = ta.getColor(R.styleable.LrcView_lrcTimeTextColor,
- ContextCompat.getColor(getContext(), R.color.lrc_time_text_color));
- float timeTextSize = ta.getDimension(R.styleable.LrcView_lrcTimeTextSize, getResources().getDimension(R.dimen.lrc_time_text_size));
- mTextGravity = ta.getInteger(R.styleable.LrcView_lrcTextGravity, LrcEntry.GRAVITY_CENTER);
-
- ta.recycle();
-
- mDrawableWidth = (int) getResources().getDimension(R.dimen.lrc_drawable_width);
- mTimeTextWidth = (int) getResources().getDimension(R.dimen.lrc_time_width);
-
- mLrcPaint.setAntiAlias(true);
- mLrcPaint.setTextSize(mCurrentTextSize);
- mLrcPaint.setTextAlign(Paint.Align.LEFT);
- mTimePaint.setAntiAlias(true);
- mTimePaint.setTextSize(timeTextSize);
- mTimePaint.setTextAlign(Paint.Align.CENTER);
- //noinspection SuspiciousNameCombination
- mTimePaint.setStrokeWidth(timelineHeight);
- mTimePaint.setStrokeCap(Paint.Cap.ROUND);
- mTimeFontMetrics = mTimePaint.getFontMetrics();
-
- mGestureDetector = new GestureDetector(getContext(), mSimpleOnGestureListener);
- mGestureDetector.setIsLongpressEnabled(false);
- mScroller = new Scroller(getContext());
- }
-
- /**
- * 设置非当前行歌词字体颜色
- */
- public void setNormalColor(int normalColor) {
- mNormalTextColor = normalColor;
- postInvalidate();
- }
-
- /**
- * 普通歌词文本字体大小
- */
- public void setNormalTextSize(float size) {
- mNormalTextSize = size;
- }
-
- /**
- * 当前歌词文本字体大小
- */
- public void setCurrentTextSize(float size) {
- mCurrentTextSize = size;
- }
-
- /**
- * 设置当前行歌词的字体颜色
- */
- public void setCurrentColor(int currentColor) {
- mCurrentTextColor = currentColor;
- postInvalidate();
- }
-
- /**
- * 设置拖动歌词时选中歌词的字体颜色
- */
- public void setTimelineTextColor(int timelineTextColor) {
- mTimelineTextColor = timelineTextColor;
- postInvalidate();
- }
-
- /**
- * 设置拖动歌词时时间线的颜色
- */
- public void setTimelineColor(int timelineColor) {
- mTimelineColor = timelineColor;
- postInvalidate();
- }
-
- /**
- * 设置拖动歌词时右侧时间字体颜色
- */
- public void setTimeTextColor(int timeTextColor) {
- mTimeTextColor = timeTextColor;
- postInvalidate();
- }
-
- /**
- * 设置歌词是否允许拖动
- *
- * @param draggable 是否允许拖动
- * @param onPlayClickListener 设置歌词拖动后播放按钮点击监听器,如果允许拖动,则不能为 null
- */
- public void setDraggable(boolean draggable, OnPlayClickListener onPlayClickListener) {
- if (draggable) {
- if (onPlayClickListener == null) {
- throw new IllegalArgumentException("if draggable == true, onPlayClickListener must not be null");
- }
- mOnPlayClickListener = onPlayClickListener;
- } else {
- mOnPlayClickListener = null;
- }
- }
-
- /**
- * 设置播放按钮点击监听器
- *
- * @param onPlayClickListener 如果为非 null ,则激活歌词拖动功能,否则将将禁用歌词拖动功能
- * @deprecated use {@link #setDraggable(boolean, OnPlayClickListener)} instead
- */
- @Deprecated
- public void setOnPlayClickListener(OnPlayClickListener onPlayClickListener) {
- mOnPlayClickListener = onPlayClickListener;
- }
-
- /**
- * 设置歌词控件点击监听器
- *
- * @param onTapListener 歌词控件点击监听器
- */
- public void setOnTapListener(OnTapListener onTapListener) {
- mOnTapListener = onTapListener;
- }
-
- /**
- * 设置歌词为空时屏幕中央显示的文字,如“暂无歌词”
- */
- public void setLabel(String label) {
- runOnUi(() -> {
- mDefaultLabel = label;
- invalidate();
- });
- }
-
- /**
- * 加载歌词文件
- *
- * @param lrcFile 歌词文件
- */
- public void loadLrc(File lrcFile) {
- loadLrc(lrcFile, null);
- }
-
- /**
- * 加载双语歌词文件,两种语言的歌词时间戳需要一致
- *
- * @param mainLrcFile 第一种语言歌词文件
- * @param secondLrcFile 第二种语言歌词文件
- */
- public void loadLrc(File mainLrcFile, File secondLrcFile) {
- runOnUi(() -> {
- reset();
-
- StringBuilder sb = new StringBuilder("file://");
- sb.append(mainLrcFile.getPath());
- if (secondLrcFile != null) {
- sb.append("#").append(secondLrcFile.getPath());
- }
- String flag = sb.toString();
- setFlag(flag);
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Callable> callable = () -> LrcUtils.parseLrc(new File[]{mainLrcFile, secondLrcFile});
- Future> future = executor.submit(callable);
- try {
- List lrcEntries = future.get();
- if (getFlag() == flag) {
- onLrcLoaded(lrcEntries);
- setFlag(null);
- }
- } catch (InterruptedException e) {
- // 处理中断异常
- e.printStackTrace();
- } catch (ExecutionException e) {
- // 处理执行异常
- e.printStackTrace();
- }
-// 关闭线程池
- executor.shutdown();
- });
- }
-
- /**
- * 加载歌词文本
- *
- * @param lrcText 歌词文本
- */
- public void loadLrc(String lrcText) {
- loadLrc(lrcText, null);
- }
-
- /**
- * 加载双语歌词文本,两种语言的歌词时间戳需要一致
- *
- * @param mainLrcText 第一种语言歌词文本
- * @param secondLrcText 第二种语言歌词文本
- */
- public void loadLrc(String mainLrcText, String secondLrcText) {
- runOnUi(() -> {
- reset();
-
- StringBuilder sb = new StringBuilder("file://");
- sb.append(mainLrcText);
- if (secondLrcText != null) {
- sb.append("#").append(secondLrcText);
- }
- String flag = sb.toString();
- setFlag(flag);
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Callable> callable = () -> LrcUtils.parseLrc(
- new String[]{mainLrcText, secondLrcText});
- Future> future = executor.submit(callable);
- try {
- List lrcEntries = future.get();
- if (getFlag() == flag) {
- onLrcLoaded(lrcEntries);
- setFlag(null);
- }
- } catch (InterruptedException e) {
- // 处理中断异常
- e.printStackTrace();
- } catch (ExecutionException e) {
- // 处理执行异常
- e.printStackTrace();
- }
-// 关闭线程池
- executor.shutdown();
- });
- }
-
- public static void Lrc(String mainLrcText, String secondLrcText) {
- StringBuilder sb = new StringBuilder("file://");
- sb.append(mainLrcText);
- if (secondLrcText != null) {
- sb.append("#").append(secondLrcText);
- }
- String flag = sb.toString();
- ExecutorService executor = Executors.newSingleThreadExecutor();
- Callable> callable = () -> LrcUtils.parseLrc(
- new String[]{mainLrcText, secondLrcText});
- Future> future = executor.submit(callable);
- try {
- mLrcEntryList = future.get();
- } catch (InterruptedException e) {
- // 处理中断异常
- e.printStackTrace();
- } catch (ExecutionException e) {
- // 处理执行异常
- e.printStackTrace();
- }
-// 关闭线程池
- executor.shutdown();
- }
-
- /**
- * 歌词是否有效
- *
- * @return true,如果歌词有效,否则false
- */
- public boolean hasLrc() {
- return !mLrcEntryList.isEmpty();
- }
-
- /**
- * 刷新歌词
- * time 当前播放时间
- */
-
- public int index = 0;
- public void updateTime(long time) {
- if (mOnPlayClickListener == null) {
- runOnUi(() -> {
- if (!hasLrc()) {
- return;
- }
- index = findShowLine(time);
- invalidate();
- });
- return;
- }
- runOnUi(() -> {
- if (!hasLrc()) {
- return;
- }
- int line = findShowLine(time);
- if (line != mCurrentLine) {
- mCurrentLine = line;
- if (!isShowTimeline) {
- smoothScrollTo(line);
- } else {
- invalidate();
- }
- }
- });
- }
-
- /**
- * 将歌词滚动到指定时间
- *
- * @param time 指定的时间
- * @deprecated 请使用 {@link #updateTime(long)} 代替
- */
- @Deprecated
- public void onDrag(long time) {
- updateTime(time);
- }
-
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (changed) {
- initPlayDrawable();
- initEntryList();
- if (hasLrc()) {
- smoothScrollTo(mCurrentLine, 0L);
- }
- }
- }
-
- @Override
- protected void onDraw(@NonNull Canvas canvas) {
- super.onDraw(canvas);
- int centerY = getHeight() / 2;
- // 无歌词文件
- if (!hasLrc()) {
- mLrcPaint.setColor(mCurrentTextColor);
- @SuppressLint("DrawAllocation")
- StaticLayout staticLayout = new StaticLayout(mDefaultLabel, mLrcPaint,
- (int) getLrcWidth(), Layout.Alignment.ALIGN_CENTER, 1f, 0f, false);
- drawText(canvas, staticLayout, centerY);
- return;
- }
-
- if (mOnPlayClickListener == null) {
- mLrcPaint.setColor(mCurrentTextColor);
- @SuppressLint("DrawAllocation")
- StaticLayout staticLayout = new StaticLayout(mLrcEntryList.get(index).getShowText()
- , mLrcPaint,
- (int) getLrcWidth(), Layout.Alignment.ALIGN_CENTER, 1f,
- 0f, false);
- drawText(canvas, staticLayout, centerY);
- return;
- }
-
- int centerLine = getCenterLine();
-
- if (isShowTimeline) {
- mPlayDrawable.draw(canvas);
-
- mTimePaint.setColor(mTimelineColor);
- canvas.drawLine(mTimeTextWidth, centerY, getWidth() - mTimeTextWidth, centerY, mTimePaint);
-
- mTimePaint.setColor(mTimeTextColor);
- String timeText = LrcUtils.formatTime(mLrcEntryList.get(centerLine).getTime());
- float timeX = getWidth() - (float) mTimeTextWidth / 2;
- float timeY = centerY - (mTimeFontMetrics.descent + mTimeFontMetrics.ascent) / 2;
- canvas.drawText(timeText, timeX, timeY, mTimePaint);
- }
-
- canvas.translate(0, mOffset);
-
- float y = 0;
- for (int i = 0; i < mLrcEntryList.size(); i++) {
-
- if (i > 0) {
- y += ((mLrcEntryList.get(i - 1).getHeight() + mLrcEntryList.get(i).getHeight()) >> 1)
- + mDividerHeight;
- }
- if (i == mCurrentLine) {
- mLrcPaint.setTextSize(mCurrentTextSize);
- mLrcPaint.setColor(mCurrentTextColor);
- } else if (isShowTimeline && i == centerLine) {
- mLrcPaint.setColor(mTimelineTextColor);
- } else {
- mLrcPaint.setTextSize(mNormalTextSize);
- mLrcPaint.setColor(mNormalTextColor);
- }
- drawText(canvas, mLrcEntryList.get(i).getStaticLayout(), y);
- }
- }
-
- /**
- * 画一行歌词
- *
- * @param y 歌词中心 Y 坐标
- */
- private void drawText(Canvas canvas, StaticLayout staticLayout, float y) {
- if (staticLayout != null) {
- canvas.save();
- canvas.translate(mLrcPadding, y - (staticLayout.getHeight() >> 1));
- staticLayout.draw(canvas);
- canvas.restore();
- }
- }
-
- @SuppressLint("ClickableViewAccessibility")
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
- isTouching = false;
- // 手指离开屏幕,启动延时任务,恢复歌词位置
- if (hasLrc() && isShowTimeline) {
- adjustCenter();
- postDelayed(hideTimelineRunnable, TIMELINE_KEEP_TIME);
- }
- }
- return mGestureDetector.onTouchEvent(event);
- }
-
- /**
- * 手势监听器
- */
- private GestureDetector.SimpleOnGestureListener mSimpleOnGestureListener =
- new GestureDetector.SimpleOnGestureListener() {
- // 本次点击仅仅为了停止歌词滚动,则不响应点击事件
- private boolean isTouchForStopFling = false;
-
- @Override
- public boolean onDown(@NonNull MotionEvent e) {
- if (!hasLrc()) {
- return mOnTapListener != null;
- }
- isTouching = true;
- removeCallbacks(hideTimelineRunnable);
- if (isFling) {
- isTouchForStopFling = true;
- mScroller.forceFinished(true);
- } else {
- isTouchForStopFling = false;
- }
- return mOnPlayClickListener != null || mOnTapListener != null;
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, @NonNull MotionEvent e2, float distanceX, float distanceY) {
- if (!hasLrc() || mOnPlayClickListener == null) {
- return super.onScroll(e1, e2, distanceX, distanceY);
- }
- if (!isShowTimeline) {
- isShowTimeline = true;
- } else {
- mOffset -= distanceY;
- mOffset = Math.min(mOffset, getOffset(0));
- mOffset = Math.max(mOffset, getOffset(mLrcEntryList.size() - 1));
- }
- invalidate();
- return true;
- }
-
- @Override
- public boolean onFling(MotionEvent e1, @NonNull MotionEvent e2, float velocityX, float velocityY) {
- if (!hasLrc() || mOnPlayClickListener == null) {
- return super.onFling(e1, e2, velocityX, velocityY);
- }
- if (isShowTimeline) {
- isFling = true;
- removeCallbacks(hideTimelineRunnable);
- mScroller.fling(0, (int) mOffset, 0, (int) velocityY, 0, 0, (int) getOffset(mLrcEntryList.size() - 1), (int) getOffset(0));
- return true;
- }
- return super.onFling(e1, e2, velocityX, velocityY);
- }
-
- @Override
- public boolean onSingleTapConfirmed(@NonNull MotionEvent e) {
- if (hasLrc() && mOnPlayClickListener != null && isShowTimeline && mPlayDrawable.getBounds().contains((int) e.getX(), (int) e.getY())) {
- int centerLine = getCenterLine();
- long centerLineTime = mLrcEntryList.get(centerLine).getTime();
- // onPlayClick 消费了才更新 UI
- if (mOnPlayClickListener != null && mOnPlayClickListener.onPlayClick(LrcView.this, centerLineTime)) {
- isShowTimeline = false;
- removeCallbacks(hideTimelineRunnable);
- mCurrentLine = centerLine;
- invalidate();
- return true;
- }
- } else if (mOnTapListener != null && !isTouchForStopFling) {
- mOnTapListener.onTap(LrcView.this, e.getX(), e.getY());
- }
- return super.onSingleTapConfirmed(e);
- }
- };
-
- private Runnable hideTimelineRunnable = new Runnable() {
- @Override
- public void run() {
- Log.d(TAG, "hideTimelineRunnable run");
- if (hasLrc() && isShowTimeline) {
- isShowTimeline = false;
- smoothScrollTo(mCurrentLine);
- }
- }
- };
-
- @Override
- public void computeScroll() {
- if (mScroller.computeScrollOffset()) {
- mOffset = mScroller.getCurrY();
- invalidate();
- }
-
- if (isFling && mScroller.isFinished()) {
- Log.d(TAG, "fling finish");
- isFling = false;
- if (hasLrc() && !isTouching) {
- adjustCenter();
- postDelayed(hideTimelineRunnable, TIMELINE_KEEP_TIME);
- }
- }
- }
-
- @Override
- protected void onDetachedFromWindow() {
- removeCallbacks(hideTimelineRunnable);
- super.onDetachedFromWindow();
- }
-
- private void onLrcLoaded(List entryList) {
- if (entryList != null && !entryList.isEmpty()) {
- mLrcEntryList.addAll(entryList);
- }
-
- Collections.sort(mLrcEntryList);
-
- initEntryList();
- invalidate();
- }
-
- private void initPlayDrawable() {
- int l = (mTimeTextWidth - mDrawableWidth) / 2;
- int t = getHeight() / 2 - mDrawableWidth / 2;
- int r = l + mDrawableWidth;
- int b = t + mDrawableWidth;
- mPlayDrawable.setBounds(l, t, r, b);
- }
-
- private void initEntryList() {
- if (!hasLrc() || getWidth() == 0) {
- return;
- }
-
- for (LrcEntry lrcEntry : mLrcEntryList) {
- lrcEntry.init(mLrcPaint, (int) getLrcWidth(), mTextGravity);
- }
-
- mOffset = (float) getHeight() / 2;
- }
-
- private void reset() {
- endAnimation();
- mScroller.forceFinished(true);
- isShowTimeline = false;
- isTouching = false;
- isFling = false;
- removeCallbacks(hideTimelineRunnable);
- mLrcEntryList.clear();
- mOffset = 0;
- mCurrentLine = 0;
- invalidate();
- }
-
- /**
- * 将中心行微调至正中心
- */
- private void adjustCenter() {
- smoothScrollTo(getCenterLine(), ADJUST_DURATION);
- }
-
- /**
- * 滚动到某一行
- */
- private void smoothScrollTo(int line) {
- smoothScrollTo(line, mAnimationDuration);
- }
-
- /**
- * 滚动到某一行
- */
- private void smoothScrollTo(int line, long duration) {
- float offset = getOffset(line);
- endAnimation();
-
- mAnimator = ValueAnimator.ofFloat(mOffset, offset);
- mAnimator.setDuration(duration);
- mAnimator.setInterpolator(new LinearInterpolator());
- mAnimator.addUpdateListener(animation -> {
- mOffset = (float) animation.getAnimatedValue();
- invalidate();
- });
- LrcUtils.resetDurationScale();
- mAnimator.start();
- }
-
- /**
- * 结束滚动动画
- */
- private void endAnimation() {
- if (mAnimator != null && mAnimator.isRunning()) {
- mAnimator.end();
- }
- }
-
- /**
- * 二分法查找当前时间应该显示的行数(最后一个 <= time 的行数)
- */
- private int findShowLine(long time) {
- int left = 0;
- int right = mLrcEntryList.size();
- while (left <= right) {
- int middle = (left + right) / 2;
- long middleTime = mLrcEntryList.get(middle).getTime();
-
- if (time < middleTime) {
- right = middle - 1;
- } else {
- if (middle + 1 >= mLrcEntryList.size() || time < mLrcEntryList.get(middle + 1).getTime()) {
- return middle;
- }
-
- left = middle + 1;
- }
- }
-
- return 0;
- }
-
- /**
- * 获取当前在视图中央的行数
- */
- private int getCenterLine() {
- int centerLine = 0;
- float minDistance = Float.MAX_VALUE;
- for (int i = 0; i < mLrcEntryList.size(); i++) {
- if (Math.abs(mOffset - getOffset(i)) < minDistance) {
- minDistance = Math.abs(mOffset - getOffset(i));
- centerLine = i;
- }
- }
- return centerLine;
- }
-
- /**
- * 获取歌词距离视图顶部的距离
- * 采用懒加载方式
- */
- private float getOffset(int line) {
- if (mLrcEntryList.get(line).getOffset() == Float.MIN_VALUE) {
- float offset = (float) getHeight() / 2;
- for (int i = 1; i <= line; i++) {
- offset -= ((mLrcEntryList.get(i - 1).getHeight() + mLrcEntryList.get(i).getHeight()) >> 1) + mDividerHeight;
- }
- mLrcEntryList.get(line).setOffset(offset);
- }
-
- return mLrcEntryList.get(line).getOffset();
- }
-
- /**
- * 获取歌词宽度
- */
- private float getLrcWidth() {
- return getWidth() - mLrcPadding * 2;
- }
-
- /**
- * 在主线程中运行
- */
- private void runOnUi(Runnable r) {
- if (Looper.myLooper() == Looper.getMainLooper()) {
- r.run();
- } else {
- post(r);
- }
- }
-
- private Object getFlag() {
- return mFlag;
- }
-
- private void setFlag(Object flag) {
- this.mFlag = flag;
- }
-}
diff --git a/lrcview/src/main/res/values/attrs.xml b/lrcview/src/main/res/values/attrs.xml
deleted file mode 100644
index e09df43..0000000
--- a/lrcview/src/main/res/values/attrs.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/lrcview/src/main/res/values/colors.xml b/lrcview/src/main/res/values/colors.xml
deleted file mode 100644
index e2e3dda..0000000
--- a/lrcview/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
- #9E9E9E
- #FF4081
- #F8BBD0
- #809E9E9E
- #809E9E9E
-
\ No newline at end of file
diff --git a/lrcview/src/main/res/values/dimens.xml b/lrcview/src/main/res/values/dimens.xml
deleted file mode 100644
index 0dca0dd..0000000
--- a/lrcview/src/main/res/values/dimens.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
- 1000
- 20sp
- 16sp
- 12sp
- 16dp
- 1dp
- 30dp
- 40dp
-
\ No newline at end of file
diff --git a/lrcview/src/main/res/values/strings.xml b/lrcview/src/main/res/values/strings.xml
deleted file mode 100644
index bd87035..0000000
--- a/lrcview/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- 暂无歌词
-
diff --git a/settings.gradle b/settings.gradle
index ad8fdf1..c18215c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -17,4 +17,4 @@ dependencyResolutionManagement {
rootProject.name = "Cloud_music"
include ':app'
include(':StatusBarUtil')
-include(":lrcview")
\ No newline at end of file
+//include(":lrcview")
\ No newline at end of file