修复BUG,更新UI
This commit is contained in:
parent
3d8b8e05d3
commit
98a4bd87ad
|
@ -1,17 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="deploymentTargetDropDown">
|
|
||||||
<targetSelectedWithDropDown>
|
|
||||||
<Target>
|
|
||||||
<type value="QUICK_BOOT_TARGET" />
|
|
||||||
<deviceKey>
|
|
||||||
<Key>
|
|
||||||
<type value="VIRTUAL_DEVICE_PATH" />
|
|
||||||
<value value="C:\Users\19669\.android\avd\Pixel_2_API_30.avd" />
|
|
||||||
</Key>
|
|
||||||
</deviceKey>
|
|
||||||
</Target>
|
|
||||||
</targetSelectedWithDropDown>
|
|
||||||
<timeTargetWasSelectedWithDropDown value="2024-02-17T09:31:32.068883900Z" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
|
@ -12,7 +12,6 @@
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
<option value="$PROJECT_DIR$/StatusBarUtil" />
|
<option value="$PROJECT_DIR$/StatusBarUtil" />
|
||||||
<option value="$PROJECT_DIR$/app" />
|
<option value="$PROJECT_DIR$/app" />
|
||||||
<option value="$PROJECT_DIR$/lrcview" />
|
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveExternalAnnotations" value="false" />
|
<option name="resolveExternalAnnotations" value="false" />
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
<option name="callCheckString" value="java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.AbstractStringBuilder,capacity|codePointAt|codePointBefore|codePointCount|indexOf|lastIndexOf|offsetByCodePoints|substring|subSequence,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigDecimal,.*,java.math.BigInteger,.*,java.net.InetAddress,.*,java.net.URI,.*,java.nio.channels.AsynchronousChannelGroup,.*,java.nio.channels.Channel,isOpen,java.nio.channels.FileChannel,open|map|lock|tryLock|write,java.nio.channels.ScatteringByteChannel,read,java.nio.channels.SocketChannel,open|socket|isConnected|isConnectionPending,java.util.Arrays,.*,java.util.Collections,(?!addAll).*,java.util.List,of,java.util.Map,of|ofEntries|entry,java.util.Set,of,java.util.UUID,.*,java.util.concurrent.BlockingQueue,offer|remove,java.util.concurrent.CountDownLatch,await|getCount,java.util.concurrent.ExecutorService,awaitTermination|isShutdown|isTerminated,java.util.concurrent.ForkJoinPool,awaitQuiescence,java.util.concurrent.Semaphore,tryAcquire|availablePermits|isFair|hasQueuedThreads|getQueueLength|getQueuedThreads,java.util.concurrent.locks.Condition,await|awaitNanos|awaitUntil,java.util.concurrent.locks.Lock,tryLock|newCondition,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*,java.util.stream.DoubleStream,.*,java.util.stream.IntStream,.*,java.util.stream.LongStream,.*,java.util.stream.Stream,.*" />
|
<option name="callCheckString" value="java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.AbstractStringBuilder,capacity|codePointAt|codePointBefore|codePointCount|indexOf|lastIndexOf|offsetByCodePoints|substring|subSequence,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigDecimal,.*,java.math.BigInteger,.*,java.net.InetAddress,.*,java.net.URI,.*,java.nio.channels.AsynchronousChannelGroup,.*,java.nio.channels.Channel,isOpen,java.nio.channels.FileChannel,open|map|lock|tryLock|write,java.nio.channels.ScatteringByteChannel,read,java.nio.channels.SocketChannel,open|socket|isConnected|isConnectionPending,java.util.Arrays,.*,java.util.Collections,(?!addAll).*,java.util.List,of,java.util.Map,of|ofEntries|entry,java.util.Set,of,java.util.UUID,.*,java.util.concurrent.BlockingQueue,offer|remove,java.util.concurrent.CountDownLatch,await|getCount,java.util.concurrent.ExecutorService,awaitTermination|isShutdown|isTerminated,java.util.concurrent.ForkJoinPool,awaitQuiescence,java.util.concurrent.Semaphore,tryAcquire|availablePermits|isFair|hasQueuedThreads|getQueueLength|getQueuedThreads,java.util.concurrent.locks.Condition,await|awaitNanos|awaitUntil,java.util.concurrent.locks.Lock,tryLock|newCondition,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*,java.util.stream.DoubleStream,.*,java.util.stream.IntStream,.*,java.util.stream.LongStream,.*,java.util.stream.Stream,.*" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="InnerClassMayBeStatic" enabled="false" level="WARNING" enabled_by_default="false" />
|
<inspection_tool class="InnerClassMayBeStatic" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="PrivatePropertyName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
|
<inspection_tool class="PropertyName" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
|
||||||
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
<option name="processCode" value="true" />
|
<option name="processCode" value="true" />
|
||||||
<option name="processLiterals" value="true" />
|
<option name="processLiterals" value="true" />
|
||||||
|
|
6
.idea/kotlinc.xml
Normal file
6
.idea/kotlinc.xml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="KotlinJpsPluginSettings">
|
||||||
|
<option name="version" value="1.8.0" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -46,4 +46,7 @@
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK" />
|
||||||
|
<component name="SuppressKotlinCodeStyleNotification">
|
||||||
|
<option name="disableForAll" value="true" />
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
|
|
||||||
* 在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流
|
* 在使用中有任何问题,欢迎反馈给我,可以用以下联系方式跟我交流
|
||||||
* [邮件](<a target="_blank" href="http://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=MAEJBgYJBAQDAABwQUEeU19d" style="text-decoration:none;"><img src="http://rescdn.qqmail.com/zh_CN/htmledition/images/function/qm_open/ico_mailme_12.png"/></a>)
|
* [邮件](<a target="_blank"%2href="http://mail.qq.com/cgi-bin/qm_share?t=qm_mailme&email=MAEJBgYJBAQDAABwQUEeU19d" style="text-decoration:none;"><img src="http://rescdn.qqmail.com/zh_CN/htmledition/images/function/qm_open/ico_mailme_12.png"/></a>)
|
||||||
* QQ:1966944300
|
* QQ:1966944300
|
||||||
* 后台源码-Github: [网易云音乐 API](https://github.com/Binaryify/NeteaseCloudMusicApi)
|
* 后台源码-Github: [网易云音乐 API](https://github.com/Binaryify/NeteaseCloudMusicApi)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
|
id 'kotlin-android'
|
||||||
}
|
}
|
||||||
android {
|
android {
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
|
@ -18,8 +19,7 @@ android {
|
||||||
//noinspection ExpiredTargetSdkVersion,OldTargetApi
|
//noinspection ExpiredTargetSdkVersion,OldTargetApi
|
||||||
targetSdk 31
|
targetSdk 31
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.9.9"
|
versionName "2.0.0"
|
||||||
|
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
@ -39,11 +39,15 @@ android {
|
||||||
outputFileName = "Cloud_music-${variant.name}-v${variant.versionName}.apk"
|
outputFileName = "Cloud_music-${variant.name}-v${variant.versionName}.apk"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
viewBinding {
|
viewBinding {
|
||||||
enabled = true
|
enabled = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation 'androidx.core:core-ktx:1.7.0'
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
implementation 'com.google.android.material:material:1.9.0'
|
implementation 'com.google.android.material:material:1.9.0'
|
||||||
|
|
||||||
|
@ -54,6 +58,7 @@ dependencies {
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
|
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
|
||||||
//图片处理
|
//图片处理
|
||||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||||
|
|
||||||
implementation "androidx.palette:palette:1.0.0"
|
implementation "androidx.palette:palette:1.0.0"
|
||||||
// 废弃的歌词组件
|
// 废弃的歌词组件
|
||||||
// implementation 'com.github.wangchenyan:lrcview:2.2.1'
|
// implementation 'com.github.wangchenyan:lrcview:2.2.1'
|
||||||
|
@ -65,6 +70,9 @@ dependencies {
|
||||||
implementation 'com.mpatric:mp3agic:0.9.1'
|
implementation 'com.mpatric:mp3agic:0.9.1'
|
||||||
|
|
||||||
// 沉浸式状态栏
|
// 沉浸式状态栏
|
||||||
api project(path: ':StatusBarUtil')
|
implementation project(path: ':StatusBarUtil')
|
||||||
api project(path: ':lrcview')
|
// api project(path: ':lrcview')
|
||||||
|
//歌词组件库
|
||||||
|
api "com.github.cy745:EaseView:e11c3208a9"
|
||||||
|
api "androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03"
|
||||||
}
|
}
|
|
@ -24,7 +24,6 @@ import java.io.IOException;
|
||||||
|
|
||||||
public class MediaPlayer extends android.media.MediaPlayer {
|
public class MediaPlayer extends android.media.MediaPlayer {
|
||||||
// 每秒更新一次进度
|
// 每秒更新一次进度
|
||||||
|
|
||||||
@SuppressLint("UnsafeOptInUsageError")
|
@SuppressLint("UnsafeOptInUsageError")
|
||||||
public MediaPlayer() {
|
public MediaPlayer() {
|
||||||
setOnErrorListener((mediaPlayer, i, i1) -> {
|
setOnErrorListener((mediaPlayer, i, i1) -> {
|
||||||
|
@ -88,8 +87,11 @@ public class MediaPlayer extends android.media.MediaPlayer {
|
||||||
bfqkz.xm = mp3;
|
bfqkz.xm = mp3;
|
||||||
main.handler.post(() -> {
|
main.handler.post(() -> {
|
||||||
bfui();
|
bfui();
|
||||||
|
if (bfqkz.notify != null) {
|
||||||
bfqkz.notify.tzl();
|
bfqkz.notify.tzl();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
new Thread() {
|
new Thread() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
@ -14,13 +14,13 @@ import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
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.FlexWrap;
|
||||||
import com.google.android.flexbox.FlexboxLayoutManager;
|
import com.google.android.flexbox.FlexboxLayoutManager;
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
import com.google.android.material.search.SearchView;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.muqingbfq.databinding.ActivitySearchBinding;
|
import com.muqingbfq.databinding.ActivitySearchBinding;
|
||||||
|
@ -37,7 +38,6 @@ import com.muqingbfq.fragment.search;
|
||||||
import com.muqingbfq.mq.FragmentActivity;
|
import com.muqingbfq.mq.FragmentActivity;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
import com.muqingbfq.mq.wj;
|
import com.muqingbfq.mq.wj;
|
||||||
import com.muqingbfq.mq.wl;
|
|
||||||
import com.muqingbfq.view.Edit;
|
import com.muqingbfq.view.Edit;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
@ -55,14 +55,20 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
|
|
||||||
public static void start(Activity context, View view) {
|
public static void start(Activity context, View view) {
|
||||||
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
||||||
view, "view");
|
view, "edit");
|
||||||
context.startActivity(new Intent(context, activity_search.class), options.toBundle());
|
context.startActivity(new Intent(context, activity_search.class), options.toBundle());
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(getViewBinding().getRoot());
|
setContentView(getViewBinding().getRoot());
|
||||||
FlexboxLayoutManager manager = new FlexboxLayoutManager(this);
|
setToolbar();
|
||||||
|
FlexboxLayoutManager manager = new FlexboxLayoutManager(this){
|
||||||
|
@Override
|
||||||
|
public boolean canScrollVertically() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
//设置主轴排列方式
|
//设置主轴排列方式
|
||||||
manager.setFlexDirection(FlexDirection.ROW);
|
manager.setFlexDirection(FlexDirection.ROW);
|
||||||
//设置是否换行
|
//设置是否换行
|
||||||
|
@ -70,16 +76,6 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
manager.setAlignItems(AlignItems.STRETCH);
|
manager.setAlignItems(AlignItems.STRETCH);
|
||||||
binding.listRecycler.setLayoutManager(manager);
|
binding.listRecycler.setLayoutManager(manager);
|
||||||
binding.listRecycler.setAdapter(new SearchRecordAdapter());
|
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(
|
binding.deleat.setOnClickListener(v -> new MaterialAlertDialogBuilder(
|
||||||
activity_search.this)
|
activity_search.this)
|
||||||
.setTitle("删除")
|
.setTitle("删除")
|
||||||
|
@ -109,20 +105,17 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
if (null != v) {
|
if (null != v) {
|
||||||
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
||||||
}
|
}
|
||||||
binding.editview.setText(list.get(i));//把选择的选项内容展示在EditText上
|
binding.toolbar.setText(list.get(i));//把选择的选项内容展示在EditText上
|
||||||
dismiss();//如果已经选择了,隐藏起来
|
dismiss();//如果已经选择了,隐藏起来
|
||||||
start(binding.editview.getText().toString());
|
start(binding.toolbar.getText().toString());
|
||||||
|
|
||||||
});
|
});
|
||||||
Object o = new Object();
|
Object o = new Object();
|
||||||
binding.editview.addTextChangedListener(new Edit.TextWatcher() {
|
binding.searchview.getEditText().addTextChangedListener(new Edit.TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
binding.editview.iskong();
|
|
||||||
if (TextUtils.isEmpty(s)) {
|
if (TextUtils.isEmpty(s)) {
|
||||||
listPopupWindow.setVisibility(View.GONE);
|
listPopupWindow.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
|
@ -135,7 +128,8 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
synchronized (o) {
|
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 {
|
try {
|
||||||
JSONArray jsonArray = new JSONObject(hq).getJSONObject("result")
|
JSONArray jsonArray = new JSONObject(hq).getJSONObject("result")
|
||||||
.getJSONArray("allMatch");
|
.getJSONArray("allMatch");
|
||||||
|
@ -153,18 +147,46 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
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() {
|
public void dismiss() {
|
||||||
binding.editview.clearFocus();
|
binding.searchview.hide();
|
||||||
listPopupWindow.setVisibility(View.GONE);
|
|
||||||
gj.ycjp(binding.editview.editText);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSearchRecord(String name) {
|
private void addSearchRecord(String name) {
|
||||||
|
@ -204,13 +226,17 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
|
if (binding.searchFragment.getVisibility() == View.VISIBLE) {
|
||||||
|
binding.searchFragment.setVisibility(View.GONE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (itemId == android.R.id.home) {
|
if (itemId == android.R.id.home) {
|
||||||
ActivityCompat.finishAfterTransition(this);
|
ActivityCompat.finishAfterTransition(this);
|
||||||
return false;
|
return false;
|
||||||
} else if (itemId == 0) {
|
} 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) {
|
public void start(String name) {
|
||||||
|
@ -269,7 +295,7 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
String keyword = json_list.get(position);
|
String keyword = json_list.get(position);
|
||||||
holder.recordTextView.setText(keyword);
|
holder.recordTextView.setText(keyword);
|
||||||
holder.recordTextView.setOnClickListener(v -> {
|
holder.recordTextView.setOnClickListener(v -> {
|
||||||
binding.editview.setText(keyword);
|
binding.toolbar.setText(keyword);
|
||||||
start(keyword);
|
start(keyword);
|
||||||
});
|
});
|
||||||
holder.recordTextView.setOnLongClickListener(view -> {
|
holder.recordTextView.setOnLongClickListener(view -> {
|
||||||
|
@ -308,6 +334,10 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void end() {
|
private void end() {
|
||||||
|
if (binding.searchview.isShowing()) {
|
||||||
|
binding.searchview.hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (binding.searchRecycler.getVisibility() == View.VISIBLE) {
|
if (binding.searchRecycler.getVisibility() == View.VISIBLE) {
|
||||||
binding.searchRecycler.setVisibility(View.GONE);
|
binding.searchRecycler.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package com.muqingbfq.api;
|
package com.muqingbfq.api;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
import com.mpatric.mp3agic.ID3v2;
|
import com.mpatric.mp3agic.ID3v2;
|
||||||
import com.mpatric.mp3agic.Mp3File;
|
import com.mpatric.mp3agic.Mp3File;
|
||||||
import com.muqingbfq.MP3;
|
import com.muqingbfq.MP3;
|
||||||
import com.muqingbfq.fragment.Media;
|
import com.muqingbfq.fragment.Media;
|
||||||
import com.muqingbfq.login.user_logs;
|
import com.muqingbfq.home;
|
||||||
import com.muqingbfq.main;
|
import com.muqingbfq.main;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
import com.muqingbfq.mq.wj;
|
import com.muqingbfq.mq.wj;
|
||||||
|
@ -55,9 +53,9 @@ public class url extends Thread {
|
||||||
if (json.getInt("code") == -460) {
|
if (json.getInt("code") == -460) {
|
||||||
String message = json.getString("message");
|
String message = json.getString("message");
|
||||||
main.handler.post(() -> {
|
main.handler.post(() -> {
|
||||||
gj.ts(main.application, message);
|
gj.ts(home.activity, message);
|
||||||
main.application.startActivity(new Intent(main.application
|
home.activity.startActivity(new android.content.Intent(home.activity
|
||||||
, user_logs.class));
|
, com.muqingbfq.login.user_logs.class));
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.muqingbfq;
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
|
import android.animation.ValueAnimator;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -10,7 +11,10 @@ import android.content.res.ColorStateList;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
|
import android.graphics.drawable.LayerDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
|
@ -18,13 +22,12 @@ import android.view.LayoutInflater;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.AlphaAnimation;
|
import android.view.animation.LinearInterpolator;
|
||||||
import android.view.animation.Animation;
|
import android.widget.SeekBar;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
import androidx.core.graphics.ColorUtils;
|
|
||||||
import androidx.palette.graphics.Palette;
|
import androidx.palette.graphics.Palette;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
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.RequestListener;
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
import com.bumptech.glide.request.target.Target;
|
import com.bumptech.glide.request.target.Target;
|
||||||
import com.google.android.material.slider.Slider;
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.mpatric.mp3agic.ID3v2;
|
import com.mpatric.mp3agic.ID3v2;
|
||||||
|
@ -56,6 +58,23 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
public MP3 mp3;
|
public MP3 mp3;
|
||||||
public boolean isplay = true;
|
public boolean isplay = true;
|
||||||
GestureDetector gestureDetector;
|
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")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
private void setLrc() {
|
private void setLrc() {
|
||||||
|
@ -66,48 +85,66 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
if (!gj.isTablet(this)) {
|
if (!gj.isTablet(this)) {
|
||||||
layoutParams.height = (int) (main.k / 1.3f);
|
layoutParams.height = (int) (main.k / 1.3f);
|
||||||
layoutParams.width = (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) -> {
|
binding.lrcView.setOnSingerClickListener(() -> lrc(binding.lrcView));
|
||||||
|
// binding.lrcView.setTextGravity(GRAVITY_LEFT)
|
||||||
// 隐藏view2并显示view1的动画效果
|
binding.lrcView.setNormalTextSize(80f);
|
||||||
view.animate()
|
binding.lrcView.setCurrentTextSize(100f);
|
||||||
.alpha(0.0f)
|
binding.lrcView.setTranslateTextScaleValue(0.8f);
|
||||||
.setDuration(500)
|
binding.lrcView.setHorizontalOffset(-50f);
|
||||||
.setListener(new AnimatorListenerAdapter() {
|
binding.lrcView.setHorizontalOffsetPercent(0.5f);
|
||||||
@Override
|
binding.lrcView.setItemOffsetPercent(0.5f);
|
||||||
public void onAnimationEnd(Animator animation) {
|
binding.lrcView.setIsDrawTranslation(true);
|
||||||
view.setVisibility(View.GONE);
|
binding.lrcView.setIsEnableBlurEffect(true);
|
||||||
binding.cardview.setVisibility(View.VISIBLE);
|
|
||||||
binding.cardview.setAlpha(0.0f);
|
|
||||||
binding.cardview.animate().alpha(1.0f).setDuration(500).setListener(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
layoutParams.height = (int) (main.g / 2.0f);
|
layoutParams.height = (int) (main.g / 2.0f);
|
||||||
layoutParams.width = (int) (main.g / 2.0f);
|
layoutParams.width = (int) (main.g / 2.0f);
|
||||||
}
|
}
|
||||||
binding.cardview.setLayoutParams(layoutParams);
|
binding.cardview.setLayoutParams(layoutParams);
|
||||||
binding.lrcView.
|
|
||||||
setDraggable(true, (a, time) -> {
|
binding.lrcView.setDraggable(true, time -> {
|
||||||
bfqkz.mt.seekTo((int) time);
|
bfqkz.mt.seekTo((int) time);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
binding.tdt.addOnChangeListener((slider, value, fromUser) ->
|
binding.tdt.setThumb(null);
|
||||||
setTime_b(bfq_an.getTime((long) value)));
|
binding.tdt.post(() -> seekbarH = binding.tdt.getHeight());
|
||||||
binding.tdt.addOnSliderTouchListener(new Slider.OnSliderTouchListener() {
|
binding.tdt.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
@Override
|
@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;
|
isplay = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStopTrackingTouch(@NonNull Slider slider) {
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
// 播放音乐到指定位置
|
// 当停止拖动滑块时执行操作
|
||||||
isplay = true;
|
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<ActivityBfqBinding>
|
||||||
context.startActivity(intent);
|
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")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
protected void UI(@Nullable Bundle savedInstanceState) {
|
protected void UI(@Nullable Bundle savedInstanceState) {
|
||||||
gestureDetector = new GestureDetector(this, this);
|
gestureDetector = new GestureDetector(this, this);
|
||||||
setLrc();
|
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 -> {
|
binding.kg.setOnClickListener(v -> {
|
||||||
if (bfqkz.mt.isPlaying()) {
|
if (bfqkz.mt.isPlaying()) {
|
||||||
bfqkz.mt.pause();
|
bfqkz.mt.pause();
|
||||||
|
setbf(false);
|
||||||
} else {
|
} else {
|
||||||
bfqkz.mt.start();
|
bfqkz.mt.start();
|
||||||
|
setbf(true);
|
||||||
}
|
}
|
||||||
|
Animation();
|
||||||
});
|
});
|
||||||
binding.xyq.setOnClickListener(v -> bfq_an.xyq());
|
binding.xyq.setOnClickListener(v -> bfq_an.xyq());
|
||||||
binding.syq.setOnClickListener(v -> bfq_an.syq());
|
binding.syq.setOnClickListener(v -> bfq_an.syq());
|
||||||
|
@ -178,6 +237,21 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
mp3 = (MP3) intent.getSerializableExtra("MP3");
|
mp3 = (MP3) intent.getSerializableExtra("MP3");
|
||||||
new thread().start();
|
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 {
|
private class toolbar implements View.OnClickListener {
|
||||||
|
@ -211,28 +285,12 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
if (mp3 != null) {
|
if (mp3 != null) {
|
||||||
sx();
|
sx();
|
||||||
}
|
}
|
||||||
if (bfqkz.mt != null && bfqkz.mt.isPlaying()) {
|
setbf(bfqkz.mt.isPlaying());
|
||||||
binding.kg.setImageResource(R.drawable.bf);
|
Animation();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
main.handler.post(runnable);
|
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() {
|
public void sx() {
|
||||||
|
@ -269,12 +327,12 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setlike(boolean bool) {
|
public void setlike(boolean bool) {
|
||||||
int color = R.color.text;
|
|
||||||
if (bool) {
|
if (bool) {
|
||||||
color = android.R.color.holo_red_dark;
|
|
||||||
}
|
|
||||||
binding.like.setImageTintList(ContextCompat.
|
binding.like.setImageTintList(ContextCompat.
|
||||||
getColorStateList(binding.getRoot().getContext(), color));
|
getColorStateList(binding.getRoot().getContext(), android.R.color.holo_red_dark));
|
||||||
|
} else {
|
||||||
|
binding.like.setImageTintList(ColorStateList.valueOf(ColorTint));
|
||||||
|
}
|
||||||
islike = bool;
|
islike = bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,6 +357,7 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
setImageBitmap();
|
setImageBitmap();
|
||||||
}
|
}
|
||||||
if (bfqkz.mt.isPlaying() != isPlaying) {
|
if (bfqkz.mt.isPlaying() != isPlaying) {
|
||||||
|
|
||||||
setbf(bfqkz.mt.isPlaying());
|
setbf(bfqkz.mt.isPlaying());
|
||||||
}
|
}
|
||||||
if (bfqkz.like_bool != islike) {
|
if (bfqkz.like_bool != islike) {
|
||||||
|
@ -307,7 +366,7 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
if (!Objects.equals(bfqkz.lrc, lrc)) {
|
if (!Objects.equals(bfqkz.lrc, lrc)) {
|
||||||
lrc = bfqkz.lrc;
|
lrc = bfqkz.lrc;
|
||||||
String[] strings = Media.loadLyric();
|
String[] strings = Media.loadLyric();
|
||||||
binding.lrcView.loadLrc(strings[0], strings[1]);
|
binding.lrcView.loadLyric(strings[0], strings[1]);
|
||||||
}
|
}
|
||||||
main.handler.postDelayed(this, 1000); // 每秒更新一次进度
|
main.handler.postDelayed(this, 1000); // 每秒更新一次进度
|
||||||
}
|
}
|
||||||
|
@ -362,7 +421,6 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
@NonNull DataSource dataSource,
|
@NonNull DataSource dataSource,
|
||||||
boolean isFirstResource) {
|
boolean isFirstResource) {
|
||||||
color(resource);
|
color(resource);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}).into(binding.cardview.imageView);
|
}).into(binding.cardview.imageView);
|
||||||
|
@ -373,23 +431,47 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
Palette.from(bitmap)
|
Palette.from(bitmap)
|
||||||
.maximumColorCount(10)
|
.maximumColorCount(10)
|
||||||
.generate(palette -> {
|
.generate(palette -> {
|
||||||
|
// 获取图片中有活力的亮色
|
||||||
|
int dominantSwatch = palette.getLightVibrantColor(Color.WHITE);
|
||||||
|
// 获取图片中柔和的亮色
|
||||||
int lightMutedColor = palette.getLightMutedColor(Color.GRAY);
|
int lightMutedColor = palette.getLightMutedColor(Color.GRAY);
|
||||||
GradientDrawable gradientDrawable = new GradientDrawable(
|
GradientDrawable gradientDrawable = new GradientDrawable(
|
||||||
GradientDrawable.Orientation.BOTTOM_TOP, // 渐变方向:从上到下
|
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);
|
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
|
||||||
// trackColorInactive
|
|
||||||
// 创建颜色列表
|
|
||||||
ColorStateList trackInactiveTintList = ColorStateList
|
|
||||||
.valueOf(ColorUtils.blendARGB(lightMutedColor
|
|
||||||
, Color.WHITE, 0.5f));
|
|
||||||
binding.tdt.setTrackInactiveTintList(trackInactiveTintList);
|
|
||||||
binding.getRoot().setBackground(gradientDrawable);
|
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
|
@Override
|
||||||
public void finish() {
|
public void finish() {
|
||||||
super.finish();
|
super.finish();
|
||||||
|
@ -405,18 +487,14 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMax(int max) {
|
public void setMax(int max) {
|
||||||
binding.tdt.setValueTo(Math.max(0, max));
|
binding.tdt.setMax(Math.max(0, max));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Progress(int progress) {
|
public void Progress(int progress) {
|
||||||
if (binding.tdt.getValueTo() < progress) {
|
int min = Math.min(progress, binding.tdt.getMax());
|
||||||
return;
|
binding.tdt.setProgress(min);
|
||||||
// 处理超出范围的情况
|
binding.lrcView.updateTime(min, true);
|
||||||
}
|
}
|
||||||
binding.tdt.setValue(progress);
|
|
||||||
binding.lrcView.updateTime(progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onDown(@NonNull MotionEvent e) {
|
public boolean onDown(@NonNull MotionEvent e) {
|
||||||
|
@ -471,9 +549,9 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
||||||
@Override
|
@Override
|
||||||
public boolean onScroll(@NonNull MotionEvent e1, @NonNull MotionEvent e2,
|
public boolean onScroll(@NonNull MotionEvent e1, @NonNull MotionEvent e2,
|
||||||
float distanceX, float distanceY) {
|
float distanceX, float distanceY) {
|
||||||
if (binding.lrcView.getVisibility() == View.VISIBLE) {
|
/* if (binding.lrcView.getVisibility() == View.VISIBLE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}*/
|
||||||
float y = binding.getRoot().getRootView().getTranslationY() - distanceY;
|
float y = binding.getRoot().getRootView().getTranslationY() - distanceY;
|
||||||
y = Math.max(0, y);
|
y = Math.max(0, y);
|
||||||
//移动的距离
|
//移动的距离
|
||||||
|
|
|
@ -25,7 +25,8 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class bfqkz extends MediaBrowserServiceCompat {
|
public class bfqkz extends MediaBrowserServiceCompat {
|
||||||
public static MediaPlayer mt = new MediaPlayer();
|
public final static MediaPlayer mt = new MediaPlayer();
|
||||||
|
|
||||||
public static List<MP3> list = new ArrayList<>();
|
public static List<MP3> list = new ArrayList<>();
|
||||||
//保存原始list顺序
|
//保存原始list顺序
|
||||||
public static List<MP3> list_baocun = new ArrayList<>();
|
public static List<MP3> list_baocun = new ArrayList<>();
|
||||||
|
|
|
@ -28,12 +28,11 @@ import java.util.List;
|
||||||
public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
|
public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
|
||||||
List<String[]> list = new ArrayList<>();
|
List<String[]> list = new ArrayList<>();
|
||||||
List<String> list_box = new ArrayList<>();
|
List<String> list_box = new ArrayList<>();
|
||||||
ActivityCleanBinding binding;
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
binding = ActivityCleanBinding.inflate(getLayoutInflater());
|
setContentView();
|
||||||
setContentView(binding.getRoot());
|
setToolbar();
|
||||||
UI();
|
UI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +116,7 @@ public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
if (item.getItemId() == android.R.id.home) {
|
if (item.getItemId() == android.R.id.home) {
|
||||||
finish();
|
finish();
|
||||||
} else if (item == menu_deleat) {
|
} else if (item == menu_deleat) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.muqingbfq.fragment;
|
package com.muqingbfq.fragment;
|
||||||
|
|
||||||
|
import com.dirror.lyricviewx.LyricViewX;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -19,10 +20,8 @@ public class Media {
|
||||||
} catch (Exception e) {
|
} 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};
|
return new String[]{a, b};
|
||||||
// bfq.lrcView.getLrc();
|
|
||||||
// bfq.lrcView.loadLrc(a, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class gd extends com.muqingbfq.mq.FragmentActivity<ActivityGdBinding> {
|
||||||
|
|
||||||
public static void start(Activity context, String[] str, View view) {
|
public static void start(Activity context, String[] str, View view) {
|
||||||
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
||||||
view, "view");
|
view, "text");
|
||||||
Intent intent = new Intent(context, gd.class);
|
Intent intent = new Intent(context, gd.class);
|
||||||
intent.putExtra("id", str[0]);
|
intent.putExtra("id", str[0]);
|
||||||
intent.putExtra("name", str[1]);
|
intent.putExtra("name", str[1]);
|
||||||
|
|
|
@ -10,7 +10,6 @@ import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.drawerlayout.widget.DrawerLayout;
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
@ -41,20 +40,24 @@ public class gd_adapter extends Fragment {
|
||||||
List<XM> list = new ArrayList<>();
|
List<XM> list = new ArrayList<>();
|
||||||
List<MP3> listmp3 = new ArrayList<>();
|
List<MP3> listmp3 = new ArrayList<>();
|
||||||
FragmentGdBinding binding;
|
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
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
binding = FragmentGdBinding.inflate(getLayoutInflater(), container, false);
|
binding = FragmentGdBinding.inflate(getLayoutInflater(), container, false);
|
||||||
//初始化工具栏
|
//初始化工具栏
|
||||||
|
toolbar();
|
||||||
((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();
|
|
||||||
|
|
||||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
|
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
|
||||||
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||||
binding.recyclerview1.setHasFixedSize(true);
|
binding.recyclerview1.setHasFixedSize(true);
|
||||||
|
@ -122,7 +125,7 @@ public class gd_adapter extends Fragment {
|
||||||
});
|
});
|
||||||
mp3list();
|
mp3list();
|
||||||
|
|
||||||
binding.editView.setOnClickListener(v -> activity_search.start(getActivity(),v));
|
binding.toolbar.setOnClickListener(v -> activity_search.start(getActivity(), v));
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class mp3 extends FragmentActivity<ActivityMp3Binding> {
|
||||||
|
|
||||||
public static void start(Activity context, String[] str, View view) {
|
public static void start(Activity context, String[] str, View view) {
|
||||||
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
||||||
view, "view");
|
view, "text");
|
||||||
Intent intent = new Intent(context, mp3.class);
|
Intent intent = new Intent(context, mp3.class);
|
||||||
intent.putExtra("id", str[0]);
|
intent.putExtra("id", str[0]);
|
||||||
intent.putExtra("name", str[1]);
|
intent.putExtra("name", str[1]);
|
||||||
|
|
|
@ -71,18 +71,22 @@ public class wode extends Fragment {
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
public static baseadapter adaper;
|
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
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
binding = FragmentWdBinding.inflate(inflater, container, false);
|
binding = FragmentWdBinding.inflate(inflater, container, false);
|
||||||
//初始化工具栏
|
//初始化工具栏
|
||||||
((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
|
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();
|
|
||||||
name = binding.text1;
|
name = binding.text1;
|
||||||
binding.appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
|
binding.appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
|
||||||
boolean isCollapsed = false; // 标记是否处于折叠状态
|
boolean isCollapsed = false; // 标记是否处于折叠状态
|
||||||
|
@ -146,7 +150,7 @@ public class wode extends Fragment {
|
||||||
getContext().startActivity(a);
|
getContext().startActivity(a);
|
||||||
break;
|
break;
|
||||||
case "排行榜":
|
case "排行榜":
|
||||||
gd.start(getActivity(), new String[]{data, s}, holder.itemView);
|
gd.start(getActivity(), new String[]{data, s}, holder.textView);
|
||||||
break;
|
break;
|
||||||
case "API":
|
case "API":
|
||||||
EditViewDialog editViewDialog = new EditViewDialog(getContext(), "更换接口API")
|
EditViewDialog editViewDialog = new EditViewDialog(getContext(), "更换接口API")
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.muqingbfq;
|
package com.muqingbfq;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
@ -14,6 +16,7 @@ import android.view.MenuItem;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
|
@ -27,12 +30,17 @@ import java.util.List;
|
||||||
|
|
||||||
public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding> {
|
public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding> {
|
||||||
public MediaBrowserCompat mBrowser;
|
public MediaBrowserCompat mBrowser;
|
||||||
|
@SuppressLint("StaticFieldLeak")
|
||||||
|
public static Context activity;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ActivityHomeBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
protected ActivityHomeBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
||||||
return ActivityHomeBinding.inflate(layoutInflater);
|
return ActivityHomeBinding.inflate(layoutInflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
activity = this;
|
||||||
setTheme(R.style.Theme_muqing);
|
setTheme(R.style.Theme_muqing);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(getViewBinding().getRoot());
|
setContentView(getViewBinding().getRoot());
|
||||||
|
@ -72,14 +80,12 @@ public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ComponentName componentName;
|
public static ComponentName componentName;
|
||||||
|
|
||||||
private class Adaper extends FragmentStateAdapter {
|
|
||||||
List<Fragment> list = new ArrayList<>();
|
List<Fragment> list = new ArrayList<>();
|
||||||
public Adaper(@NonNull FragmentActivity fragmentActivity) {
|
public void UI() {
|
||||||
super(fragmentActivity);
|
list.clear();
|
||||||
list.add(new gd_adapter());
|
list.add(new gd_adapter());
|
||||||
list.add(new wode());
|
list.add(new wode());
|
||||||
}
|
binding.viewPager.setAdapter(new FragmentStateAdapter(this) {
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment createFragment(int position) {
|
public Fragment createFragment(int position) {
|
||||||
|
@ -90,13 +96,9 @@ public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return list.size();
|
return list.size();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
public void UI() {
|
|
||||||
Adaper adapter = new Adaper(this);
|
|
||||||
binding.viewPager.setAdapter(adapter);
|
|
||||||
binding.viewPager.setSaveEnabled(false);
|
binding.viewPager.setSaveEnabled(false);
|
||||||
// 将 ViewPager2 绑定到 TabLayout
|
// 将 ViewPager2 绑定到 TabLayou
|
||||||
binding.tablayout.setOnItemSelectedListener(item -> {
|
binding.tablayout.setOnItemSelectedListener(item -> {
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
if (itemId == R.id.a) {
|
if (itemId == R.id.a) {
|
||||||
|
@ -132,6 +134,7 @@ public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding
|
||||||
editor.putString("listData", jsonList);
|
editor.putString("listData", jsonList);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
moveTaskToBack(true);
|
moveTaskToBack(true);
|
||||||
|
|
|
@ -27,16 +27,13 @@ import java.util.List;
|
||||||
|
|
||||||
public class main extends Application {
|
public class main extends Application {
|
||||||
public static Application application;
|
public static Application application;
|
||||||
|
|
||||||
public static Handler handler = new Handler(Looper.getMainLooper());
|
public static Handler handler = new Handler(Looper.getMainLooper());
|
||||||
public static String api = "http://139.196.224.229:3000";
|
public static String api = "https://service-8xjb06vc-1319932248.gz.tencentapigw.com.cn/release";
|
||||||
public static String http = "http://139.196.224.229/muqing";
|
public static String http = "https://www.muqingkaifazhe.top/muqingbfq.php";
|
||||||
public static int k, g;
|
public static int k, g;
|
||||||
public static SharedPreferences sp;
|
public static SharedPreferences sp;
|
||||||
public static SharedPreferences.Editor edit;
|
public static SharedPreferences.Editor edit;
|
||||||
public int count = 0;
|
private int count = 0;
|
||||||
public static long item = System.currentTimeMillis();
|
|
||||||
@SuppressLint("HardwareIds")
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
@ -80,7 +77,6 @@ public class main extends Application {
|
||||||
if (wl.Cookie.equals("")) {
|
if (wl.Cookie.equals("")) {
|
||||||
new visitor();
|
new visitor();
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPreferences theme = getSharedPreferences("theme", MODE_PRIVATE);
|
SharedPreferences theme = getSharedPreferences("theme", MODE_PRIVATE);
|
||||||
@SuppressLint("CommitPrefEdits") SharedPreferences.Editor edit = theme.edit();
|
@SuppressLint("CommitPrefEdits") SharedPreferences.Editor edit = theme.edit();
|
||||||
int i = theme.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
int i = theme.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
||||||
|
@ -89,7 +85,6 @@ public class main extends Application {
|
||||||
edit.apply();
|
edit.apply();
|
||||||
}
|
}
|
||||||
AppCompatDelegate.setDefaultNightMode(i);
|
AppCompatDelegate.setDefaultNightMode(i);
|
||||||
|
|
||||||
String jsonList = this.getSharedPreferences("list", Context.MODE_PRIVATE)
|
String jsonList = this.getSharedPreferences("list", Context.MODE_PRIVATE)
|
||||||
.getString("listData", null); // 获取保存的 JSON 字符串
|
.getString("listData", null); // 获取保存的 JSON 字符串
|
||||||
if (jsonList != null) {
|
if (jsonList != null) {
|
||||||
|
@ -116,12 +111,10 @@ public class main extends Application {
|
||||||
}
|
}
|
||||||
}.start();
|
}.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||||
@Override
|
@Override
|
||||||
public void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {
|
public void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityStarted(@NonNull Activity activity) {
|
public void onActivityStarted(@NonNull Activity activity) {
|
||||||
if (count == 0) { //后台切换到前台
|
if (count == 0) { //后台切换到前台
|
||||||
|
@ -131,21 +124,16 @@ public class main extends Application {
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResumed(@NonNull Activity activity) {
|
public void onActivityResumed(@NonNull Activity activity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityPaused(@NonNull Activity activity) {
|
public void onActivityPaused(@NonNull Activity activity) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityStopped(@NonNull Activity activity) {
|
public void onActivityStopped(@NonNull Activity activity) {
|
||||||
count--;
|
count--;
|
||||||
if (count == 0) { //后台切换到前台
|
if (count == 0) { //后台切换到前台
|
||||||
// gj.sc(">>>>>>>>>>>>>>>>>>>App切到后台");
|
|
||||||
new Thread(){
|
new Thread(){
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -154,7 +142,6 @@ public class main extends Application {
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
// gj.sc(count);
|
|
||||||
if (count != 0) {
|
if (count != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +160,6 @@ public class main extends Application {
|
||||||
@Override
|
@Override
|
||||||
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
|
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityDestroyed(@NonNull Activity activity) {
|
public void onActivityDestroyed(@NonNull Activity activity) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ public class BluetoothMusicController {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
IntentFilter intentFilter = new IntentFilter();
|
IntentFilter intentFilter = new IntentFilter();
|
||||||
intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
|
intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
|
||||||
|
|
||||||
intentFilter.addAction("android.intent.action.HEADSET_PLUG");
|
intentFilter.addAction("android.intent.action.HEADSET_PLUG");
|
||||||
context.registerReceiver(new MyButtonClickReceiver(), intentFilter);
|
context.registerReceiver(new MyButtonClickReceiver(), intentFilter);
|
||||||
registerHeadsetReceiver();
|
registerHeadsetReceiver();
|
||||||
|
|
|
@ -17,6 +17,8 @@ import android.widget.ImageView;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.dirror.lyricviewx.LyricEntry;
|
||||||
|
import com.dirror.lyricviewx.LyricViewX;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.muqingbfq.R;
|
import com.muqingbfq.R;
|
||||||
|
@ -27,10 +29,6 @@ import com.muqingbfq.main;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Type;
|
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 {
|
public class FloatingLyricsService extends Service implements View.OnClickListener, View.OnTouchListener {
|
||||||
private WindowManager windowManager;
|
private WindowManager windowManager;
|
||||||
private View layout;
|
private View layout;
|
||||||
|
@ -39,26 +37,17 @@ public class FloatingLyricsService extends Service implements View.OnClickListen
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < LrcView.mLrcEntryList.size(); i++) {
|
for (int i = 0; i < LyricViewX.lyricEntryList.size(); i++) {
|
||||||
LrcEntry lineLrc = LrcView.mLrcEntryList.get(i);
|
LyricEntry lineLrc = LyricViewX.lyricEntryList.get(i);
|
||||||
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
|
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
|
||||||
index = i;
|
index = i;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index < LrcView.mLrcEntryList.size()) {
|
if (index < LyricViewX.lyricEntryList.size()) {
|
||||||
String text;
|
String text;
|
||||||
if (LrcView.mLrcEntryList.size() <= 3) {
|
LyricEntry currentLrc = LyricViewX.lyricEntryList.get(index);
|
||||||
for (LrcEntry a : LrcView.mLrcEntryList) {
|
|
||||||
if (a.time == 5940000 && a.text.equals("纯音乐,请欣赏")) {
|
|
||||||
text = "纯音乐,请欣赏";
|
|
||||||
binding.lrcView.setText(text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LrcEntry currentLrc = LrcView.mLrcEntryList.get(index);
|
|
||||||
text = currentLrc.text;
|
text = currentLrc.text;
|
||||||
if (currentLrc.secondText != null) {
|
if (currentLrc.secondText != null) {
|
||||||
text += "\n" + currentLrc.secondText;
|
text += "\n" + currentLrc.secondText;
|
||||||
|
|
|
@ -5,6 +5,7 @@ import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import androidx.viewbinding.ViewBinding;
|
import androidx.viewbinding.ViewBinding;
|
||||||
|
|
||||||
import com.jaeger.library.StatusBarUtil;
|
import com.jaeger.library.StatusBarUtil;
|
||||||
|
@ -29,13 +30,19 @@ public abstract class FragmentActivity<ViewBindingType extends ViewBinding>
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
public void setToolbar() {
|
public void setToolbar() {
|
||||||
setSupportActionBar(findViewById(R.id.toolbar));
|
View viewById = findViewById(R.id.toolbar);
|
||||||
|
if (viewById != null) {
|
||||||
|
setSupportActionBar((Toolbar) viewById);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
public void setContentView(int view) {
|
public void setContentView(int view) {
|
||||||
super.setContentView(view);
|
super.setContentView(view);
|
||||||
|
}
|
||||||
|
public void setContentView() {
|
||||||
|
binding = getViewBindingObject(getLayoutInflater());
|
||||||
|
setContentView(binding.getRoot());
|
||||||
setToolbar();
|
setToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +50,5 @@ public abstract class FragmentActivity<ViewBindingType extends ViewBinding>
|
||||||
public void setContentView(View view) {
|
public void setContentView(View view) {
|
||||||
StatusBarUtil.setTransparent(this);
|
StatusBarUtil.setTransparent(this);
|
||||||
super.setContentView(view);
|
super.setContentView(view);
|
||||||
setToolbar();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class gj {
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
a = "null";
|
a = "null";
|
||||||
}
|
}
|
||||||
Log.d("云音乐", a.toString());
|
Log.d("打印", a.toString());
|
||||||
floating.addtext(a.toString());
|
floating.addtext(a.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.WebChromeClient;
|
import android.webkit.WebChromeClient;
|
||||||
|
import android.webkit.WebSettings;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.WebViewClient;
|
import android.webkit.WebViewClient;
|
||||||
|
|
||||||
|
@ -41,27 +42,26 @@ import okhttp3.Response;
|
||||||
|
|
||||||
public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
||||||
WebView web;
|
WebView web;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ActivityLlqBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
protected ActivityLlqBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
||||||
return ActivityLlqBinding.inflate(layoutInflater);
|
return ActivityLlqBinding.inflate(layoutInflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
@Override
|
@Override
|
||||||
protected void UI(@Nullable Bundle savedInstanceState) {
|
protected void UI(@Nullable Bundle savedInstanceState) {
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
web = findViewById(R.id.webview);
|
web = binding.webview;
|
||||||
web.getSettings().setJavaScriptEnabled(true);
|
web.getSettings().setJavaScriptEnabled(true);
|
||||||
|
web.getSettings().setDomStorageEnabled(true);
|
||||||
|
// 禁用缓存
|
||||||
|
web.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||||
web.setWebViewClient(new WebViewClient() {
|
web.setWebViewClient(new WebViewClient() {
|
||||||
@Override
|
@Override
|
||||||
public void onPageFinished(WebView view, String url) {
|
public void onPageFinished(WebView view, String url) {
|
||||||
super.onPageFinished(view, url);
|
super.onPageFinished(view, url);
|
||||||
String title = view.getTitle();
|
setTitle(web.getTitle());
|
||||||
setTitle(title);
|
|
||||||
setSubtitle(url);
|
|
||||||
// 在这里获取到了网页的标题
|
// 在这里获取到了网页的标题
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -162,15 +162,9 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
||||||
});
|
});
|
||||||
loadUrl(intent.getStringExtra("url"));
|
loadUrl(intent.getStringExtra("url"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSubtitle(String url) {
|
|
||||||
binding.toolbar.setSubtitle(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadUrl(String url) {
|
private void loadUrl(String url) {
|
||||||
web.loadUrl(url);
|
web.loadUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
|
@ -180,13 +174,11 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
||||||
gj.ts(this, "权限已授予,请重新执行文件下载操作");
|
gj.ts(this, "权限已授予,请重新执行文件下载操作");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.llq, menu);
|
getMenuInflater().inflate(R.menu.llq, menu);
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (web.canGoBack()) {
|
if (web.canGoBack()) {
|
||||||
|
@ -195,8 +187,6 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
int itemId = item.getItemId();
|
int itemId = item.getItemId();
|
||||||
|
@ -213,4 +203,5 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,18 +17,20 @@ import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
import androidx.appcompat.app.AppCompatDelegate;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import com.colorpicker.ColorPickerView;
|
import com.colorpicker.ColorPickerView;
|
||||||
import com.colorpicker.builder.ColorPickerDialogBuilder;
|
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.materialswitch.MaterialSwitch;
|
||||||
import com.google.android.material.slider.Slider;
|
import com.google.android.material.slider.Slider;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.reflect.TypeToken;
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.muqingbfq.databinding.ActivitySzBinding;
|
||||||
import com.muqingbfq.databinding.ActivitySzSetlrcBinding;
|
import com.muqingbfq.databinding.ActivitySzSetlrcBinding;
|
||||||
|
import com.muqingbfq.mq.AppCompatActivity;
|
||||||
import com.muqingbfq.mq.FloatingLyricsService;
|
import com.muqingbfq.mq.FloatingLyricsService;
|
||||||
import com.muqingbfq.mq.wj;
|
import com.muqingbfq.mq.wj;
|
||||||
|
|
||||||
|
@ -36,48 +38,40 @@ import java.io.File;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import me.wcy.lrcview.LrcEntry;
|
public class sz extends AppCompatActivity<ActivitySzBinding> {
|
||||||
import me.wcy.lrcview.LrcView;
|
|
||||||
|
|
||||||
public class sz extends AppCompatActivity {
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected ActivitySzBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
||||||
super.onCreate(savedInstanceState);
|
return ActivitySzBinding.inflate(layoutInflater);
|
||||||
setContentView(R.layout.activity_sz);
|
|
||||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
|
||||||
setSupportActionBar(toolbar);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
toolbar.setTitle(getString(R.string.sz));
|
|
||||||
UI();
|
|
||||||
kaifazhe();
|
|
||||||
}
|
}
|
||||||
|
@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);
|
SharedPreferences theme = getSharedPreferences("theme", MODE_PRIVATE);
|
||||||
@SuppressLint("CommitPrefEdits") SharedPreferences.Editor edit = theme.edit();
|
@SuppressLint("CommitPrefEdits") SharedPreferences.Editor edit = theme.edit();
|
||||||
int i = theme.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
int i = theme.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
||||||
if (i == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
|
if (i == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
|
||||||
a1.setChecked(true);
|
binding.switchA1.setChecked(true);
|
||||||
a2.setEnabled(false);
|
binding.switchA2.setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
a1.setChecked(false);
|
binding.switchA1.setChecked(false);
|
||||||
a2.setEnabled(true);
|
binding.switchA2.setEnabled(true);
|
||||||
a2.setChecked(i == AppCompatDelegate.MODE_NIGHT_YES);
|
binding.switchA2.setChecked(i == AppCompatDelegate.MODE_NIGHT_YES);
|
||||||
}
|
}
|
||||||
a1.setOnCheckedChangeListener((compoundButton, b) -> {
|
binding.switchA1.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||||
if (b) {
|
if (b) {
|
||||||
// 跟随系统设置切换颜色模式
|
// 跟随系统设置切换颜色模式
|
||||||
int ms = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
int ms = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||||
AppCompatDelegate.setDefaultNightMode(ms);
|
AppCompatDelegate.setDefaultNightMode(ms);
|
||||||
edit.putInt("theme", 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()) {
|
if (compoundButton.isEnabled()) {
|
||||||
int ms;
|
int ms;
|
||||||
if (b) {
|
if (b) {
|
||||||
|
@ -91,8 +85,6 @@ public class sz extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
if (item.getItemId() == android.R.id.home) {
|
if (item.getItemId() == android.R.id.home) {
|
||||||
|
@ -100,7 +92,6 @@ public class sz extends AppCompatActivity {
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityResultLauncher<Intent> intent = registerForActivityResult(
|
ActivityResultLauncher<Intent> intent = registerForActivityResult(
|
||||||
new ActivityResultContracts.StartActivityForResult(),
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
result -> {
|
result -> {
|
||||||
|
@ -108,9 +99,9 @@ public class sz extends AppCompatActivity {
|
||||||
com.muqingbfq.mq.floating.start(sz.this);
|
com.muqingbfq.mq.floating.start(sz.this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
public void kaifazhe() {
|
public void kaifazhe() {
|
||||||
MaterialSwitch materialSwitch = findViewById(R.id.switch_kfz);
|
/* MaterialSwitch materialSwitch = findViewById(R.id
|
||||||
|
.switch_kfz);
|
||||||
materialSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
materialSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||||
if (b) {
|
if (b) {
|
||||||
if (!Settings.canDrawOverlays(this)) {
|
if (!Settings.canDrawOverlays(this)) {
|
||||||
|
@ -123,10 +114,8 @@ public class sz extends AppCompatActivity {
|
||||||
} else {
|
} else {
|
||||||
com.muqingbfq.mq.floating.end(sz.this);
|
com.muqingbfq.mq.floating.end(sz.this);
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class setlrc extends Fragment implements Slider.OnSliderTouchListener,
|
public static class setlrc extends Fragment implements Slider.OnSliderTouchListener,
|
||||||
Slider.OnChangeListener {
|
Slider.OnChangeListener {
|
||||||
ActivityResultLauncher<Intent> LyricsService =
|
ActivityResultLauncher<Intent> LyricsService =
|
||||||
|
@ -142,26 +131,17 @@ public class sz extends AppCompatActivity {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (bfqkz.mt.isPlaying()) {
|
if (bfqkz.mt.isPlaying()) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 0; i < LrcView.mLrcEntryList.size(); i++) {
|
for (int i = 0; i < LyricViewX.lyricEntryList.size(); i++) {
|
||||||
LrcEntry lineLrc = LrcView.mLrcEntryList.get(i);
|
LyricEntry lineLrc = LyricViewX.lyricEntryList.get(i);
|
||||||
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
|
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
|
||||||
index = i;
|
index = i;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index < LrcView.mLrcEntryList.size()) {
|
if (index < LyricViewX.lyricEntryList.size()) {
|
||||||
String text;
|
String text;
|
||||||
if (LrcView.mLrcEntryList.size() <= 3) {
|
LyricEntry currentLrc = LyricViewX.lyricEntryList.get(index);
|
||||||
for (LrcEntry a : LrcView.mLrcEntryList) {
|
|
||||||
if (a.time == 5940000 && a.text.equals("纯音乐,请欣赏")) {
|
|
||||||
text = "纯音乐,请欣赏";
|
|
||||||
binding.lrctext.setText(text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LrcEntry currentLrc = LrcView.mLrcEntryList.get(index);
|
|
||||||
text = currentLrc.text;
|
text = currentLrc.text;
|
||||||
if (currentLrc.secondText != null) {
|
if (currentLrc.secondText != null) {
|
||||||
text += "\n" + currentLrc.secondText;
|
text += "\n" + currentLrc.secondText;
|
||||||
|
|
|
@ -9,6 +9,8 @@ import android.text.NoCopySpan;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
@ -19,6 +21,7 @@ import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import com.muqingbfq.R;
|
import com.muqingbfq.R;
|
||||||
|
|
||||||
public class Edit extends LinearLayout {
|
public class Edit extends LinearLayout {
|
||||||
|
@ -44,6 +47,8 @@ public class Edit extends LinearLayout {
|
||||||
public EditText editText;
|
public EditText editText;
|
||||||
|
|
||||||
private void initView() {
|
private void initView() {
|
||||||
|
TextInputLayout layout = new TextInputLayout(getContext());
|
||||||
|
// layout.clearIconDrawable
|
||||||
setGravity(Gravity.CENTER_VERTICAL);
|
setGravity(Gravity.CENTER_VERTICAL);
|
||||||
setBackgroundResource(R.drawable.ui_editview);
|
setBackgroundResource(R.drawable.ui_editview);
|
||||||
setPadding(30, 0, 30, 0);
|
setPadding(30, 0, 30, 0);
|
||||||
|
@ -52,28 +57,29 @@ public class Edit extends LinearLayout {
|
||||||
editText.setHint("搜索");
|
editText.setHint("搜索");
|
||||||
editText.setSingleLine(true);
|
editText.setSingleLine(true);
|
||||||
editText.setBackground(null);
|
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.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
|
||||||
|
// editText.passwordToggleEnabled
|
||||||
addTextChangedListener(new TextWatcher() {
|
addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence var1, int var2, int var3, int var4) {
|
public void beforeTextChanged(CharSequence var1, int var2, int var3, int var4) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence var1, int var2, int var3, int var4) {
|
public void onTextChanged(CharSequence var1, int var2, int var3, int var4) {
|
||||||
iskong();
|
iskong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable var1) {
|
public void afterTextChanged(Editable var1) {
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
ImageView imageView = new ImageView(getContext());
|
ImageView imageView = new ImageView(getContext());
|
||||||
imageView.setImageResource(R.drawable.sousuo);
|
imageView.setImageResource(R.drawable.sousuo);
|
||||||
imageView.setImageTintList(ContextCompat.getColorStateList(getContext(),
|
|
||||||
R.color.text_tm));
|
|
||||||
addView(imageView, (int) TypedValue.applyDimension(TypedValue.
|
addView(imageView, (int) TypedValue.applyDimension(TypedValue.
|
||||||
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics())
|
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics())
|
||||||
, (int) TypedValue.applyDimension(TypedValue.
|
, (int) TypedValue.applyDimension(TypedValue.
|
||||||
|
@ -106,23 +112,15 @@ public class Edit extends LinearLayout {
|
||||||
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.Edit);
|
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.Edit);
|
||||||
boolean isEnabled = a.getBoolean(R.styleable.Edit_Enabled, true);
|
boolean isEnabled = a.getBoolean(R.styleable.Edit_Enabled, true);
|
||||||
if (!isEnabled) {
|
if (!isEnabled) {
|
||||||
removeView(editText);
|
|
||||||
removeView(imageView);
|
removeView(imageView);
|
||||||
removeView(chahao);
|
removeView(chahao);
|
||||||
TextView textView = new TextView(getContext());
|
|
||||||
textView.setTextColor(editText.getHintTextColors());
|
|
||||||
textView.setText("搜索");
|
|
||||||
|
|
||||||
// 将 px 值转换为 sp
|
// editText.setGravity(Gravity.CENTER);
|
||||||
float v = TypedValue.applyDimension(
|
editText.setFocusable(false);
|
||||||
TypedValue.COMPLEX_UNIT_PX,
|
editText.setFocusableInTouchMode(false);
|
||||||
editText.getTextSize(),
|
// editText.setEnabled(false);
|
||||||
getResources().getDisplayMetrics()
|
editText.setClickable(false);
|
||||||
) / getResources().getDisplayMetrics().scaledDensity;
|
|
||||||
textView.setTextSize(v);
|
|
||||||
setGravity(Gravity.CENTER);
|
|
||||||
addView(textView);
|
|
||||||
textView.setPadding(26, 26, 26, 26);
|
|
||||||
}
|
}
|
||||||
a.recycle();
|
a.recycle();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24"
|
android:viewportHeight="24"
|
||||||
android:width="128dp"
|
android:width="26dp"
|
||||||
android:height="128dp">
|
android:height="26dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#CCCCCC"
|
android:fillColor="#CCCCCC"
|
||||||
android:pathData="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z" />
|
android:pathData="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z" />
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24"
|
android:viewportHeight="24"
|
||||||
android:width="128dp"
|
android:width="26dp"
|
||||||
android:height="128dp">
|
android:height="26dp">
|
||||||
<path
|
<path
|
||||||
android:pathData="M12 21.35l-1.45 -1.32C5.4 15.36 2 12.27 2 8.5C2 5.41 4.42 3 7.5 3c1.74 0 3.41 0.81 4.5 2.08C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.41 22 8.5c0 3.77 -3.4 6.86 -8.55 11.53z"
|
android:pathData="M12 21.35l-1.45 -1.32C5.4 15.36 2 12.27 2 8.5C2 5.41 4.42 3 7.5 3c1.74 0 3.41 0.81 4.5 2.08C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.41 22 8.5c0 3.77 -3.4 6.86 -8.55 11.53z"
|
||||||
android:fillColor="#000000" />
|
android:fillColor="#000000" />
|
||||||
|
|
Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 438 B |
24
app/src/main/res/drawable/progress.xml
Normal file
24
app/src/main/res/drawable/progress.xml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:id="@android:id/background">
|
||||||
|
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
<size
|
||||||
|
android:width="100dp"
|
||||||
|
android:height="1dp" />
|
||||||
|
<solid android:color="#5CCCCCCC" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item android:id="@android:id/progress">
|
||||||
|
<scale android:scaleWidth="100%">
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<corners android:radius="16dp" />
|
||||||
|
<size
|
||||||
|
android:width="100dp"
|
||||||
|
android:height="1dp" />
|
||||||
|
<solid android:color="#FFFFFF" />
|
||||||
|
</shape>
|
||||||
|
</scale>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:height="36dp"
|
android:height="26dp"
|
||||||
android:width="36dp"
|
android:width="26dp"
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:drawable="@drawable/background" />
|
<item>
|
||||||
<item android:top="88.0dip">
|
|
||||||
<bitmap
|
<bitmap
|
||||||
android:gravity="center|top"
|
android:src="@mipmap/icon"
|
||||||
android:src="@mipmap/logo" />
|
android:scaleType="center"/>
|
||||||
</item>
|
</item>
|
||||||
</layer-list>
|
</layer-list>
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<me.wcy.lrcview.LrcView
|
<com.dirror.lyricviewx.LyricViewX
|
||||||
android:id="@+id/lrcView"
|
android:id="@+id/lrcView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -199,16 +199,11 @@
|
||||||
android:text="@string/_00_00"
|
android:text="@string/_00_00"
|
||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
|
|
||||||
<com.google.android.material.slider.Slider
|
<SeekBar
|
||||||
android:id="@+id/tdt"
|
android:id="@+id/tdt"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1" />
|
||||||
app:labelBehavior="gone"
|
|
||||||
app:thumbColor="#E6E6E6"
|
|
||||||
app:trackColorActive="#CCCCCC"
|
|
||||||
tools:ignore="SpeakableTextPresentCheck" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/time_b"
|
android:id="@+id/time_b"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -8,41 +8,6 @@
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:paddingHorizontal="10dp">
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/image1"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:src="@drawable/end"
|
|
||||||
app:tint="#F1F1F1" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:gravity="center_horizontal">
|
|
||||||
|
|
||||||
<com.muqingbfq.view.Text
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="歌曲"
|
|
||||||
android:textColor="#F1F1F1"
|
|
||||||
android:textSize="26sp"
|
|
||||||
android:visibility="visible" />
|
|
||||||
</LinearLayout>
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/image2"
|
|
||||||
android:layout_width="26dp"
|
|
||||||
android:layout_height="26dp"
|
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:src="@drawable/abc_ic_menu_share_mtrl_alpha"
|
|
||||||
app:tint="#F1F1F1" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/fragment_bfq"
|
android:id="@+id/fragment_bfq"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -50,57 +15,61 @@
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingHorizontal="10dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image1"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginTop="3dp"
|
||||||
|
android:src="@drawable/end"
|
||||||
|
app:tint="@color/tint_image"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<com.muqingbfq.view.CardImage
|
<com.muqingbfq.view.CardImage
|
||||||
android:id="@+id/cardview"
|
android:id="@+id/cardview"
|
||||||
android:layout_width="256dp"
|
android:layout_width="256dp"
|
||||||
android:layout_height="256dp"
|
android:layout_height="256dp"
|
||||||
app:cardCornerRadius="16dp"
|
|
||||||
app:cardUseCompatPadding="true"
|
|
||||||
app:cardBackgroundColor="@color/tm"
|
app:cardBackgroundColor="@color/tm"
|
||||||
|
app:cardCornerRadius="180dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||||
|
|
||||||
<me.wcy.lrcview.LrcView
|
<com.dirror.lyricviewx.LyricViewX
|
||||||
android:id="@+id/lrcView"
|
android:id="@+id/lrcView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
app:lrcCurrentTextColor="#FFFFFF"
|
||||||
|
app:lrcNormalTextColor="#FFFDFD"
|
||||||
|
app:lrcTimelineTextColor="#FFFFFF"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||||
app:lrcCurrentTextColor="#EEEEEE"
|
|
||||||
app:lrcNormalTextColor="#CCCCCC"
|
|
||||||
app:lrcTimelineTextColor="#EEEEEE"
|
|
||||||
app:lrcNormalTextSize="16sp"
|
|
||||||
app:lrcTextSize="20sp" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="6dp"
|
|
||||||
android:paddingBottom="10dp">
|
android:paddingBottom="10dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="6dp"
|
android:paddingHorizontal="10dp"
|
||||||
android:layout_marginEnd="6dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:gravity="center_vertical"
|
android:orientation="vertical"
|
||||||
android:orientation="horizontal"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/tdt"
|
app:layout_constraintBottom_toTopOf="@id/tdt"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
app:tint="#CCCCCC">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="6dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.muqingbfq.view.Text
|
<com.muqingbfq.view.Text
|
||||||
android:id="@+id/name"
|
android:id="@+id/name"
|
||||||
|
@ -108,9 +77,9 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="@string/name"
|
android:text="@string/name"
|
||||||
android:textColor="#CCCCCC"
|
android:textColor="@color/tint_image"
|
||||||
android:textStyle="bold"
|
android:textSize="26sp"
|
||||||
android:textSize="26sp" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<com.muqingbfq.view.Text
|
<com.muqingbfq.view.Text
|
||||||
android:id="@+id/zz"
|
android:id="@+id/zz"
|
||||||
|
@ -118,32 +87,53 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="@string/zz"
|
android:text="@string/zz"
|
||||||
android:textColor="#CCCCCC"
|
android:textColor="@color/tint_image"
|
||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<ImageView
|
<SeekBar
|
||||||
android:id="@+id/like"
|
android:id="@+id/tdt"
|
||||||
android:layout_width="36dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="36dp"
|
android:layout_height="wrap_content"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
android:layout_marginBottom="3dp"
|
||||||
android:src="@drawable/like"
|
android:background="@null"
|
||||||
app:tint="#CCCCCC"
|
android:paddingStart="10dp"
|
||||||
tools:ignore="ContentDescription" />
|
android:paddingEnd="10dp"
|
||||||
</LinearLayout>
|
android:progressDrawable="@drawable/progress"
|
||||||
|
android:theme="@null"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/time_a" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/time_a"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:text="@string/_00_00"
|
||||||
|
android:textColor="@color/tint_image"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/linearLayout3"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/time_b"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:text="@string/_00_00"
|
||||||
|
android:textColor="@color/tint_image"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/linearLayout3"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
<com.google.android.flexbox.FlexboxLayout
|
<com.google.android.flexbox.FlexboxLayout
|
||||||
android:id="@+id/linearLayout3"
|
android:id="@+id/linearLayout3"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="26dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
app:alignItems="center"
|
app:alignItems="center"
|
||||||
app:flexDirection="row"
|
app:flexDirection="row"
|
||||||
app:justifyContent="space_around"
|
app:justifyContent="space_around"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/download"
|
app:layout_constraintBottom_toTopOf="@+id/layout2"
|
||||||
tools:ignore="MissingConstraints"
|
tools:ignore="MissingConstraints">
|
||||||
tools:layout_editor_absoluteX="6dp">
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/control"
|
android:id="@+id/control"
|
||||||
|
@ -151,7 +141,7 @@
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/mt_sx"
|
android:src="@drawable/mt_sx"
|
||||||
app:tint="#CCCCCC"
|
app:tint="@color/tint_image"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -160,16 +150,17 @@
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/syq"
|
android:src="@drawable/syq"
|
||||||
app:tint="#CCCCCC"
|
app:tint="@color/tint_image"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/kg"
|
android:id="@+id/kg"
|
||||||
android:layout_width="46dp"
|
android:layout_width="66dp"
|
||||||
android:layout_height="46dp"
|
android:layout_height="66dp"
|
||||||
android:background="?selectableItemBackgroundBorderless"
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/zt"
|
android:src="@drawable/zt"
|
||||||
app:tint="#CCCCCC"
|
app:tint="@color/tint_image"
|
||||||
|
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -178,7 +169,7 @@
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/xyq"
|
android:src="@drawable/xyq"
|
||||||
app:tint="#CCCCCC"
|
app:tint="@color/tint_image"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
@ -187,37 +178,20 @@
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/mplist"
|
android:src="@drawable/mplist"
|
||||||
app:tint="#CCCCCC"
|
app:tint="@color/tint_image"
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
</com.google.android.flexbox.FlexboxLayout>
|
</com.google.android.flexbox.FlexboxLayout>
|
||||||
|
|
||||||
<com.google.android.material.slider.Slider
|
<com.google.android.flexbox.FlexboxLayout
|
||||||
android:id="@+id/tdt"
|
android:id="@+id/layout2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:labelBehavior="gone"
|
app:alignItems="center"
|
||||||
app:layout_constraintBottom_toTopOf="@id/time_a"
|
app:flexDirection="row"
|
||||||
app:thumbColor="#E6E6E6"
|
app:justifyContent="space_around"
|
||||||
app:trackColorActive="#CCCCCC"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
tools:ignore="SpeakableTextPresentCheck" />
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent">
|
||||||
<TextView
|
|
||||||
android:id="@+id/time_a"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="10dp"
|
|
||||||
android:text="@string/_00_00"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/linearLayout3"
|
|
||||||
app:layout_constraintStart_toStartOf="parent" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/time_b"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="10dp"
|
|
||||||
android:text="@string/_00_00"
|
|
||||||
app:layout_constraintBottom_toTopOf="@id/linearLayout3"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/download"
|
android:id="@+id/download"
|
||||||
|
@ -225,12 +199,29 @@
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/download"
|
android:src="@drawable/download"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:tint="@color/tint_image"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:tint="#CCCCCC"
|
|
||||||
tools:ignore="ContentDescription" />
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/like"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/like"
|
||||||
|
app:tint="@color/tint_image"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image2"
|
||||||
|
android:layout_width="26dp"
|
||||||
|
android:layout_height="26dp"
|
||||||
|
android:layout_marginTop="3dp"
|
||||||
|
android:src="@drawable/abc_ic_menu_share_mtrl_alpha"
|
||||||
|
app:tint="@color/tint_image"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
</com.google.android.flexbox.FlexboxLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -14,7 +14,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="26sp"
|
android:textSize="26sp"
|
||||||
android:transitionName="view"
|
android:transitionName="text"
|
||||||
android:textColor="@color/text"/>
|
android:textColor="@color/text"/>
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,31 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fitsSystemWindows="true"
|
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fitsSystemWindows="true">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/webViewProgressBar"
|
android:id="@+id/webViewProgressBar"
|
||||||
style="?android:attr/progressBarStyleHorizontal"
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="6dp"
|
android:layout_height="6dp"
|
||||||
android:indeterminate="false"
|
android:indeterminate="false"
|
||||||
android:max="100" />
|
android:max="100" />
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<WebView
|
<WebView
|
||||||
android:id="@+id/webview"
|
android:id="@+id/webview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent"
|
||||||
</LinearLayout>
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -8,7 +8,6 @@
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:transitionName="view"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
@ -22,6 +21,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="@color/text"
|
android:textColor="@color/text"
|
||||||
|
android:transitionName="text"
|
||||||
android:textSize="26sp" />
|
android:textSize="26sp" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
|
|
|
@ -1,25 +1,40 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:orientation="vertical"
|
|
||||||
tools:context=".activity_search">
|
tools:context=".activity_search">
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.search.SearchView
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/searchview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:hint="@string/search"
|
||||||
|
app:layout_anchor="@id/toolbar">
|
||||||
|
<ListView
|
||||||
|
android:id="@+id/search_recycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
</com.google.android.material.search.SearchView>
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/barlayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
<com.muqingbfq.view.Edit
|
<com.google.android.material.search.SearchBar
|
||||||
android:id="@+id/editview"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:transitionName="view"
|
app:defaultMarginsEnabled="true"
|
||||||
android:enabled="false"/>
|
app:hideNavigationIcon="false"
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
app:navigationIcon="@drawable/end"
|
||||||
|
android:transitionName="edit"
|
||||||
|
android:hint="@string/search"/>
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
|
||||||
android:layout_weight="1">
|
android:layout_weight="1">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/xxbj1"
|
android:id="@+id/xxbj1"
|
||||||
|
@ -43,8 +58,9 @@
|
||||||
android:id="@+id/deleat"
|
android:id="@+id/deleat"
|
||||||
android:layout_width="36dp"
|
android:layout_width="36dp"
|
||||||
android:layout_height="36dp"
|
android:layout_height="36dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
app:tint="@color/text"
|
||||||
|
android:background="?selectableItemBackgroundBorderless"
|
||||||
android:contentDescription="@string/deleat"
|
android:contentDescription="@string/deleat"
|
||||||
android:src="@drawable/delete" />
|
android:src="@drawable/delete" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -60,21 +76,15 @@
|
||||||
android:name="com.muqingbfq.fragment.search"
|
android:name="com.muqingbfq.fragment.search"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:layout="@layout/fragment_search" />
|
tools:layout="@layout/fragment_search" />
|
||||||
<ListView
|
|
||||||
android:id="@+id/search_recycler"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:background="?android:colorBackground"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/bfq_db"
|
android:id="@+id/bfq_db"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:backgroundTint="@color/bj"
|
android:backgroundTint="@color/bj"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
|
||||||
android:name="com.muqingbfq.fragment.bfq_db"
|
android:name="com.muqingbfq.fragment.bfq_db"
|
||||||
tools:layout="@layout/fragment_bfq_db" />
|
tools:layout="@layout/fragment_bfq_db" />
|
||||||
|
|
||||||
</LinearLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
|
android:orientation="vertical"
|
||||||
tools:context=".sz">
|
tools:context=".sz">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
|
@ -16,13 +16,13 @@
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginHorizontal="10dp">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
android:padding="16dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -32,45 +32,32 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="主题模式"
|
android:layout_marginTop="6dp"
|
||||||
android:textSize="20sp" />
|
android:layout_marginBottom="6dp"
|
||||||
|
android:text="主题"/>
|
||||||
|
|
||||||
<com.google.android.material.materialswitch.MaterialSwitch
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
android:id="@+id/switch_a1"
|
android:id="@+id/switch_a1"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checked="true"
|
android:checked="true"
|
||||||
android:text="根据系统" />
|
android:textSize="20sp"
|
||||||
|
android:text="跟随系统模式来选择" />
|
||||||
|
|
||||||
<com.google.android.material.materialswitch.MaterialSwitch
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
android:id="@+id/switch_a2"
|
android:id="@+id/switch_a2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="26dp"
|
android:textSize="20sp"
|
||||||
android:text="深色模式" />
|
android:text="深色模式" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
<TextView
|
||||||
|
|
||||||
<com.google.android.material.divider.MaterialDivider
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.google.android.material.materialswitch.MaterialSwitch
|
|
||||||
android:id="@+id/switch_kfz"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="开发者模式" />
|
android:layout_marginTop="6dp"
|
||||||
</LinearLayout>
|
android:layout_marginBottom="6dp"
|
||||||
|
android:text="歌词"/>
|
||||||
<com.google.android.material.divider.MaterialDivider
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<androidx.fragment.app.FragmentContainerView
|
<androidx.fragment.app.FragmentContainerView
|
||||||
android:id="@+id/fragment_setlrc"
|
android:id="@+id/fragment_setlrc"
|
||||||
|
|
|
@ -5,21 +5,16 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="歌词调节"
|
|
||||||
android:textSize="20sp" />
|
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cardUseCompatPadding="true">
|
app:cardUseCompatPadding="true"
|
||||||
|
app:contentPadding="10dp">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:padding="6dp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/lrctext"
|
android:id="@+id/lrctext"
|
||||||
|
@ -92,14 +87,15 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.materialswitch.MaterialSwitch
|
|
||||||
android:id="@+id/switch_a1"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="歌词开关"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/layout2" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<com.google.android.material.materialswitch.MaterialSwitch
|
||||||
|
android:id="@+id/switch_a1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="歌词开关"
|
||||||
|
android:textSize="20sp"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/layout2" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -8,23 +8,20 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:fitsSystemWindows="true">
|
android:fitsSystemWindows="true">
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
|
||||||
|
<com.google.android.material.search.SearchBar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
|
||||||
<com.muqingbfq.view.Edit
|
|
||||||
android:id="@+id/editView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="10dp"
|
android:transitionName="edit"
|
||||||
app:Enabled="false"
|
app:layout_scrollFlags="exitUntilCollapsed"
|
||||||
tools:ignore="TouchTargetSizeCheck" />
|
android:hint="@string/search"/>
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
<androidx.core.widget.NestedScrollView
|
<androidx.core.widget.NestedScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:fillViewport="true"
|
android:fillViewport="true"
|
||||||
|
android:layout_marginHorizontal="10dp"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -34,17 +31,14 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:text="每日趣荐"
|
android:text="每日趣荐"
|
||||||
android:textSize="26sp"
|
android:textSize="16sp"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardUseCompatPadding="true">
|
||||||
app:contentPadding="6dp">
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/recyclerview1_bar"
|
android:id="@+id/recyclerview1_bar"
|
||||||
|
@ -55,7 +49,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/nullPlaylists"
|
android:text="@string/nullPlaylists"
|
||||||
android:textSize="26sp"
|
android:textSize="16sp"
|
||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_centerHorizontal="true"/>
|
android:layout_centerHorizontal="true"/>
|
||||||
|
@ -72,17 +66,14 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:text="每日一首"
|
android:text="每日一首"
|
||||||
android:textSize="26sp"
|
android:textSize="16sp"
|
||||||
tools:ignore="HardcodedText" />
|
tools:ignore="HardcodedText" />
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardUseCompatPadding="true">
|
||||||
app:contentPadding="6dp">
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/recyclerview2_bar"
|
android:id="@+id/recyclerview2_bar"
|
||||||
|
@ -93,7 +84,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/nullPlaylists"
|
android:text="@string/nullPlaylists"
|
||||||
android:textSize="26sp"
|
android:textSize="16sp"
|
||||||
android:padding="6dp"
|
android:padding="6dp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_centerHorizontal="true"/>
|
android:layout_centerHorizontal="true"/>
|
||||||
|
|
|
@ -20,5 +20,6 @@
|
||||||
android:id="@+id/text1"
|
android:id="@+id/text1"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:transitionName="text"
|
||||||
android:text="@string/app_name"/>
|
android:text="@string/app_name"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB |
|
@ -1,12 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<declare-styleable name="LrcView">
|
|
||||||
<!--声明MyTextView需要使用系统定义过的text属性,注意前面需要加上android命名-->
|
|
||||||
<attr name="TextColor" format="color" />
|
|
||||||
<attr name="Lrcline" format="boolean" />
|
|
||||||
<attr name="addOnGlobalLayoutListener" format="boolean" />
|
|
||||||
</declare-styleable>
|
|
||||||
|
|
||||||
<declare-styleable name="ColorPickerPreference">
|
<declare-styleable name="ColorPickerPreference">
|
||||||
<attr name="alphaSlider" format="boolean"/>
|
<attr name="alphaSlider" format="boolean"/>
|
||||||
<attr name="lightnessSlider" format="boolean"/>
|
<attr name="lightnessSlider" format="boolean"/>
|
||||||
|
@ -33,4 +26,31 @@
|
||||||
<declare-styleable name="Edit">
|
<declare-styleable name="Edit">
|
||||||
<attr name="Enabled" format="boolean" />
|
<attr name="Enabled" format="boolean" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
<declare-styleable name="LyricView">
|
||||||
|
<attr name="lrcTextSize" format="dimension"/>
|
||||||
|
<attr name="lrcNormalTextSize" format="dimension"/>
|
||||||
|
<attr name="lrcSentenceDividerHeight" format="dimension"/>
|
||||||
|
<attr name="lrcTranslateDividerHeight" format="dimension"/>
|
||||||
|
<attr name="lrcNormalTextColor" format="reference|color"/>
|
||||||
|
<attr name="lrcCurrentTextColor" format="reference|color"/>
|
||||||
|
<attr name="lrcTimelineTextColor" format="reference|color"/>
|
||||||
|
<attr name="lrcAnimationDuration" format="integer"/>
|
||||||
|
<attr name="lrcLabel" format="string"/>
|
||||||
|
<attr name="lrcPadding" format="dimension"/>
|
||||||
|
<attr name="lrcTimelineColor" format="reference|color"/>
|
||||||
|
<attr name="lrcTimelineHeight" format="dimension"/>
|
||||||
|
<attr name="lrcPlayDrawable" format="reference"/>
|
||||||
|
<attr name="lrcTimeTextColor" format="reference|color"/>
|
||||||
|
<attr name="lrcTimeTextSize" format="dimension"/>
|
||||||
|
<attr name="lrcTextGravity">
|
||||||
|
<enum name="center" value="0"/>
|
||||||
|
<enum name="left" value="1"/>
|
||||||
|
<enum name="right" value="2"/>
|
||||||
|
</attr>
|
||||||
|
<attr name="lrcTranslateTextScaleValue" format="float"/>
|
||||||
|
<attr name="lrcHorizontalOffset" format="dimension"/>
|
||||||
|
<attr name="lrcHorizontalOffsetPercent" format="float"/>
|
||||||
|
<attr name="lrcItemOffsetPercent" format="float"/>
|
||||||
|
<attr name="lrcIsDrawTranslation" format="boolean"/>
|
||||||
|
</declare-styleable>
|
||||||
</resources>
|
</resources>
|
|
@ -19,4 +19,12 @@
|
||||||
<color name="thumbColor">#625B71</color>
|
<color name="thumbColor">#625B71</color>
|
||||||
<!-- <color name="button_bj">@color/bj</color>-->
|
<!-- <color name="button_bj">@color/bj</color>-->
|
||||||
<color name="bj_tint">#FFCCCC</color>
|
<color name="bj_tint">#FFCCCC</color>
|
||||||
|
|
||||||
|
<color name="tint_image">#F1F1F1</color>
|
||||||
|
|
||||||
|
<color name="lrc_normal_text_color">#A2A2A2</color>
|
||||||
|
<color name="lrc_current_text_color">#000000</color>
|
||||||
|
<color name="lrc_timeline_text_color">#343434</color>
|
||||||
|
<color name="lrc_timeline_color">#809E9E9E</color>
|
||||||
|
<color name="lrc_time_text_color">#809E9E9E</color>
|
||||||
</resources>
|
</resources>
|
|
@ -2,6 +2,17 @@
|
||||||
<resources>
|
<resources>
|
||||||
<dimen name="text_margin">16dp</dimen>
|
<dimen name="text_margin">16dp</dimen>
|
||||||
|
|
||||||
|
<!-- 行间距 -->
|
||||||
|
|
||||||
|
<dimen name="default_slider_height">36dp</dimen>
|
||||||
|
<dimen name="default_slider_margin">24dp</dimen>
|
||||||
|
<dimen name="default_slider_bar_height">4dp</dimen>
|
||||||
|
<dimen name="default_slider_handler_radius">10dp</dimen>
|
||||||
|
<dimen name="default_padding_side">24dp</dimen>
|
||||||
|
<dimen name="default_preview_height">40dp</dimen>
|
||||||
|
<dimen name="default_preview_image_height">36dp</dimen>
|
||||||
|
<dimen name="default_margin_top">20dp</dimen>
|
||||||
|
|
||||||
<integer name="lrc_animation_duration">1000</integer>
|
<integer name="lrc_animation_duration">1000</integer>
|
||||||
<dimen name="lrc_text_size">16sp</dimen>
|
<dimen name="lrc_text_size">16sp</dimen>
|
||||||
<dimen name="lrc_time_text_size">12sp</dimen>
|
<dimen name="lrc_time_text_size">12sp</dimen>
|
||||||
|
@ -11,13 +22,4 @@
|
||||||
<dimen name="lrc_timeline_height">1dp</dimen>
|
<dimen name="lrc_timeline_height">1dp</dimen>
|
||||||
<dimen name="lrc_drawable_width">30dp</dimen>
|
<dimen name="lrc_drawable_width">30dp</dimen>
|
||||||
<dimen name="lrc_time_width">40dp</dimen>
|
<dimen name="lrc_time_width">40dp</dimen>
|
||||||
|
|
||||||
<dimen name="default_slider_height">36dp</dimen>
|
|
||||||
<dimen name="default_slider_margin">24dp</dimen>
|
|
||||||
<dimen name="default_slider_bar_height">4dp</dimen>
|
|
||||||
<dimen name="default_slider_handler_radius">10dp</dimen>
|
|
||||||
<dimen name="default_padding_side">24dp</dimen>
|
|
||||||
<dimen name="default_preview_height">40dp</dimen>
|
|
||||||
<dimen name="default_preview_image_height">36dp</dimen>
|
|
||||||
<dimen name="default_margin_top">20dp</dimen>
|
|
||||||
</resources>
|
</resources>
|
|
@ -44,4 +44,10 @@
|
||||||
<item>男</item>
|
<item>男</item>
|
||||||
<item>女</item>
|
<item>女</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
|
<string-array name="theme">
|
||||||
|
<item>跟随系统</item>
|
||||||
|
<item>浅色模式</item>
|
||||||
|
<item>深色模式</item>
|
||||||
|
</string-array>
|
||||||
</resources>
|
</resources>
|
14
build.gradle
14
build.gradle
|
@ -1,4 +1,18 @@
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application' version '8.1.0' apply false
|
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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
1
lrcview/.gitignore
vendored
1
lrcview/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
/build
|
|
|
@ -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'
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
</manifest>
|
|
|
@ -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<LrcEntry> {
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<LrcEntry> parseLrc(File[] lrcFiles) {
|
|
||||||
if (lrcFiles == null || lrcFiles.length != 2 || lrcFiles[0] == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
File mainLrcFile = lrcFiles[0];
|
|
||||||
File secondLrcFile = lrcFiles[1];
|
|
||||||
List<LrcEntry> mainEntryList = parseLrc(mainLrcFile);
|
|
||||||
List<LrcEntry> 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<LrcEntry> parseLrc(File lrcFile) {
|
|
||||||
if (lrcFile == null || !lrcFile.exists()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<LrcEntry> 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<LrcEntry> 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<LrcEntry> parseLrc(String[] lrcTexts) {
|
|
||||||
if (lrcTexts == null || lrcTexts.length != 2 || TextUtils.isEmpty(lrcTexts[0])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String mainLrcText = lrcTexts[0];
|
|
||||||
String secondLrcText = lrcTexts[1];
|
|
||||||
List<LrcEntry> mainEntryList = parseLrc(mainLrcText);
|
|
||||||
List<LrcEntry> 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<LrcEntry> parseLrc(String lrcText) {
|
|
||||||
if (TextUtils.isEmpty(lrcText)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lrcText.startsWith("\uFEFF")) {
|
|
||||||
lrcText = lrcText.replace("\uFEFF", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
List<LrcEntry> entryList = new ArrayList<>();
|
|
||||||
String[] array = lrcText.split("\\n");
|
|
||||||
for (String line : array) {
|
|
||||||
List<LrcEntry> 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<LrcEntry> 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<LrcEntry> 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<LrcEntry> 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<List<LrcEntry>> callable = () -> LrcUtils.parseLrc(new File[]{mainLrcFile, secondLrcFile});
|
|
||||||
Future<List<LrcEntry>> future = executor.submit(callable);
|
|
||||||
try {
|
|
||||||
List<LrcEntry> 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<List<LrcEntry>> callable = () -> LrcUtils.parseLrc(
|
|
||||||
new String[]{mainLrcText, secondLrcText});
|
|
||||||
Future<List<LrcEntry>> future = executor.submit(callable);
|
|
||||||
try {
|
|
||||||
List<LrcEntry> 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<List<LrcEntry>> callable = () -> LrcUtils.parseLrc(
|
|
||||||
new String[]{mainLrcText, secondLrcText});
|
|
||||||
Future<List<LrcEntry>> 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<LrcEntry> 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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<declare-styleable name="LrcView">
|
|
||||||
<attr name="lrcTextSize" format="dimension" />
|
|
||||||
<attr name="lrcNormalTextSize" format="dimension" />
|
|
||||||
<attr name="lrcDividerHeight" format="dimension" />
|
|
||||||
<attr name="lrcNormalTextColor" format="reference|color" />
|
|
||||||
<attr name="lrcCurrentTextColor" format="reference|color" />
|
|
||||||
<attr name="lrcTimelineTextColor" format="reference|color" />
|
|
||||||
<attr name="lrcAnimationDuration" format="integer" />
|
|
||||||
<attr name="lrcLabel" format="string" />
|
|
||||||
<attr name="lrcPadding" format="dimension" />
|
|
||||||
<attr name="lrcTimelineColor" format="reference|color" />
|
|
||||||
<attr name="lrcTimelineHeight" format="dimension" />
|
|
||||||
<attr name="lrcPlayDrawable" format="reference" />
|
|
||||||
<attr name="lrcTimeTextColor" format="reference|color" />
|
|
||||||
<attr name="lrcTimeTextSize" format="dimension" />
|
|
||||||
<attr name="lrcTextGravity">
|
|
||||||
<enum name="center" value="0" />
|
|
||||||
<enum name="left" value="1" />
|
|
||||||
<enum name="right" value="2" />
|
|
||||||
</attr>
|
|
||||||
</declare-styleable>
|
|
||||||
</resources>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<color name="lrc_normal_text_color">#9E9E9E</color>
|
|
||||||
<color name="lrc_current_text_color">#FF4081</color>
|
|
||||||
<color name="lrc_timeline_text_color">#F8BBD0</color>
|
|
||||||
<color name="lrc_timeline_color">#809E9E9E</color>
|
|
||||||
<color name="lrc_time_text_color">#809E9E9E</color>
|
|
||||||
</resources>
|
|
|
@ -1,11 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<integer name="lrc_animation_duration">1000</integer>
|
|
||||||
<dimen name="lrc_text_size">20sp</dimen>
|
|
||||||
<dimen name="lrcNormalTextSize">16sp</dimen>
|
|
||||||
<dimen name="lrc_time_text_size">12sp</dimen>
|
|
||||||
<dimen name="lrc_divider_height">16dp</dimen>
|
|
||||||
<dimen name="lrc_timeline_height">1dp</dimen>
|
|
||||||
<dimen name="lrc_drawable_width">30dp</dimen>
|
|
||||||
<dimen name="lrc_time_width">40dp</dimen>
|
|
||||||
</resources>
|
|
|
@ -1,3 +0,0 @@
|
||||||
<resources>
|
|
||||||
<string name="lrc_label">暂无歌词</string>
|
|
||||||
</resources>
|
|
|
@ -17,4 +17,4 @@ dependencyResolutionManagement {
|
||||||
rootProject.name = "Cloud_music"
|
rootProject.name = "Cloud_music"
|
||||||
include ':app'
|
include ':app'
|
||||||
include(':StatusBarUtil')
|
include(':StatusBarUtil')
|
||||||
include(":lrcview")
|
//include(":lrcview")
|
Loading…
Reference in New Issue
Block a user