修复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$/StatusBarUtil" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/lrcview" />
|
||||
</set>
|
||||
</option>
|
||||
<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,.*" />
|
||||
</inspection_tool>
|
||||
<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">
|
||||
<option name="processCode" 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>
|
||||
</component>
|
||||
<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>
|
|
@ -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
|
||||
* 后台源码-Github: [网易云音乐 API](https://github.com/Binaryify/NeteaseCloudMusicApi)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
}
|
||||
android {
|
||||
signingConfigs {
|
||||
|
@ -18,8 +19,7 @@ android {
|
|||
//noinspection ExpiredTargetSdkVersion,OldTargetApi
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.9.9"
|
||||
|
||||
versionName "2.0.0"
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
|
@ -39,11 +39,15 @@ android {
|
|||
outputFileName = "Cloud_music-${variant.name}-v${variant.versionName}.apk"
|
||||
}
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
viewBinding {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.9.0'
|
||||
|
||||
|
@ -54,6 +58,7 @@ dependencies {
|
|||
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
|
||||
//图片处理
|
||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||
|
||||
implementation "androidx.palette:palette:1.0.0"
|
||||
// 废弃的歌词组件
|
||||
// implementation 'com.github.wangchenyan:lrcview:2.2.1'
|
||||
|
@ -65,6 +70,9 @@ dependencies {
|
|||
implementation 'com.mpatric:mp3agic:0.9.1'
|
||||
|
||||
// 沉浸式状态栏
|
||||
api project(path: ':StatusBarUtil')
|
||||
api project(path: ':lrcview')
|
||||
implementation project(path: ':StatusBarUtil')
|
||||
// api project(path: ':lrcview')
|
||||
//歌词组件库
|
||||
api "com.github.cy745:EaseView:e11c3208a9"
|
||||
api "androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03"
|
||||
}
|
|
@ -24,7 +24,6 @@ import java.io.IOException;
|
|||
|
||||
public class MediaPlayer extends android.media.MediaPlayer {
|
||||
// 每秒更新一次进度
|
||||
|
||||
@SuppressLint("UnsafeOptInUsageError")
|
||||
public MediaPlayer() {
|
||||
setOnErrorListener((mediaPlayer, i, i1) -> {
|
||||
|
@ -88,8 +87,11 @@ public class MediaPlayer extends android.media.MediaPlayer {
|
|||
bfqkz.xm = mp3;
|
||||
main.handler.post(() -> {
|
||||
bfui();
|
||||
bfqkz.notify.tzl();
|
||||
if (bfqkz.notify != null) {
|
||||
bfqkz.notify.tzl();
|
||||
}
|
||||
});
|
||||
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
|
@ -14,13 +14,13 @@ import android.view.Menu;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
@ -30,6 +30,7 @@ import com.google.android.flexbox.FlexDirection;
|
|||
import com.google.android.flexbox.FlexWrap;
|
||||
import com.google.android.flexbox.FlexboxLayoutManager;
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
import com.google.android.material.search.SearchView;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.muqingbfq.databinding.ActivitySearchBinding;
|
||||
|
@ -37,7 +38,6 @@ import com.muqingbfq.fragment.search;
|
|||
import com.muqingbfq.mq.FragmentActivity;
|
||||
import com.muqingbfq.mq.gj;
|
||||
import com.muqingbfq.mq.wj;
|
||||
import com.muqingbfq.mq.wl;
|
||||
import com.muqingbfq.view.Edit;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
@ -55,14 +55,20 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
|
||||
public static void start(Activity context, View view) {
|
||||
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
||||
view, "view");
|
||||
view, "edit");
|
||||
context.startActivity(new Intent(context, activity_search.class), options.toBundle());
|
||||
}
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getViewBinding().getRoot());
|
||||
FlexboxLayoutManager manager = new FlexboxLayoutManager(this);
|
||||
setToolbar();
|
||||
FlexboxLayoutManager manager = new FlexboxLayoutManager(this){
|
||||
@Override
|
||||
public boolean canScrollVertically() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
//设置主轴排列方式
|
||||
manager.setFlexDirection(FlexDirection.ROW);
|
||||
//设置是否换行
|
||||
|
@ -70,16 +76,6 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
manager.setAlignItems(AlignItems.STRETCH);
|
||||
binding.listRecycler.setLayoutManager(manager);
|
||||
binding.listRecycler.setAdapter(new SearchRecordAdapter());
|
||||
|
||||
binding.editview.setOnEditorActionListener((v, actionId, event) -> {
|
||||
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||
String str = v.getText().toString();
|
||||
if (!str.equals("")) {
|
||||
start(str);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
binding.deleat.setOnClickListener(v -> new MaterialAlertDialogBuilder(
|
||||
activity_search.this)
|
||||
.setTitle("删除")
|
||||
|
@ -109,20 +105,17 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
if (null != v) {
|
||||
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
|
||||
}
|
||||
binding.editview.setText(list.get(i));//把选择的选项内容展示在EditText上
|
||||
binding.toolbar.setText(list.get(i));//把选择的选项内容展示在EditText上
|
||||
dismiss();//如果已经选择了,隐藏起来
|
||||
start(binding.editview.getText().toString());
|
||||
|
||||
start(binding.toolbar.getText().toString());
|
||||
});
|
||||
Object o = new Object();
|
||||
binding.editview.addTextChangedListener(new Edit.TextWatcher() {
|
||||
binding.searchview.getEditText().addTextChangedListener(new Edit.TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
binding.editview.iskong();
|
||||
if (TextUtils.isEmpty(s)) {
|
||||
listPopupWindow.setVisibility(View.GONE);
|
||||
return;
|
||||
|
@ -135,7 +128,8 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
@Override
|
||||
public void run() {
|
||||
synchronized (o) {
|
||||
String hq = wl.hq("/search/suggest?keywords=" + s + "&type=mobile");
|
||||
String hq = com.muqingbfq.mq.wl.
|
||||
hq("/search/suggest?keywords=" + s + "&type=mobile");
|
||||
try {
|
||||
JSONArray jsonArray = new JSONObject(hq).getJSONObject("result")
|
||||
.getJSONArray("allMatch");
|
||||
|
@ -153,18 +147,46 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
});
|
||||
gj.tcjp(binding.editview.editText);
|
||||
/* if (binding.toolbar.collapse(contextualToolbar, binding.barlayout)) {
|
||||
// Clear selection.
|
||||
return;
|
||||
}*/
|
||||
binding.searchview.inflateMenu(R.menu.search);
|
||||
binding.searchview.setOnMenuItemClickListener(
|
||||
menuItem -> {
|
||||
binding.searchview.hide();
|
||||
start(binding.searchview.getText().toString());
|
||||
return true;
|
||||
});
|
||||
|
||||
binding.searchview.addTransitionListener(
|
||||
(searchView, previousState, newState) -> {
|
||||
if (newState == SearchView.TransitionState.HIDDEN) {
|
||||
binding.toolbar.setText(searchView.getText());
|
||||
}
|
||||
});
|
||||
binding.searchview
|
||||
.getEditText()
|
||||
.setOnEditorActionListener(
|
||||
(v, actionId, event) -> {
|
||||
binding.toolbar.setText(binding.searchview.getText());
|
||||
binding.searchview.hide();
|
||||
start(binding.searchview.getText().toString());
|
||||
return false;
|
||||
});
|
||||
binding.toolbar.setOnMenuItemClickListener(item -> {
|
||||
//搜索
|
||||
start(binding.toolbar.getText().toString());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
binding.editview.clearFocus();
|
||||
listPopupWindow.setVisibility(View.GONE);
|
||||
gj.ycjp(binding.editview.editText);
|
||||
binding.searchview.hide();
|
||||
}
|
||||
|
||||
private void addSearchRecord(String name) {
|
||||
|
@ -204,13 +226,17 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
if (binding.searchFragment.getVisibility() == View.VISIBLE) {
|
||||
binding.searchFragment.setVisibility(View.GONE);
|
||||
return false;
|
||||
}
|
||||
if (itemId == android.R.id.home) {
|
||||
ActivityCompat.finishAfterTransition(this);
|
||||
return false;
|
||||
} else if (itemId == 0) {
|
||||
start(binding.editview.getText().toString());
|
||||
start(binding.toolbar.getText().toString());
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void start(String name) {
|
||||
|
@ -269,7 +295,7 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
String keyword = json_list.get(position);
|
||||
holder.recordTextView.setText(keyword);
|
||||
holder.recordTextView.setOnClickListener(v -> {
|
||||
binding.editview.setText(keyword);
|
||||
binding.toolbar.setText(keyword);
|
||||
start(keyword);
|
||||
});
|
||||
holder.recordTextView.setOnLongClickListener(view -> {
|
||||
|
@ -308,6 +334,10 @@ public class activity_search extends FragmentActivity<ActivitySearchBinding> {
|
|||
}
|
||||
|
||||
private void end() {
|
||||
if (binding.searchview.isShowing()) {
|
||||
binding.searchview.hide();
|
||||
return;
|
||||
}
|
||||
if (binding.searchRecycler.getVisibility() == View.VISIBLE) {
|
||||
binding.searchRecycler.setVisibility(View.GONE);
|
||||
return;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package com.muqingbfq.api;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.mpatric.mp3agic.ID3v2;
|
||||
import com.mpatric.mp3agic.Mp3File;
|
||||
import com.muqingbfq.MP3;
|
||||
import com.muqingbfq.fragment.Media;
|
||||
import com.muqingbfq.login.user_logs;
|
||||
import com.muqingbfq.home;
|
||||
import com.muqingbfq.main;
|
||||
import com.muqingbfq.mq.gj;
|
||||
import com.muqingbfq.mq.wj;
|
||||
|
@ -55,9 +53,9 @@ public class url extends Thread {
|
|||
if (json.getInt("code") == -460) {
|
||||
String message = json.getString("message");
|
||||
main.handler.post(() -> {
|
||||
gj.ts(main.application, message);
|
||||
main.application.startActivity(new Intent(main.application
|
||||
, user_logs.class));
|
||||
gj.ts(home.activity, message);
|
||||
home.activity.startActivity(new android.content.Intent(home.activity
|
||||
, com.muqingbfq.login.user_logs.class));
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.muqingbfq;
|
|||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -10,7 +11,10 @@ import android.content.res.ColorStateList;
|
|||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.GestureDetector;
|
||||
|
@ -18,13 +22,12 @@ import android.view.LayoutInflater;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
import androidx.palette.graphics.Palette;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
@ -33,7 +36,6 @@ import com.bumptech.glide.load.engine.GlideException;
|
|||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.google.android.material.slider.Slider;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.mpatric.mp3agic.ID3v2;
|
||||
|
@ -56,6 +58,23 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
public MP3 mp3;
|
||||
public boolean isplay = true;
|
||||
GestureDetector gestureDetector;
|
||||
int seekbarH = 0;
|
||||
|
||||
private void lrc(View v) {
|
||||
// 隐藏view2并显示view1的动画效果
|
||||
v.animate()
|
||||
.alpha(0.0f)
|
||||
.setDuration(500)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
v.setVisibility(View.GONE);
|
||||
binding.cardview.setVisibility(View.VISIBLE);
|
||||
binding.cardview.setAlpha(0.0f);
|
||||
binding.cardview.animate().alpha(1.0f).setDuration(500).setListener(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private void setLrc() {
|
||||
|
@ -66,48 +85,66 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
if (!gj.isTablet(this)) {
|
||||
layoutParams.height = (int) (main.k / 1.3f);
|
||||
layoutParams.width = (int) (main.k / 1.3f);
|
||||
binding.fragmentBfq.setOnTouchListener((v, event) -> bfq.super.onTouchEvent(event));
|
||||
binding.lrcView.setOnClickListener(this::lrc);
|
||||
|
||||
binding.lrcView.setOnTapListener((view, x, y) -> {
|
||||
|
||||
// 隐藏view2并显示view1的动画效果
|
||||
view.animate()
|
||||
.alpha(0.0f)
|
||||
.setDuration(500)
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
view.setVisibility(View.GONE);
|
||||
binding.cardview.setVisibility(View.VISIBLE);
|
||||
binding.cardview.setAlpha(0.0f);
|
||||
binding.cardview.animate().alpha(1.0f).setDuration(500).setListener(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
binding.lrcView.setOnSingerClickListener(() -> lrc(binding.lrcView));
|
||||
// binding.lrcView.setTextGravity(GRAVITY_LEFT)
|
||||
binding.lrcView.setNormalTextSize(80f);
|
||||
binding.lrcView.setCurrentTextSize(100f);
|
||||
binding.lrcView.setTranslateTextScaleValue(0.8f);
|
||||
binding.lrcView.setHorizontalOffset(-50f);
|
||||
binding.lrcView.setHorizontalOffsetPercent(0.5f);
|
||||
binding.lrcView.setItemOffsetPercent(0.5f);
|
||||
binding.lrcView.setIsDrawTranslation(true);
|
||||
binding.lrcView.setIsEnableBlurEffect(true);
|
||||
} else {
|
||||
layoutParams.height = (int) (main.g / 2.0f);
|
||||
layoutParams.width = (int) (main.g / 2.0f);
|
||||
}
|
||||
binding.cardview.setLayoutParams(layoutParams);
|
||||
binding.lrcView.
|
||||
setDraggable(true, (a, time) -> {
|
||||
bfqkz.mt.seekTo((int) time);
|
||||
return false;
|
||||
});
|
||||
binding.tdt.addOnChangeListener((slider, value, fromUser) ->
|
||||
setTime_b(bfq_an.getTime((long) value)));
|
||||
binding.tdt.addOnSliderTouchListener(new Slider.OnSliderTouchListener() {
|
||||
|
||||
binding.lrcView.setDraggable(true, time -> {
|
||||
bfqkz.mt.seekTo((int) time);
|
||||
return false;
|
||||
});
|
||||
binding.tdt.setThumb(null);
|
||||
binding.tdt.post(() -> seekbarH = binding.tdt.getHeight());
|
||||
binding.tdt.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onStartTrackingTouch(@NonNull Slider slider) {
|
||||
// 拖动条移动中
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
// 当进度发生变化时执行操作
|
||||
setTime_b(bfq_an.getTime(progress));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
// 当开始拖动滑块时执行操作
|
||||
// 创建 ValueAnimator 对象,实现进度条高度的平滑过渡
|
||||
ValueAnimator animator = ValueAnimator.ofInt(seekbarH,
|
||||
seekbarH + 30);
|
||||
animator.addUpdateListener(animation -> {
|
||||
seekBar.getLayoutParams().height = (int) animation.getAnimatedValue();
|
||||
seekBar.requestLayout();
|
||||
});
|
||||
animator.setDuration(200); // 设置动画持续时间为 200 毫秒
|
||||
animator.start(); // 开始执行动画
|
||||
isplay = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(@NonNull Slider slider) {
|
||||
// 播放音乐到指定位置
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
// 当停止拖动滑块时执行操作
|
||||
isplay = true;
|
||||
bfqkz.mt.seekTo((int) slider.getValue());
|
||||
// 创建 ValueAnimator 对象,实现恢复进度条高度的平滑过渡
|
||||
ValueAnimator animator = ValueAnimator.ofInt(seekbarH + 30,
|
||||
seekbarH);
|
||||
animator.addUpdateListener(animation -> {
|
||||
seekBar.getLayoutParams().height = (int) animation.getAnimatedValue();
|
||||
seekBar.requestLayout();
|
||||
});
|
||||
animator.setDuration(200); // 设置动画持续时间为 200 毫秒
|
||||
animator.start(); // 开始执行动画
|
||||
bfqkz.mt.seekTo(seekBar.getProgress());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -120,17 +157,39 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
ObjectAnimator rotateAnimation;
|
||||
|
||||
private void Animation() {
|
||||
if (bfqkz.mt.isPlaying()) {
|
||||
if (rotateAnimation.isPaused()) {
|
||||
rotateAnimation.resume();
|
||||
} else {
|
||||
rotateAnimation.start();
|
||||
}
|
||||
} else {
|
||||
rotateAnimation.pause();
|
||||
}
|
||||
}
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
protected void UI(@Nullable Bundle savedInstanceState) {
|
||||
gestureDetector = new GestureDetector(this, this);
|
||||
setLrc();
|
||||
rotateAnimation = ObjectAnimator.ofFloat(binding.cardview
|
||||
, "rotation", 0f, 360f);
|
||||
rotateAnimation.setDuration(30000); // 设置动画持续时间,单位为毫秒
|
||||
rotateAnimation.setRepeatCount(ObjectAnimator.INFINITE); // 设置重复次数为无限
|
||||
rotateAnimation.setInterpolator(new LinearInterpolator()); // 设置插值器,这里使用线性插值器
|
||||
rotateAnimation.start();
|
||||
binding.kg.setOnClickListener(v -> {
|
||||
if (bfqkz.mt.isPlaying()) {
|
||||
bfqkz.mt.pause();
|
||||
setbf(false);
|
||||
} else {
|
||||
bfqkz.mt.start();
|
||||
setbf(true);
|
||||
}
|
||||
Animation();
|
||||
});
|
||||
binding.xyq.setOnClickListener(v -> bfq_an.xyq());
|
||||
binding.syq.setOnClickListener(v -> bfq_an.syq());
|
||||
|
@ -178,6 +237,21 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
Intent intent = getIntent();
|
||||
mp3 = (MP3) intent.getSerializableExtra("MP3");
|
||||
new thread().start();
|
||||
binding.fragmentBfq.setOnTouchListener((v, event) -> {
|
||||
gestureDetector.onTouchEvent(event);
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (binding.getRoot().getRootView().getTranslationY() > (main.g / 2.0f)) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(binding.getRoot().getRootView()
|
||||
, "y", binding.getRoot().getRootView().getTranslationY(), 0);
|
||||
animator.setDuration(500);
|
||||
animator.start();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private class toolbar implements View.OnClickListener {
|
||||
|
@ -211,28 +285,12 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
if (mp3 != null) {
|
||||
sx();
|
||||
}
|
||||
if (bfqkz.mt != null && bfqkz.mt.isPlaying()) {
|
||||
binding.kg.setImageResource(R.drawable.bf);
|
||||
}
|
||||
setbf(bfqkz.mt.isPlaying());
|
||||
Animation();
|
||||
});
|
||||
main.handler.post(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
gestureDetector.onTouchEvent(event);
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
if (binding.getRoot().getRootView().getTranslationY() > (main.g / 2.0f)) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
ObjectAnimator animator = ObjectAnimator.ofFloat(binding.getRoot().getRootView()
|
||||
, "y", binding.getRoot().getRootView().getTranslationY(), 0);
|
||||
animator.setDuration(500);
|
||||
animator.start();
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void sx() {
|
||||
|
@ -269,12 +327,12 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
}
|
||||
|
||||
public void setlike(boolean bool) {
|
||||
int color = R.color.text;
|
||||
if (bool) {
|
||||
color = android.R.color.holo_red_dark;
|
||||
binding.like.setImageTintList(ContextCompat.
|
||||
getColorStateList(binding.getRoot().getContext(), android.R.color.holo_red_dark));
|
||||
} else {
|
||||
binding.like.setImageTintList(ColorStateList.valueOf(ColorTint));
|
||||
}
|
||||
binding.like.setImageTintList(ContextCompat.
|
||||
getColorStateList(binding.getRoot().getContext(), color));
|
||||
islike = bool;
|
||||
}
|
||||
|
||||
|
@ -299,6 +357,7 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
setImageBitmap();
|
||||
}
|
||||
if (bfqkz.mt.isPlaying() != isPlaying) {
|
||||
|
||||
setbf(bfqkz.mt.isPlaying());
|
||||
}
|
||||
if (bfqkz.like_bool != islike) {
|
||||
|
@ -307,7 +366,7 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
if (!Objects.equals(bfqkz.lrc, lrc)) {
|
||||
lrc = bfqkz.lrc;
|
||||
String[] strings = Media.loadLyric();
|
||||
binding.lrcView.loadLrc(strings[0], strings[1]);
|
||||
binding.lrcView.loadLyric(strings[0], strings[1]);
|
||||
}
|
||||
main.handler.postDelayed(this, 1000); // 每秒更新一次进度
|
||||
}
|
||||
|
@ -362,7 +421,6 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
@NonNull DataSource dataSource,
|
||||
boolean isFirstResource) {
|
||||
color(resource);
|
||||
|
||||
return false;
|
||||
}
|
||||
}).into(binding.cardview.imageView);
|
||||
|
@ -373,23 +431,47 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
Palette.from(bitmap)
|
||||
.maximumColorCount(10)
|
||||
.generate(palette -> {
|
||||
// 获取图片中有活力的亮色
|
||||
int dominantSwatch = palette.getLightVibrantColor(Color.WHITE);
|
||||
// 获取图片中柔和的亮色
|
||||
int lightMutedColor = palette.getLightMutedColor(Color.GRAY);
|
||||
GradientDrawable gradientDrawable = new GradientDrawable(
|
||||
GradientDrawable.Orientation.BOTTOM_TOP, // 渐变方向:从上到下
|
||||
new int[]{Color.BLACK, lightMutedColor} // 渐变颜色数组
|
||||
new int[]{lightMutedColor, dominantSwatch} // 渐变颜色数组
|
||||
);
|
||||
// 设置渐变背景的形状为矩形
|
||||
int vibrantColor = palette.getVibrantColor(Color.BLACK);
|
||||
setTint(vibrantColor);
|
||||
gradientDrawable.setShape(GradientDrawable.RECTANGLE);
|
||||
// trackColorInactive
|
||||
// 创建颜色列表
|
||||
ColorStateList trackInactiveTintList = ColorStateList
|
||||
.valueOf(ColorUtils.blendARGB(lightMutedColor
|
||||
, Color.WHITE, 0.5f));
|
||||
binding.tdt.setTrackInactiveTintList(trackInactiveTintList);
|
||||
binding.getRoot().setBackground(gradientDrawable);
|
||||
});
|
||||
}
|
||||
|
||||
private int ColorTint = Color.WHITE;
|
||||
private void setTint(int color) {
|
||||
this.ColorTint = color;
|
||||
ColorStateList colorStateList = ColorStateList.valueOf(color);
|
||||
binding.kg.setImageTintList(colorStateList);
|
||||
binding.syq.setImageTintList(colorStateList);
|
||||
binding.xyq.setImageTintList(colorStateList);
|
||||
binding.bfqListMp3.setImageTintList(colorStateList);
|
||||
binding.control.setImageTintList(colorStateList);
|
||||
binding.like.setImageTintList(colorStateList);
|
||||
binding.download.setImageTintList(colorStateList);
|
||||
binding.image2.setImageTintList(colorStateList);
|
||||
binding.name.setTextColor(color);
|
||||
binding.zz.setTextColor(color);
|
||||
binding.timeA.setTextColor(color);
|
||||
binding.timeB.setTextColor(color);
|
||||
|
||||
Drawable progressDrawable = binding.tdt.getProgressDrawable();
|
||||
LayerDrawable layerDrawable = (LayerDrawable) progressDrawable;
|
||||
Drawable progress = layerDrawable.findDrawableByLayerId(android.R.id.progress);
|
||||
progress.setColorFilter(color, PorterDuff.Mode.SRC_IN);
|
||||
// 设置进度条背景的颜色
|
||||
/* Drawable background = layerDrawable.findDrawableByLayerId(android.R.id.background);
|
||||
background.setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_IN);*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
super.finish();
|
||||
|
@ -405,19 +487,15 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
}
|
||||
|
||||
public void setMax(int max) {
|
||||
binding.tdt.setValueTo(Math.max(0, max));
|
||||
binding.tdt.setMax(Math.max(0, max));
|
||||
}
|
||||
|
||||
public void Progress(int progress) {
|
||||
if (binding.tdt.getValueTo() < progress) {
|
||||
return;
|
||||
// 处理超出范围的情况
|
||||
}
|
||||
binding.tdt.setValue(progress);
|
||||
binding.lrcView.updateTime(progress);
|
||||
int min = Math.min(progress, binding.tdt.getMax());
|
||||
binding.tdt.setProgress(min);
|
||||
binding.lrcView.updateTime(min, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onDown(@NonNull MotionEvent e) {
|
||||
return false;
|
||||
|
@ -471,9 +549,9 @@ public class bfq extends AppCompatActivity<ActivityBfqBinding>
|
|||
@Override
|
||||
public boolean onScroll(@NonNull MotionEvent e1, @NonNull MotionEvent e2,
|
||||
float distanceX, float distanceY) {
|
||||
if (binding.lrcView.getVisibility() == View.VISIBLE) {
|
||||
/* if (binding.lrcView.getVisibility() == View.VISIBLE) {
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
float y = binding.getRoot().getRootView().getTranslationY() - distanceY;
|
||||
y = Math.max(0, y);
|
||||
//移动的距离
|
||||
|
|
|
@ -25,7 +25,8 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class bfqkz extends MediaBrowserServiceCompat {
|
||||
public static MediaPlayer mt = new MediaPlayer();
|
||||
public final static MediaPlayer mt = new MediaPlayer();
|
||||
|
||||
public static List<MP3> list = new ArrayList<>();
|
||||
//保存原始list顺序
|
||||
public static List<MP3> list_baocun = new ArrayList<>();
|
||||
|
|
|
@ -28,12 +28,11 @@ import java.util.List;
|
|||
public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
|
||||
List<String[]> list = new ArrayList<>();
|
||||
List<String> list_box = new ArrayList<>();
|
||||
ActivityCleanBinding binding;
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityCleanBinding.inflate(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setContentView();
|
||||
setToolbar();
|
||||
UI();
|
||||
}
|
||||
|
||||
|
@ -117,7 +116,7 @@ public class fragment_clean extends FragmentActivity<ActivityCleanBinding> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
} else if (item == menu_deleat) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.muqingbfq.fragment;
|
||||
|
||||
import com.dirror.lyricviewx.LyricViewX;
|
||||
import com.muqingbfq.mq.gj;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
@ -17,12 +18,10 @@ public class Media {
|
|||
a = jsonObject.getJSONObject("lrc").getString("lyric");
|
||||
b = jsonObject.getJSONObject("tlyric").getString("lyric");
|
||||
} catch (Exception e) {
|
||||
gj.sc("Media loadLyric "+e);
|
||||
gj.sc("Media loadLyric " + e);
|
||||
}
|
||||
me.wcy.lrcview.LrcView.Lrc(a, b);
|
||||
LyricViewX.lrc(a, b);
|
||||
return new String[]{a, b};
|
||||
// bfq.lrcView.getLrc();
|
||||
// bfq.lrcView.loadLrc(a, b);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public class gd extends com.muqingbfq.mq.FragmentActivity<ActivityGdBinding> {
|
|||
|
||||
public static void start(Activity context, String[] str, View view) {
|
||||
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
||||
view, "view");
|
||||
view, "text");
|
||||
Intent intent = new Intent(context, gd.class);
|
||||
intent.putExtra("id", str[0]);
|
||||
intent.putExtra("name", str[1]);
|
||||
|
|
|
@ -10,7 +10,6 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.drawerlayout.widget.DrawerLayout;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
@ -41,20 +40,24 @@ public class gd_adapter extends Fragment {
|
|||
List<XM> list = new ArrayList<>();
|
||||
List<MP3> listmp3 = new ArrayList<>();
|
||||
FragmentGdBinding binding;
|
||||
|
||||
public void toolbar() {
|
||||
// binding.bar.setupWithDrawer
|
||||
((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
|
||||
androidx.drawerlayout.widget.DrawerLayout drawerLayout = requireActivity().findViewById(R.id.chct);
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
||||
requireActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
|
||||
drawerLayout.addDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
binding = FragmentGdBinding.inflate(getLayoutInflater(), container, false);
|
||||
//初始化工具栏
|
||||
|
||||
((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
|
||||
DrawerLayout drawerLayout = requireActivity().findViewById(R.id.chct);
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
||||
getActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
|
||||
drawerLayout.addDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
|
||||
toolbar();
|
||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
|
||||
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
|
||||
binding.recyclerview1.setHasFixedSize(true);
|
||||
|
@ -122,7 +125,7 @@ public class gd_adapter extends Fragment {
|
|||
});
|
||||
mp3list();
|
||||
|
||||
binding.editView.setOnClickListener(v -> activity_search.start(getActivity(),v));
|
||||
binding.toolbar.setOnClickListener(v -> activity_search.start(getActivity(), v));
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public class mp3 extends FragmentActivity<ActivityMp3Binding> {
|
|||
|
||||
public static void start(Activity context, String[] str, View view) {
|
||||
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(context,
|
||||
view, "view");
|
||||
view, "text");
|
||||
Intent intent = new Intent(context, mp3.class);
|
||||
intent.putExtra("id", str[0]);
|
||||
intent.putExtra("name", str[1]);
|
||||
|
|
|
@ -71,18 +71,22 @@ public class wode extends Fragment {
|
|||
@SuppressLint("StaticFieldLeak")
|
||||
public static baseadapter adaper;
|
||||
|
||||
public void toolbar() {
|
||||
((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
|
||||
DrawerLayout drawerLayout = requireActivity().findViewById(R.id.chct);
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
||||
requireActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
|
||||
drawerLayout.addDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
binding = FragmentWdBinding.inflate(inflater, container, false);
|
||||
//初始化工具栏
|
||||
((AppCompatActivity) requireActivity()).setSupportActionBar(binding.toolbar);
|
||||
DrawerLayout drawerLayout = getActivity().findViewById(R.id.chct);
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
||||
getActivity(), drawerLayout, binding.toolbar, R.string.app_name, R.string.app_name);
|
||||
drawerLayout.addDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
toolbar();
|
||||
name = binding.text1;
|
||||
binding.appbar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
|
||||
boolean isCollapsed = false; // 标记是否处于折叠状态
|
||||
|
@ -146,7 +150,7 @@ public class wode extends Fragment {
|
|||
getContext().startActivity(a);
|
||||
break;
|
||||
case "排行榜":
|
||||
gd.start(getActivity(), new String[]{data, s}, holder.itemView);
|
||||
gd.start(getActivity(), new String[]{data, s}, holder.textView);
|
||||
break;
|
||||
case "API":
|
||||
EditViewDialog editViewDialog = new EditViewDialog(getContext(), "更换接口API")
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.muqingbfq;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
@ -14,6 +16,7 @@ import android.view.MenuItem;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import androidx.viewpager2.widget.ViewPager2;
|
||||
|
||||
|
@ -27,12 +30,17 @@ import java.util.List;
|
|||
|
||||
public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding> {
|
||||
public MediaBrowserCompat mBrowser;
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
public static Context activity;
|
||||
|
||||
@Override
|
||||
protected ActivityHomeBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
||||
return ActivityHomeBinding.inflate(layoutInflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
activity = this;
|
||||
setTheme(R.style.Theme_muqing);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(getViewBinding().getRoot());
|
||||
|
@ -72,31 +80,25 @@ public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding
|
|||
}
|
||||
|
||||
public static ComponentName componentName;
|
||||
|
||||
private class Adaper extends FragmentStateAdapter {
|
||||
List<Fragment> list = new ArrayList<>();
|
||||
public Adaper(@NonNull FragmentActivity fragmentActivity) {
|
||||
super(fragmentActivity);
|
||||
list.add(new gd_adapter());
|
||||
list.add(new wode());
|
||||
}
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
return list.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list.size();
|
||||
}
|
||||
}
|
||||
|
||||
List<Fragment> list = new ArrayList<>();
|
||||
public void UI() {
|
||||
Adaper adapter = new Adaper(this);
|
||||
binding.viewPager.setAdapter(adapter);
|
||||
list.clear();
|
||||
list.add(new gd_adapter());
|
||||
list.add(new wode());
|
||||
binding.viewPager.setAdapter(new FragmentStateAdapter(this) {
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
return list.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list.size();
|
||||
}
|
||||
});
|
||||
binding.viewPager.setSaveEnabled(false);
|
||||
// 将 ViewPager2 绑定到 TabLayout
|
||||
// 将 ViewPager2 绑定到 TabLayou
|
||||
binding.tablayout.setOnItemSelectedListener(item -> {
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.a) {
|
||||
|
@ -132,6 +134,7 @@ public class home extends com.muqingbfq.mq.AppCompatActivity<ActivityHomeBinding
|
|||
editor.putString("listData", jsonList);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
moveTaskToBack(true);
|
||||
|
|
|
@ -27,16 +27,13 @@ import java.util.List;
|
|||
|
||||
public class main extends Application {
|
||||
public static Application application;
|
||||
|
||||
public static Handler handler = new Handler(Looper.getMainLooper());
|
||||
public static String api = "http://139.196.224.229:3000";
|
||||
public static String http = "http://139.196.224.229/muqing";
|
||||
public static String api = "https://service-8xjb06vc-1319932248.gz.tencentapigw.com.cn/release";
|
||||
public static String http = "https://www.muqingkaifazhe.top/muqingbfq.php";
|
||||
public static int k, g;
|
||||
public static SharedPreferences sp;
|
||||
public static SharedPreferences.Editor edit;
|
||||
public int count = 0;
|
||||
public static long item = System.currentTimeMillis();
|
||||
@SuppressLint("HardwareIds")
|
||||
private int count = 0;
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
@ -80,7 +77,6 @@ public class main extends Application {
|
|||
if (wl.Cookie.equals("")) {
|
||||
new visitor();
|
||||
}
|
||||
|
||||
SharedPreferences theme = getSharedPreferences("theme", MODE_PRIVATE);
|
||||
@SuppressLint("CommitPrefEdits") SharedPreferences.Editor edit = theme.edit();
|
||||
int i = theme.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
||||
|
@ -89,7 +85,6 @@ public class main extends Application {
|
|||
edit.apply();
|
||||
}
|
||||
AppCompatDelegate.setDefaultNightMode(i);
|
||||
|
||||
String jsonList = this.getSharedPreferences("list", Context.MODE_PRIVATE)
|
||||
.getString("listData", null); // 获取保存的 JSON 字符串
|
||||
if (jsonList != null) {
|
||||
|
@ -116,12 +111,10 @@ public class main extends Application {
|
|||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||
@Override
|
||||
public void onActivityCreated(@NonNull Activity activity, Bundle savedInstanceState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(@NonNull Activity activity) {
|
||||
if (count == 0) { //后台切换到前台
|
||||
|
@ -131,21 +124,16 @@ public class main extends Application {
|
|||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(@NonNull Activity activity) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(@NonNull Activity activity) {
|
||||
count--;
|
||||
if (count == 0) { //后台切换到前台
|
||||
// gj.sc(">>>>>>>>>>>>>>>>>>>App切到后台");
|
||||
new Thread(){
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -154,7 +142,6 @@ public class main extends Application {
|
|||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// gj.sc(count);
|
||||
if (count != 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -173,7 +160,6 @@ public class main extends Application {
|
|||
@Override
|
||||
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(@NonNull Activity activity) {
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ public class BluetoothMusicController {
|
|||
this.context = context;
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
|
||||
|
||||
intentFilter.addAction("android.intent.action.HEADSET_PLUG");
|
||||
context.registerReceiver(new MyButtonClickReceiver(), intentFilter);
|
||||
registerHeadsetReceiver();
|
||||
|
|
|
@ -17,6 +17,8 @@ import android.widget.ImageView;
|
|||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.dirror.lyricviewx.LyricEntry;
|
||||
import com.dirror.lyricviewx.LyricViewX;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.muqingbfq.R;
|
||||
|
@ -27,10 +29,6 @@ import com.muqingbfq.main;
|
|||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import me.wcy.lrcview.LrcEntry;
|
||||
import me.wcy.lrcview.LrcView;
|
||||
|
||||
public class FloatingLyricsService extends Service implements View.OnClickListener, View.OnTouchListener {
|
||||
private WindowManager windowManager;
|
||||
private View layout;
|
||||
|
@ -39,26 +37,17 @@ public class FloatingLyricsService extends Service implements View.OnClickListen
|
|||
@Override
|
||||
public void run() {
|
||||
int index = 0;
|
||||
for (int i = 0; i < LrcView.mLrcEntryList.size(); i++) {
|
||||
LrcEntry lineLrc = LrcView.mLrcEntryList.get(i);
|
||||
for (int i = 0; i < LyricViewX.lyricEntryList.size(); i++) {
|
||||
LyricEntry lineLrc = LyricViewX.lyricEntryList.get(i);
|
||||
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
|
||||
index = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index < LrcView.mLrcEntryList.size()) {
|
||||
if (index < LyricViewX.lyricEntryList.size()) {
|
||||
String text;
|
||||
if (LrcView.mLrcEntryList.size() <= 3) {
|
||||
for (LrcEntry a : LrcView.mLrcEntryList) {
|
||||
if (a.time == 5940000 && a.text.equals("纯音乐,请欣赏")) {
|
||||
text = "纯音乐,请欣赏";
|
||||
binding.lrcView.setText(text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
LrcEntry currentLrc = LrcView.mLrcEntryList.get(index);
|
||||
LyricEntry currentLrc = LyricViewX.lyricEntryList.get(index);
|
||||
text = currentLrc.text;
|
||||
if (currentLrc.secondText != null) {
|
||||
text += "\n" + currentLrc.secondText;
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.jaeger.library.StatusBarUtil;
|
||||
|
@ -29,13 +30,19 @@ public abstract class FragmentActivity<ViewBindingType extends ViewBinding>
|
|||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
public void setToolbar() {
|
||||
setSupportActionBar(findViewById(R.id.toolbar));
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
View viewById = findViewById(R.id.toolbar);
|
||||
if (viewById != null) {
|
||||
setSupportActionBar((Toolbar) viewById);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContentView(int view) {
|
||||
super.setContentView(view);
|
||||
}
|
||||
public void setContentView() {
|
||||
binding = getViewBindingObject(getLayoutInflater());
|
||||
setContentView(binding.getRoot());
|
||||
setToolbar();
|
||||
}
|
||||
|
||||
|
@ -43,6 +50,5 @@ public abstract class FragmentActivity<ViewBindingType extends ViewBinding>
|
|||
public void setContentView(View view) {
|
||||
StatusBarUtil.setTransparent(this);
|
||||
super.setContentView(view);
|
||||
setToolbar();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ public class gj {
|
|||
if (a == null) {
|
||||
a = "null";
|
||||
}
|
||||
Log.d("云音乐", a.toString());
|
||||
Log.d("打印", a.toString());
|
||||
floating.addtext(a.toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.view.Menu;
|
|||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
|
@ -41,27 +42,26 @@ import okhttp3.Response;
|
|||
|
||||
public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
||||
WebView web;
|
||||
|
||||
@Override
|
||||
protected ActivityLlqBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
||||
return ActivityLlqBinding.inflate(layoutInflater);
|
||||
}
|
||||
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Override
|
||||
protected void UI(@Nullable Bundle savedInstanceState) {
|
||||
Intent intent = getIntent();
|
||||
setSupportActionBar(binding.toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
web = findViewById(R.id.webview);
|
||||
web = binding.webview;
|
||||
web.getSettings().setJavaScriptEnabled(true);
|
||||
web.getSettings().setDomStorageEnabled(true);
|
||||
// 禁用缓存
|
||||
web.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
|
||||
web.setWebViewClient(new WebViewClient() {
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
super.onPageFinished(view, url);
|
||||
String title = view.getTitle();
|
||||
setTitle(title);
|
||||
setSubtitle(url);
|
||||
setTitle(web.getTitle());
|
||||
// 在这里获取到了网页的标题
|
||||
}
|
||||
});
|
||||
|
@ -162,15 +162,9 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
|||
});
|
||||
loadUrl(intent.getStringExtra("url"));
|
||||
}
|
||||
|
||||
private void setSubtitle(String url) {
|
||||
binding.toolbar.setSubtitle(url);
|
||||
}
|
||||
|
||||
private void loadUrl(String url) {
|
||||
web.loadUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
@ -180,13 +174,11 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
|||
gj.ts(this, "权限已授予,请重新执行文件下载操作");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.llq, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (web.canGoBack()) {
|
||||
|
@ -195,8 +187,6 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
|||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
int itemId = item.getItemId();
|
||||
|
@ -213,4 +203,5 @@ public class llq extends AppCompatActivity<ActivityLlqBinding> {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,18 +17,20 @@ import androidx.activity.result.ActivityResultLauncher;
|
|||
import androidx.activity.result.contract.ActivityResultContracts;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.colorpicker.ColorPickerView;
|
||||
import com.colorpicker.builder.ColorPickerDialogBuilder;
|
||||
import com.dirror.lyricviewx.LyricEntry;
|
||||
import com.dirror.lyricviewx.LyricViewX;
|
||||
import com.google.android.material.materialswitch.MaterialSwitch;
|
||||
import com.google.android.material.slider.Slider;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.muqingbfq.databinding.ActivitySzBinding;
|
||||
import com.muqingbfq.databinding.ActivitySzSetlrcBinding;
|
||||
import com.muqingbfq.mq.AppCompatActivity;
|
||||
import com.muqingbfq.mq.FloatingLyricsService;
|
||||
import com.muqingbfq.mq.wj;
|
||||
|
||||
|
@ -36,48 +38,40 @@ import java.io.File;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.Locale;
|
||||
|
||||
import me.wcy.lrcview.LrcEntry;
|
||||
import me.wcy.lrcview.LrcView;
|
||||
|
||||
public class sz extends AppCompatActivity {
|
||||
public class sz extends AppCompatActivity<ActivitySzBinding> {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_sz);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
toolbar.setTitle(getString(R.string.sz));
|
||||
UI();
|
||||
kaifazhe();
|
||||
protected ActivitySzBinding getViewBindingObject(LayoutInflater layoutInflater) {
|
||||
return ActivitySzBinding.inflate(layoutInflater);
|
||||
}
|
||||
@Override
|
||||
protected void UI(Bundle bundle) {
|
||||
setSupportActionBar(binding.toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
setTitle(getString(R.string.sz));
|
||||
kaifazhe();
|
||||
|
||||
@SuppressLint("ApplySharedPref")
|
||||
private void UI() {
|
||||
MaterialSwitch a1 = findViewById(R.id.switch_a1);
|
||||
MaterialSwitch a2 = findViewById(R.id.switch_a2);
|
||||
SharedPreferences theme = getSharedPreferences("theme", MODE_PRIVATE);
|
||||
@SuppressLint("CommitPrefEdits") SharedPreferences.Editor edit = theme.edit();
|
||||
int i = theme.getInt("theme", AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
|
||||
if (i == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
|
||||
a1.setChecked(true);
|
||||
a2.setEnabled(false);
|
||||
binding.switchA1.setChecked(true);
|
||||
binding.switchA2.setEnabled(false);
|
||||
} else {
|
||||
a1.setChecked(false);
|
||||
a2.setEnabled(true);
|
||||
a2.setChecked(i == AppCompatDelegate.MODE_NIGHT_YES);
|
||||
binding.switchA1.setChecked(false);
|
||||
binding.switchA2.setEnabled(true);
|
||||
binding.switchA2.setChecked(i == AppCompatDelegate.MODE_NIGHT_YES);
|
||||
}
|
||||
a1.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||
binding.switchA1.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||
if (b) {
|
||||
// 跟随系统设置切换颜色模式
|
||||
int ms = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM;
|
||||
AppCompatDelegate.setDefaultNightMode(ms);
|
||||
edit.putInt("theme", ms);
|
||||
edit.commit();
|
||||
edit.apply();
|
||||
}
|
||||
a2.setEnabled(!b);
|
||||
binding.switchA2.setEnabled(!b);
|
||||
});
|
||||
a2.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||
binding.switchA2.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||
if (compoundButton.isEnabled()) {
|
||||
int ms;
|
||||
if (b) {
|
||||
|
@ -91,8 +85,6 @@ public class sz extends AppCompatActivity {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
|
@ -100,7 +92,6 @@ public class sz extends AppCompatActivity {
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
ActivityResultLauncher<Intent> intent = registerForActivityResult(
|
||||
new ActivityResultContracts.StartActivityForResult(),
|
||||
result -> {
|
||||
|
@ -108,9 +99,9 @@ public class sz extends AppCompatActivity {
|
|||
com.muqingbfq.mq.floating.start(sz.this);
|
||||
}
|
||||
});
|
||||
|
||||
public void kaifazhe() {
|
||||
MaterialSwitch materialSwitch = findViewById(R.id.switch_kfz);
|
||||
/* MaterialSwitch materialSwitch = findViewById(R.id
|
||||
.switch_kfz);
|
||||
materialSwitch.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||
if (b) {
|
||||
if (!Settings.canDrawOverlays(this)) {
|
||||
|
@ -123,10 +114,8 @@ public class sz extends AppCompatActivity {
|
|||
} else {
|
||||
com.muqingbfq.mq.floating.end(sz.this);
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
|
||||
public static class setlrc extends Fragment implements Slider.OnSliderTouchListener,
|
||||
Slider.OnChangeListener {
|
||||
ActivityResultLauncher<Intent> LyricsService =
|
||||
|
@ -142,26 +131,17 @@ public class sz extends AppCompatActivity {
|
|||
public void run() {
|
||||
if (bfqkz.mt.isPlaying()) {
|
||||
int index = 0;
|
||||
for (int i = 0; i < LrcView.mLrcEntryList.size(); i++) {
|
||||
LrcEntry lineLrc = LrcView.mLrcEntryList.get(i);
|
||||
for (int i = 0; i < LyricViewX.lyricEntryList.size(); i++) {
|
||||
LyricEntry lineLrc = LyricViewX.lyricEntryList.get(i);
|
||||
if (lineLrc.time <= bfqkz.mt.getCurrentPosition()) {
|
||||
index = i;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index < LrcView.mLrcEntryList.size()) {
|
||||
if (index < LyricViewX.lyricEntryList.size()) {
|
||||
String text;
|
||||
if (LrcView.mLrcEntryList.size() <= 3) {
|
||||
for (LrcEntry a : LrcView.mLrcEntryList) {
|
||||
if (a.time == 5940000 && a.text.equals("纯音乐,请欣赏")) {
|
||||
text = "纯音乐,请欣赏";
|
||||
binding.lrctext.setText(text);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
LrcEntry currentLrc = LrcView.mLrcEntryList.get(index);
|
||||
LyricEntry currentLrc = LyricViewX.lyricEntryList.get(index);
|
||||
text = currentLrc.text;
|
||||
if (currentLrc.secondText != null) {
|
||||
text += "\n" + currentLrc.secondText;
|
||||
|
@ -207,11 +187,11 @@ public class sz extends AppCompatActivity {
|
|||
binding.lrctext.setTextColor(selectedColor);
|
||||
FloatingLyricsService.baocun(setup);
|
||||
})
|
||||
.setNegativeButton("取消",null)
|
||||
.setNegativeButton("取消", null)
|
||||
.build()
|
||||
.show());
|
||||
binding.textSlide1.setText(String.valueOf(setup.size));
|
||||
binding.textSlide2.setText(String.format(Locale.US,"%.2f",setup.Alpha));
|
||||
binding.textSlide2.setText(String.format(Locale.US, "%.2f", setup.Alpha));
|
||||
if (setup.i != 0) {
|
||||
binding.switchA1.setChecked(true);
|
||||
}
|
||||
|
@ -282,10 +262,10 @@ public class sz extends AppCompatActivity {
|
|||
setup.size,
|
||||
getResources().getDisplayMetrics()));
|
||||
binding.textSlide1.setText(String.valueOf(setup.size));
|
||||
}else if (slider == binding.slide2) {
|
||||
} else if (slider == binding.slide2) {
|
||||
setup.Alpha = value;
|
||||
binding.lrctext.setAlpha(value);
|
||||
binding.textSlide2.setText(String.format(Locale.US,"%.2f", value));
|
||||
binding.textSlide2.setText(String.format(Locale.US, "%.2f", value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import android.text.NoCopySpan;
|
|||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
|
@ -19,6 +21,7 @@ import android.widget.TextView;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
import com.muqingbfq.R;
|
||||
|
||||
public class Edit extends LinearLayout {
|
||||
|
@ -44,6 +47,8 @@ public class Edit extends LinearLayout {
|
|||
public EditText editText;
|
||||
|
||||
private void initView() {
|
||||
TextInputLayout layout = new TextInputLayout(getContext());
|
||||
// layout.clearIconDrawable
|
||||
setGravity(Gravity.CENTER_VERTICAL);
|
||||
setBackgroundResource(R.drawable.ui_editview);
|
||||
setPadding(30, 0, 30, 0);
|
||||
|
@ -52,28 +57,29 @@ public class Edit extends LinearLayout {
|
|||
editText.setHint("搜索");
|
||||
editText.setSingleLine(true);
|
||||
editText.setBackground(null);
|
||||
editText.setTransitionName("edit");
|
||||
Drawable startIcon = ContextCompat.getDrawable(getContext(), R.drawable.sousuo);
|
||||
startIcon.setTint(ContextCompat.getColor(getContext(),
|
||||
R.color.text_tm));
|
||||
Drawable endIcon = ContextCompat.getDrawable(getContext(), R.drawable.chahao);
|
||||
editText.setCompoundDrawablesRelativeWithIntrinsicBounds(startIcon, null, endIcon, null);
|
||||
editText.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
|
||||
// editText.passwordToggleEnabled
|
||||
addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence var1, int var2, int var3, int var4) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence var1, int var2, int var3, int var4) {
|
||||
iskong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable var1) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
ImageView imageView = new ImageView(getContext());
|
||||
imageView.setImageResource(R.drawable.sousuo);
|
||||
imageView.setImageTintList(ContextCompat.getColorStateList(getContext(),
|
||||
R.color.text_tm));
|
||||
addView(imageView, (int) TypedValue.applyDimension(TypedValue.
|
||||
COMPLEX_UNIT_DIP, 26, getResources().getDisplayMetrics())
|
||||
, (int) TypedValue.applyDimension(TypedValue.
|
||||
|
@ -106,23 +112,15 @@ public class Edit extends LinearLayout {
|
|||
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.Edit);
|
||||
boolean isEnabled = a.getBoolean(R.styleable.Edit_Enabled, true);
|
||||
if (!isEnabled) {
|
||||
removeView(editText);
|
||||
removeView(imageView);
|
||||
removeView(chahao);
|
||||
TextView textView = new TextView(getContext());
|
||||
textView.setTextColor(editText.getHintTextColors());
|
||||
textView.setText("搜索");
|
||||
|
||||
// 将 px 值转换为 sp
|
||||
float v = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_PX,
|
||||
editText.getTextSize(),
|
||||
getResources().getDisplayMetrics()
|
||||
) / getResources().getDisplayMetrics().scaledDensity;
|
||||
textView.setTextSize(v);
|
||||
setGravity(Gravity.CENTER);
|
||||
addView(textView);
|
||||
textView.setPadding(26, 26, 26, 26);
|
||||
// editText.setGravity(Gravity.CENTER);
|
||||
editText.setFocusable(false);
|
||||
editText.setFocusableInTouchMode(false);
|
||||
// editText.setEnabled(false);
|
||||
editText.setClickable(false);
|
||||
|
||||
}
|
||||
a.recycle();
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:width="128dp"
|
||||
android:height="128dp">
|
||||
android:width="26dp"
|
||||
android:height="26dp">
|
||||
<path
|
||||
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" />
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:width="128dp"
|
||||
android:height="128dp">
|
||||
android:width="26dp"
|
||||
android:height="26dp">
|
||||
<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: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"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="36dp"
|
||||
android:width="36dp"
|
||||
android:height="26dp"
|
||||
android:width="26dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/background" />
|
||||
<item android:top="88.0dip">
|
||||
<item>
|
||||
<bitmap
|
||||
android:gravity="center|top"
|
||||
android:src="@mipmap/logo" />
|
||||
android:src="@mipmap/icon"
|
||||
android:scaleType="center"/>
|
||||
</item>
|
||||
</layer-list>
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<me.wcy.lrcview.LrcView
|
||||
<com.dirror.lyricviewx.LyricViewX
|
||||
android:id="@+id/lrcView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -199,16 +199,11 @@
|
|||
android:text="@string/_00_00"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
<SeekBar
|
||||
android:id="@+id/tdt"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
app:labelBehavior="gone"
|
||||
app:thumbColor="#E6E6E6"
|
||||
app:trackColorActive="#CCCCCC"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
android:layout_weight="1" />
|
||||
<TextView
|
||||
android:id="@+id/time_b"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -8,41 +8,6 @@
|
|||
android:fitsSystemWindows="true"
|
||||
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
|
||||
android:id="@+id/fragment_bfq"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -50,100 +15,125 @@
|
|||
android:layout_weight="1"
|
||||
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
|
||||
android:id="@+id/cardview"
|
||||
android:layout_width="256dp"
|
||||
android:layout_height="256dp"
|
||||
app:cardCornerRadius="16dp"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:cardBackgroundColor="@color/tm"
|
||||
app:cardCornerRadius="180dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="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:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
app:lrcCurrentTextColor="#FFFFFF"
|
||||
app:lrcNormalTextColor="#FFFDFD"
|
||||
app:lrcTimelineTextColor="#FFFFFF"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:lrcCurrentTextColor="#EEEEEE"
|
||||
app:lrcNormalTextColor="#CCCCCC"
|
||||
app:lrcTimelineTextColor="#EEEEEE"
|
||||
app:lrcNormalTextSize="16sp"
|
||||
app:lrcTextSize="20sp" />
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toTopOf="@id/tdt"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:tint="#CCCCCC">
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
<com.muqingbfq.view.Text
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
android:singleLine="true"
|
||||
android:text="@string/name"
|
||||
android:textColor="@color/tint_image"
|
||||
android:textSize="26sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<com.muqingbfq.view.Text
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/name"
|
||||
android:textColor="#CCCCCC"
|
||||
android:textStyle="bold"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<com.muqingbfq.view.Text
|
||||
android:id="@+id/zz"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/zz"
|
||||
android:textColor="#CCCCCC"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/like"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/like"
|
||||
app:tint="#CCCCCC"
|
||||
tools:ignore="ContentDescription" />
|
||||
<com.muqingbfq.view.Text
|
||||
android:id="@+id/zz"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:singleLine="true"
|
||||
android:text="@string/zz"
|
||||
android:textColor="@color/tint_image"
|
||||
android:textSize="20sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/tdt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="3dp"
|
||||
android:background="@null"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingEnd="10dp"
|
||||
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
|
||||
android:id="@+id/linearLayout3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginBottom="26dp"
|
||||
android:orientation="horizontal"
|
||||
app:alignItems="center"
|
||||
app:flexDirection="row"
|
||||
app:justifyContent="space_around"
|
||||
app:layout_constraintBottom_toTopOf="@+id/download"
|
||||
tools:ignore="MissingConstraints"
|
||||
tools:layout_editor_absoluteX="6dp">
|
||||
app:layout_constraintBottom_toTopOf="@+id/layout2"
|
||||
tools:ignore="MissingConstraints">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/control"
|
||||
|
@ -151,7 +141,7 @@
|
|||
android:layout_height="36dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/mt_sx"
|
||||
app:tint="#CCCCCC"
|
||||
app:tint="@color/tint_image"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
|
@ -160,16 +150,17 @@
|
|||
android:layout_height="36dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/syq"
|
||||
app:tint="#CCCCCC"
|
||||
app:tint="@color/tint_image"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/kg"
|
||||
android:layout_width="46dp"
|
||||
android:layout_height="46dp"
|
||||
android:layout_width="66dp"
|
||||
android:layout_height="66dp"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/zt"
|
||||
app:tint="#CCCCCC"
|
||||
app:tint="@color/tint_image"
|
||||
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
|
@ -178,7 +169,7 @@
|
|||
android:layout_height="36dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/xyq"
|
||||
app:tint="#CCCCCC"
|
||||
app:tint="@color/tint_image"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<ImageView
|
||||
|
@ -187,49 +178,49 @@
|
|||
android:layout_height="36dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/mplist"
|
||||
app:tint="#CCCCCC"
|
||||
app:tint="@color/tint_image"
|
||||
tools:ignore="ContentDescription" />
|
||||
</com.google.android.flexbox.FlexboxLayout>
|
||||
|
||||
<com.google.android.material.slider.Slider
|
||||
android:id="@+id/tdt"
|
||||
<com.google.android.flexbox.FlexboxLayout
|
||||
android:id="@+id/layout2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:labelBehavior="gone"
|
||||
app:layout_constraintBottom_toTopOf="@id/time_a"
|
||||
app:thumbColor="#E6E6E6"
|
||||
app:trackColorActive="#CCCCCC"
|
||||
tools:ignore="SpeakableTextPresentCheck" />
|
||||
|
||||
<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
|
||||
android:id="@+id/download"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/download"
|
||||
app:alignItems="center"
|
||||
app:flexDirection="row"
|
||||
app:justifyContent="space_around"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:tint="#CCCCCC"
|
||||
tools:ignore="ContentDescription" />
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/download"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/download"
|
||||
app:tint="@color/tint_image"
|
||||
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>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:textSize="26sp"
|
||||
android:transitionName="view"
|
||||
android:transitionName="text"
|
||||
android:textColor="@color/text"/>
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
|
|
|
@ -1,22 +1,31 @@
|
|||
<?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_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<ProgressBar
|
||||
android:id="@+id/webViewProgressBar"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="6dp"
|
||||
android:indeterminate="false"
|
||||
android:max="100" />
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/webViewProgressBar"
|
||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="6dp"
|
||||
android:indeterminate="false"
|
||||
android:max="100" />
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:transitionName="view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
@ -22,6 +21,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/text"
|
||||
android:transitionName="text"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<EditText
|
||||
|
|
|
@ -1,25 +1,40 @@
|
|||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
tools:context=".activity_search">
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
<com.google.android.material.search.SearchView
|
||||
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_height="wrap_content">
|
||||
<com.muqingbfq.view.Edit
|
||||
android:id="@+id/editview"
|
||||
<com.google.android.material.search.SearchBar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:transitionName="view"
|
||||
android:enabled="false"/>
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
app:defaultMarginsEnabled="true"
|
||||
app:hideNavigationIcon="false"
|
||||
app:navigationIcon="@drawable/end"
|
||||
android:transitionName="edit"
|
||||
android:hint="@string/search"/>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<RelativeLayout
|
||||
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">
|
||||
<LinearLayout
|
||||
android:id="@+id/xxbj1"
|
||||
|
@ -43,8 +58,9 @@
|
|||
android:id="@+id/deleat"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:layout_marginEnd="10dp"
|
||||
app:tint="@color/text"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/deleat"
|
||||
android:src="@drawable/delete" />
|
||||
</LinearLayout>
|
||||
|
@ -60,21 +76,15 @@
|
|||
android:name="com.muqingbfq.fragment.search"
|
||||
android:visibility="gone"
|
||||
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>
|
||||
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/bfq_db"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:backgroundTint="@color/bj"
|
||||
android:layout_gravity="bottom"
|
||||
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
|
||||
android:name="com.muqingbfq.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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
tools:context=".sz">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
|
@ -16,13 +16,13 @@
|
|||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="10dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -32,45 +32,32 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="主题模式"
|
||||
android:textSize="20sp" />
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:text="主题"/>
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/switch_a1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:text="根据系统" />
|
||||
android:textSize="20sp"
|
||||
android:text="跟随系统模式来选择" />
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/switch_a2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="26dp"
|
||||
android:textSize="20sp"
|
||||
android:text="深色模式" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<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_height="wrap_content"
|
||||
android:text="开发者模式" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.divider.MaterialDivider
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:text="歌词"/>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fragment_setlrc"
|
||||
|
|
|
@ -5,21 +5,16 @@
|
|||
android:layout_height="wrap_content"
|
||||
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
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardUseCompatPadding="true">
|
||||
app:cardUseCompatPadding="true"
|
||||
app:contentPadding="10dp">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="6dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lrctext"
|
||||
|
@ -92,14 +87,15 @@
|
|||
|
||||
</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>
|
||||
</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>
|
|
@ -8,23 +8,20 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
|
||||
<com.google.android.material.search.SearchBar
|
||||
android:id="@+id/toolbar"
|
||||
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_margin="10dp"
|
||||
app:Enabled="false"
|
||||
tools:ignore="TouchTargetSizeCheck" />
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
android:layout_height="wrap_content"
|
||||
android:transitionName="edit"
|
||||
app:layout_scrollFlags="exitUntilCollapsed"
|
||||
android:hint="@string/search"/>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
android:layout_marginHorizontal="10dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@ -34,17 +31,14 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="每日趣荐"
|
||||
android:textSize="26sp"
|
||||
android:textSize="16sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:contentPadding="6dp">
|
||||
app:cardUseCompatPadding="true">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/recyclerview1_bar"
|
||||
|
@ -55,7 +49,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/nullPlaylists"
|
||||
android:textSize="26sp"
|
||||
android:textSize="16sp"
|
||||
android:padding="6dp"
|
||||
android:visibility="gone"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
@ -72,17 +66,14 @@
|
|||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="每日一首"
|
||||
android:textSize="26sp"
|
||||
android:textSize="16sp"
|
||||
tools:ignore="HardcodedText" />
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:contentPadding="6dp">
|
||||
app:cardUseCompatPadding="true">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/recyclerview2_bar"
|
||||
|
@ -93,7 +84,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/nullPlaylists"
|
||||
android:textSize="26sp"
|
||||
android:textSize="16sp"
|
||||
android:padding="6dp"
|
||||
android:visibility="gone"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
|
|
|
@ -20,5 +20,6 @@
|
|||
android:id="@+id/text1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:transitionName="text"
|
||||
android:text="@string/app_name"/>
|
||||
</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"?>
|
||||
<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">
|
||||
<attr name="alphaSlider" format="boolean"/>
|
||||
<attr name="lightnessSlider" format="boolean"/>
|
||||
|
@ -33,4 +26,31 @@
|
|||
<declare-styleable name="Edit">
|
||||
<attr name="Enabled" format="boolean" />
|
||||
</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>
|
|
@ -19,4 +19,12 @@
|
|||
<color name="thumbColor">#625B71</color>
|
||||
<!-- <color name="button_bj">@color/bj</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>
|
|
@ -2,6 +2,17 @@
|
|||
<resources>
|
||||
<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>
|
||||
<dimen name="lrc_text_size">16sp</dimen>
|
||||
<dimen name="lrc_time_text_size">12sp</dimen>
|
||||
|
@ -11,13 +22,4 @@
|
|||
<dimen name="lrc_timeline_height">1dp</dimen>
|
||||
<dimen name="lrc_drawable_width">30dp</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>
|
|
@ -44,4 +44,10 @@
|
|||
<item>男</item>
|
||||
<item>女</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="theme">
|
||||
<item>跟随系统</item>
|
||||
<item>浅色模式</item>
|
||||
<item>深色模式</item>
|
||||
</string-array>
|
||||
</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.
|
||||
plugins {
|
||||
id 'com.android.application' version '8.1.0' apply false
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.8.0'
|
||||
}
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
||||
}
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
compileTestKotlin {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
|
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"
|
||||
include ':app'
|
||||
include(':StatusBarUtil')
|
||||
include(":lrcview")
|
||||
//include(":lrcview")
|
Loading…
Reference in New Issue
Block a user