重写歌词组件,添加悬浮窗歌词效果
This commit is contained in:
parent
17daa94b94
commit
3f7664f652
|
@ -51,7 +51,8 @@ dependencies {
|
||||||
|
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
|
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
|
||||||
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
||||||
implementation 'com.github.wangchenyan:lrcview:2.2.1'
|
// 废弃的歌词组件
|
||||||
|
// implementation 'com.github.wangchenyan:lrcview:2.2.1'
|
||||||
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||||
|
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
<service android:name=".mq.floating" />
|
<service android:name=".mq.floating" />
|
||||||
|
<service android:name=".mq.FloatingLyricsService" />
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".MyButtonClickReceiver"
|
android:name=".MyButtonClickReceiver"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class MediaPlayer extends android.media.MediaPlayer {
|
||||||
public Runnable updateSeekBar = new Runnable() {
|
public Runnable updateSeekBar = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (isPlaying() && bfq.lrcview != null) {
|
if (isPlaying() && bfq.lrcView != null) {
|
||||||
long position = getCurrentPosition();
|
long position = getCurrentPosition();
|
||||||
Media.setProgress((int) position);
|
Media.setProgress((int) position);
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ public class MediaPlayer extends android.media.MediaPlayer {
|
||||||
.Builder()
|
.Builder()
|
||||||
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||||
.build());
|
.build());
|
||||||
main.handler.post(updateSeekBar); // 在播放开始时启动更新进度
|
// main.handler.post(updateSeekBar); // 在播放开始时启动更新进度
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -98,7 +98,7 @@ public class MediaPlayer extends android.media.MediaPlayer {
|
||||||
if (bfq.view != null) {
|
if (bfq.view != null) {
|
||||||
main.handler.removeCallbacks(updateSeekBar); // 在播放开始时启动更新进度
|
main.handler.removeCallbacks(updateSeekBar); // 在播放开始时启动更新进度
|
||||||
long duration = getDuration();
|
long duration = getDuration();
|
||||||
Media.setMax((int) getDuration());
|
Media.setMax(getDuration());
|
||||||
Media.setTime_a(bfq_an.getTime(duration));
|
Media.setTime_a(bfq_an.getTime(duration));
|
||||||
long position = getCurrentPosition();
|
long position = getCurrentPosition();
|
||||||
Media.setProgress((int) position);
|
Media.setProgress((int) position);
|
||||||
|
|
|
@ -4,8 +4,11 @@ import android.bluetooth.BluetoothAdapter;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
|
|
||||||
|
import com.muqingbfq.mq.FloatingLyricsService;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
|
@ -74,6 +77,31 @@ public class MyButtonClickReceiver extends BroadcastReceiver {
|
||||||
case "xyq":
|
case "xyq":
|
||||||
bfq_an.xyq();
|
bfq_an.xyq();
|
||||||
break;
|
break;
|
||||||
|
case "lrc":
|
||||||
|
if (FloatingLyricsService.lei == null) {
|
||||||
|
if (!Settings.canDrawOverlays(home.appCompatActivity)) {
|
||||||
|
// 无权限,需要申请权限
|
||||||
|
home.appCompatActivity.startActivity(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||||
|
Uri.parse("package:" + home.appCompatActivity.getPackageName())));
|
||||||
|
} else {
|
||||||
|
home.appCompatActivity.startService(
|
||||||
|
new Intent(home.appCompatActivity, FloatingLyricsService.class));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
FloatingLyricsService lei = FloatingLyricsService.lei;
|
||||||
|
gj.sc(lei.setup.i);
|
||||||
|
if (lei.setup.i == 0) {
|
||||||
|
lei.show();
|
||||||
|
} else if (lei.setup.i == 1) {
|
||||||
|
lei.setyc();
|
||||||
|
} else {
|
||||||
|
lei.setup.i = 0;
|
||||||
|
lei.baocun();
|
||||||
|
home.appCompatActivity.stopService(
|
||||||
|
new Intent(home.appCompatActivity, FloatingLyricsService.class));
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// 处理按钮点击事件的逻辑
|
// 处理按钮点击事件的逻辑
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,7 @@ public class url extends Thread {
|
||||||
|
|
||||||
public static String hq(MP3 x) {
|
public static String hq(MP3 x) {
|
||||||
getLrc(x.id);
|
getLrc(x.id);
|
||||||
if (bfq.lrcview != null) {
|
Media.loadLyric();
|
||||||
Media.loadLyric();
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (wj.cz(wj.mp3 + x.id)) {
|
if (wj.cz(wj.mp3 + x.id)) {
|
||||||
return wj.mp3 + x.id;
|
return wj.mp3 + x.id;
|
||||||
|
@ -152,7 +150,7 @@ public class url extends Thread {
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
gj.sc(e);
|
gj.sc(e);
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
bfq.lrc = wl.hq("/lyric?id=" + id);
|
bfq.lrc = wl.hq("/lyric?id=" + id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,17 +38,15 @@ import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import me.wcy.lrcview.LrcView;
|
|
||||||
|
|
||||||
public class bfq extends AppCompatActivity {
|
public class bfq extends AppCompatActivity {
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
public static ActivityBfqBinding binding;
|
public static ActivityBfqBinding binding;
|
||||||
@SuppressLint("StaticFieldLeak")
|
@SuppressLint("StaticFieldLeak")
|
||||||
public static View view;
|
public static View view;
|
||||||
public static String lrc;
|
public static String lrc;
|
||||||
public static LrcView lrcview;
|
public static com.muqingbfq.view.LrcView lrcView;
|
||||||
private void setLrc(){
|
private void setLrc(){
|
||||||
lrcview = binding.lrcView;
|
lrcView = binding.lrcView;/*
|
||||||
lrcview.setCurrentColor(ContextCompat.getColor(this,R.color.text));
|
lrcview.setCurrentColor(ContextCompat.getColor(this,R.color.text));
|
||||||
lrcview.setLabel(getString(R.string.app_name));
|
lrcview.setLabel(getString(R.string.app_name));
|
||||||
lrcview.setCurrentTextSize(TypedValue.applyDimension(
|
lrcview.setCurrentTextSize(TypedValue.applyDimension(
|
||||||
|
@ -73,7 +71,7 @@ public class bfq extends AppCompatActivity {
|
||||||
} else {
|
} else {
|
||||||
lrcview.setOnTapListener((view, x, y) -> {
|
lrcview.setOnTapListener((view, x, y) -> {
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
|
@ -211,7 +209,9 @@ public class bfq extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
public class Touch implements View.OnTouchListener {
|
public class Touch implements View.OnTouchListener {
|
||||||
private float downY, moveY;
|
private float downY;
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
public boolean onTouch(View view, MotionEvent motionEvent) {LinearLayout root = binding.getRoot();
|
public boolean onTouch(View view, MotionEvent motionEvent) {LinearLayout root = binding.getRoot();
|
||||||
switch (motionEvent.getAction()) {
|
switch (motionEvent.getAction()) {
|
||||||
|
@ -220,7 +220,7 @@ public class bfq extends AppCompatActivity {
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_MOVE:
|
case MotionEvent.ACTION_MOVE:
|
||||||
//长按事件,可以移动
|
//长按事件,可以移动
|
||||||
moveY = motionEvent.getRawY();
|
float moveY = motionEvent.getRawY();
|
||||||
//移动的距离
|
//移动的距离
|
||||||
float dy = moveY - downY;
|
float dy = moveY - downY;
|
||||||
//重新设置控件的位置。移动
|
//重新设置控件的位置。移动
|
||||||
|
@ -267,6 +267,7 @@ public class bfq extends AppCompatActivity {
|
||||||
public void finish() {
|
public void finish() {
|
||||||
super.finish();
|
super.finish();
|
||||||
view = null;
|
view = null;
|
||||||
lrcview = null;
|
lrcView = null;
|
||||||
|
main.handler.removeCallbacks(bfqkz.mt.updateSeekBar); // 在播放开始时启动更新进度
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ import androidx.media.MediaBrowserServiceCompat;
|
||||||
|
|
||||||
import com.muqingbfq.api.url;
|
import com.muqingbfq.api.url;
|
||||||
import com.muqingbfq.mq.BluetoothMusicController;
|
import com.muqingbfq.mq.BluetoothMusicController;
|
||||||
|
import com.muqingbfq.mq.FloatingLyricsService;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
import com.muqingbfq.mq.wj;
|
import com.muqingbfq.mq.wj;
|
||||||
|
|
||||||
|
@ -95,7 +96,6 @@ public class bfqkz extends MediaBrowserServiceCompat {
|
||||||
playback = new PlaybackStateCompat.Builder()
|
playback = new PlaybackStateCompat.Builder()
|
||||||
.setState(PlaybackStateCompat.STATE_NONE, 0, 1.0f)
|
.setState(PlaybackStateCompat.STATE_NONE, 0, 1.0f)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Intent intent = new Intent(Intent.ACTION_MAIN);
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
intent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||||
intent.setComponent(new ComponentName(this, home.class));//用ComponentName得到class对象
|
intent.setComponent(new ComponentName(this, home.class));//用ComponentName得到class对象
|
||||||
|
@ -111,6 +111,7 @@ public class bfqkz extends MediaBrowserServiceCompat {
|
||||||
setSessionToken(mSession.getSessionToken());
|
setSessionToken(mSession.getSessionToken());
|
||||||
|
|
||||||
notify = new com.muqingbfq.mq.NotificationManagerCompat(this);
|
notify = new com.muqingbfq.mq.NotificationManagerCompat(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class callback extends MediaSessionCompat.Callback {
|
class callback extends MediaSessionCompat.Callback {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.muqingbfq.fragment;
|
package com.muqingbfq.fragment;
|
||||||
|
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
|
|
||||||
import com.muqingbfq.R;
|
import com.muqingbfq.R;
|
||||||
import com.muqingbfq.bfq;
|
import com.muqingbfq.bfq;
|
||||||
import com.muqingbfq.bfq_an;
|
import com.muqingbfq.bfq_an;
|
||||||
|
@ -7,8 +9,11 @@ import com.muqingbfq.bfqkz;
|
||||||
import com.muqingbfq.databinding.ActivityBfqBinding;
|
import com.muqingbfq.databinding.ActivityBfqBinding;
|
||||||
import com.muqingbfq.main;
|
import com.muqingbfq.main;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
|
import com.muqingbfq.view.LrcView;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
public class Media{
|
|
||||||
|
public class Media {
|
||||||
public static void setTime_a(String str) {
|
public static void setTime_a(String str) {
|
||||||
if (bfq.view == null) {
|
if (bfq.view == null) {
|
||||||
return;
|
return;
|
||||||
|
@ -35,7 +40,8 @@ public class Media{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bfq.binding.tdt.setProgress(progress);
|
bfq.binding.tdt.setProgress(progress);
|
||||||
bfq.lrcview.updateTime(progress);
|
// bfq.lrcview.updateTime(progress);
|
||||||
|
bfq.lrcView.setTimeLrc(progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setbf(boolean bool) {
|
public static void setbf(boolean bool) {
|
||||||
|
@ -56,11 +62,13 @@ public class Media{
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
setTime_b(bfq_an.getTime(progress));
|
setTime_b(bfq_an.getTime(progress));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
// 拖动条移动中
|
// 拖动条移动中
|
||||||
main.handler.removeCallbacks(bfqkz.mt.updateSeekBar);
|
main.handler.removeCallbacks(bfqkz.mt.updateSeekBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
// 播放音乐到指定位置
|
// 播放音乐到指定位置
|
||||||
|
@ -70,12 +78,11 @@ public class Media{
|
||||||
});
|
});
|
||||||
//初始化播放器列表
|
//初始化播放器列表
|
||||||
if (bfqkz.xm != null) {
|
if (bfqkz.xm != null) {
|
||||||
// main.handler.removeCallbacks(bfqkz.mt.updateSeekBar); // 在播放开始时启动更新进度
|
|
||||||
long duration = bfqkz.mt.getDuration();
|
long duration = bfqkz.mt.getDuration();
|
||||||
binding.tdt.setMax((int) bfqkz.mt.getDuration());
|
binding.tdt.setMax(bfqkz.mt.getDuration());
|
||||||
setTime_a(bfq_an.getTime(duration));
|
setTime_a(bfq_an.getTime(duration));
|
||||||
long position = bfqkz.mt.getCurrentPosition();
|
long position = bfqkz.mt.getCurrentPosition();
|
||||||
// main.handler.post(bfqkz.mt.updateSeekBar); // 在播放开始时启动更新进度
|
main.handler.post(bfqkz.mt.updateSeekBar); // 在播放开始时启动更新进度
|
||||||
loadLyric();
|
loadLyric();
|
||||||
setProgress((int) position);
|
setProgress((int) position);
|
||||||
}
|
}
|
||||||
|
@ -83,7 +90,7 @@ public class Media{
|
||||||
|
|
||||||
|
|
||||||
public static void loadLyric() {
|
public static void loadLyric() {
|
||||||
if (bfq.lrcview == null || com.muqingbfq.bfq.lrc == null) {
|
if (com.muqingbfq.bfq.lrc == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
JSONObject jsonObject;
|
JSONObject jsonObject;
|
||||||
|
@ -95,7 +102,9 @@ public class Media{
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
gj.sc(e);
|
gj.sc(e);
|
||||||
}
|
}
|
||||||
bfq.lrcview.loadLrc(a, b);
|
LrcView.setLrc(a, b);
|
||||||
|
// bfq.lrcView.getLrc();
|
||||||
|
// bfq.lrcView.loadLrc(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ import com.muqingbfq.databinding.FragmentSearchBinding;
|
||||||
import com.muqingbfq.list.MyViewHoder;
|
import com.muqingbfq.list.MyViewHoder;
|
||||||
import com.muqingbfq.main;
|
import com.muqingbfq.main;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
import com.muqingbfq.mq.wj;
|
|
||||||
import com.muqingbfq.mq.wl;
|
import com.muqingbfq.mq.wl;
|
||||||
import com.muqingbfq.xm;
|
import com.muqingbfq.xm;
|
||||||
|
|
||||||
|
@ -39,7 +38,6 @@ public class search extends Fragment {
|
||||||
public static RecyclerView.Adapter<MyViewHoder> lbspq;
|
public static RecyclerView.Adapter<MyViewHoder> lbspq;
|
||||||
List<MP3> list = new ArrayList<>();
|
List<MP3> list = new ArrayList<>();
|
||||||
List<xm> xmList = new ArrayList<>();
|
List<xm> xmList = new ArrayList<>();
|
||||||
gd.baseadapter adapter_gd;
|
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
public FragmentSearchBinding inflate;
|
public FragmentSearchBinding inflate;
|
||||||
|
@ -55,7 +53,6 @@ public class search extends Fragment {
|
||||||
TypedValue typedValue = new TypedValue();
|
TypedValue typedValue = new TypedValue();
|
||||||
requireContext().getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true);
|
requireContext().getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true);
|
||||||
// 设置背景颜色
|
// 设置背景颜色
|
||||||
adapter_gd = new gd.baseadapter(getContext(), xmList);
|
|
||||||
view.setBackgroundColor(typedValue.data);
|
view.setBackgroundColor(typedValue.data);
|
||||||
inflate.tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
inflate.tablayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -101,7 +98,7 @@ public class search extends Fragment {
|
||||||
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(),
|
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(),
|
||||||
k);
|
k);
|
||||||
inflate.recyclerview.setLayoutManager(gridLayoutManager);
|
inflate.recyclerview.setLayoutManager(gridLayoutManager);
|
||||||
inflate.recyclerview.setAdapter(adapter_gd);
|
inflate.recyclerview.setAdapter(new gd.baseadapter(getContext(), xmList));
|
||||||
}
|
}
|
||||||
new start(name);
|
new start(name);
|
||||||
}
|
}
|
||||||
|
@ -123,14 +120,7 @@ public class search extends Fragment {
|
||||||
} else if (i == 1) {
|
} else if (i == 1) {
|
||||||
gd();
|
gd();
|
||||||
}
|
}
|
||||||
main.handler.post(() -> {
|
main.handler.post(() -> inflate.recyclerview.getAdapter().notifyDataSetChanged());
|
||||||
if (i == 0) {
|
|
||||||
lbspq.notifyDataSetChanged();
|
|
||||||
} else if (i == 1) {
|
|
||||||
adapter_gd.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
// lbspq.notifyDataSetChanged();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,16 @@ import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.provider.Settings;
|
||||||
import android.support.v4.media.MediaBrowserCompat;
|
import android.support.v4.media.MediaBrowserCompat;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.appcompat.app.ActionBarDrawerToggle;
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
@ -21,9 +25,11 @@ import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
import com.muqingbfq.databinding.ActivityHomeBinding;
|
import com.muqingbfq.databinding.ActivityHomeBinding;
|
||||||
|
import com.muqingbfq.databinding.FloatLrcviewBinding;
|
||||||
import com.muqingbfq.fragment.bfq_db;
|
import com.muqingbfq.fragment.bfq_db;
|
||||||
import com.muqingbfq.fragment.gd_adapter;
|
import com.muqingbfq.fragment.gd_adapter;
|
||||||
import com.muqingbfq.fragment.wode;
|
import com.muqingbfq.fragment.wode;
|
||||||
|
import com.muqingbfq.mq.FloatingLyricsService;
|
||||||
import com.muqingbfq.mq.gj;
|
import com.muqingbfq.mq.gj;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -77,6 +83,7 @@ public class home extends AppCompatActivity {
|
||||||
binding.editView.setOnClickListener(view ->
|
binding.editView.setOnClickListener(view ->
|
||||||
startActivity(new Intent(this, activity_search.class)));
|
startActivity(new Intent(this, activity_search.class)));
|
||||||
UI();
|
UI();
|
||||||
|
// startService(new Intent(this, FloatingLyricsService.class));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
yc.tc(this, e);
|
yc.tc(this, e);
|
||||||
}
|
}
|
||||||
|
@ -87,21 +94,25 @@ public class home extends AppCompatActivity {
|
||||||
|
|
||||||
private class Adaper extends FragmentStateAdapter {
|
private class Adaper extends FragmentStateAdapter {
|
||||||
List<Fragment> list = new ArrayList<>();
|
List<Fragment> list = new ArrayList<>();
|
||||||
|
|
||||||
public Adaper(@NonNull FragmentActivity fragmentActivity) {
|
public Adaper(@NonNull FragmentActivity fragmentActivity) {
|
||||||
super(fragmentActivity);
|
super(fragmentActivity);
|
||||||
list.add(new gd_adapter());
|
list.add(new gd_adapter());
|
||||||
list.add(new wode());
|
list.add(new wode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Fragment createFragment(int position) {
|
public Fragment createFragment(int position) {
|
||||||
return list.get(position);
|
return list.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
return list.size();
|
return list.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UI() {
|
public void UI() {
|
||||||
adapter = new Adaper(this);
|
adapter = new Adaper(this);
|
||||||
binding.viewPager.setAdapter(adapter);
|
binding.viewPager.setAdapter(adapter);
|
||||||
|
@ -144,6 +155,35 @@ public class home extends AppCompatActivity {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
stopService(new Intent(this, FloatingLyricsService.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityResultLauncher<Intent> LyricsService =
|
||||||
|
registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
||||||
|
if (Settings.canDrawOverlays(this)) {
|
||||||
|
startService(new Intent(this, FloatingLyricsService.class));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
if (!FloatingLyricsService.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!Settings.canDrawOverlays(this)) {
|
||||||
|
// 无权限,需要申请权限
|
||||||
|
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||||
|
Uri.parse("package:" + getPackageName()));
|
||||||
|
LyricsService.launch(intent);
|
||||||
|
} else {
|
||||||
|
startService(new Intent(this, FloatingLyricsService.class));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.muqingbfq;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
@ -9,6 +10,7 @@ import android.os.Looper;
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
import androidx.appcompat.app.AppCompatDelegate;
|
||||||
|
|
||||||
import com.muqingbfq.login.visitor;
|
import com.muqingbfq.login.visitor;
|
||||||
|
import com.muqingbfq.mq.FloatingLyricsService;
|
||||||
import com.muqingbfq.mq.wj;
|
import com.muqingbfq.mq.wj;
|
||||||
import com.muqingbfq.mq.wl;
|
import com.muqingbfq.mq.wl;
|
||||||
|
|
||||||
|
|
221
app/src/main/java/com/muqingbfq/mq/FloatingLyricsService.java
Normal file
221
app/src/main/java/com/muqingbfq/mq/FloatingLyricsService.java
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
package com.muqingbfq.mq;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.PixelFormat;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import com.muqingbfq.bfq_an;
|
||||||
|
import com.muqingbfq.bfqkz;
|
||||||
|
import com.muqingbfq.databinding.FloatLrcviewBinding;
|
||||||
|
import com.muqingbfq.main;
|
||||||
|
import com.muqingbfq.view.LrcView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
|
public class FloatingLyricsService extends Service implements View.OnClickListener, View.OnTouchListener {
|
||||||
|
private WindowManager windowManager;
|
||||||
|
private View layout;
|
||||||
|
public Runnable updateSeekBar = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (bfqkz.mt.isPlaying() && lrcView != null) {
|
||||||
|
long position = bfqkz.mt.getCurrentPosition();
|
||||||
|
lrcView.setTimeLrc(position);
|
||||||
|
}
|
||||||
|
handler.postDelayed(this, 1000); // 每秒更新一次进度
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@SuppressLint("StaticFieldLeak")
|
||||||
|
public static FloatingLyricsService lei;
|
||||||
|
|
||||||
|
public static boolean get() {
|
||||||
|
File file = new File(wj.filesdri + "FloatingLyricsService.json");
|
||||||
|
if (file.exists() && file.isFile()) {
|
||||||
|
String dqwb = wj.dqwb(file.toString());
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Type type = new TypeToken<SETUP>() {
|
||||||
|
}.getType();
|
||||||
|
SETUP setup = gson.fromJson(dqwb, type);
|
||||||
|
return setup.i != 0;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Handler handler = new Handler();
|
||||||
|
LrcView lrcView;
|
||||||
|
WindowManager.LayoutParams params;
|
||||||
|
|
||||||
|
public static class SETUP {
|
||||||
|
//0是关闭 1是打开 2是锁定
|
||||||
|
public int i;
|
||||||
|
public float TOP;
|
||||||
|
public int Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SETUP setup = new SETUP();
|
||||||
|
File file;
|
||||||
|
|
||||||
|
public int lock() {
|
||||||
|
if (setup != null && setup.i == 2) {
|
||||||
|
return WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||||
|
}
|
||||||
|
return WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||||
|
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
lei = this;
|
||||||
|
try {
|
||||||
|
file = new File(wj.filesdri + "FloatingLyricsService.json");
|
||||||
|
if (file.exists() && file.isFile()) {
|
||||||
|
String dqwb = wj.dqwb(file.toString());
|
||||||
|
Gson gson = new Gson();
|
||||||
|
Type type = new TypeToken<SETUP>() {
|
||||||
|
}.getType();
|
||||||
|
setup = gson.fromJson(dqwb, type);
|
||||||
|
} else {
|
||||||
|
setup.i = 1;
|
||||||
|
setup.TOP = 0;
|
||||||
|
setup.Y = -main.g;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
wj.sc(file.toString());
|
||||||
|
gj.sc(e);
|
||||||
|
}
|
||||||
|
// 创建悬浮窗歌词的 View
|
||||||
|
// FloatLrcviewBinding
|
||||||
|
FloatLrcviewBinding binding = FloatLrcviewBinding.inflate(LayoutInflater.from(this));
|
||||||
|
layout = binding.getRoot();
|
||||||
|
layout.setOnTouchListener(this);
|
||||||
|
// ViewGroup.LayoutParams layoutParams = layout.getLayoutParams();
|
||||||
|
// layout.setLayoutParams(layoutParams);
|
||||||
|
|
||||||
|
// int i = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;FLAG_NOT_TOUCH_MODAL
|
||||||
|
params = new WindowManager.LayoutParams(
|
||||||
|
WindowManager.LayoutParams.MATCH_PARENT,
|
||||||
|
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||||
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ?
|
||||||
|
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY :
|
||||||
|
WindowManager.LayoutParams.TYPE_PHONE,
|
||||||
|
lock(),
|
||||||
|
PixelFormat.TRANSLUCENT
|
||||||
|
);
|
||||||
|
|
||||||
|
params.y = setup.Y;
|
||||||
|
|
||||||
|
lrcView = binding.lrcView;
|
||||||
|
bfq_an.kz bfqAn = new bfq_an.kz();
|
||||||
|
binding.kg.setOnClickListener(bfqAn);
|
||||||
|
binding.syq.setOnClickListener(bfqAn);
|
||||||
|
binding.xyq.setOnClickListener(bfqAn);
|
||||||
|
binding.lock.setOnClickListener(this);
|
||||||
|
// params.gravity = Gravity.CENTER;
|
||||||
|
|
||||||
|
|
||||||
|
// 获取 WindowManager 并将悬浮窗歌词添加到窗口中
|
||||||
|
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||||
|
if (setup.i == 2) {
|
||||||
|
params.flags = lock();
|
||||||
|
layout.setBackground(null);
|
||||||
|
lrcView.setAlpha(0.5f);
|
||||||
|
layout.findViewById(com.muqingbfq.R.id.controlLayout).setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
windowManager.addView(layout, params);
|
||||||
|
gj.sc("添加成功");
|
||||||
|
handler.post(updateSeekBar); // 在播放开始时启动更新进度
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
// 在 Service 销毁时移除悬浮窗歌词
|
||||||
|
if (windowManager != null && layout != null) {
|
||||||
|
windowManager.removeView(layout);
|
||||||
|
handler.removeCallbacks(bfqkz.mt.updateSeekBar); // 在播放开始时启动更新进度
|
||||||
|
}
|
||||||
|
lei = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void baocun() {
|
||||||
|
String s = new Gson().toJson(setup);
|
||||||
|
wj.xrwb(new File(wj.filesdri + "FloatingLyricsService.json").toString(), s);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int initialY;
|
||||||
|
private float initialTouchY;
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View view, MotionEvent motionEvent) {
|
||||||
|
switch (motionEvent.getAction()) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
// 记录触摸事件的初始位置和坐标
|
||||||
|
initialY = params.y;
|
||||||
|
initialTouchY = motionEvent.getRawY();
|
||||||
|
return true;
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
// 计算触摸事件的偏移量,将悬浮窗口的位置设置为初始位置加上偏移量
|
||||||
|
int offsetY = (int) (motionEvent.getRawY() - initialTouchY);
|
||||||
|
setup.Y = initialY + offsetY;
|
||||||
|
params.y = setup.Y;
|
||||||
|
windowManager.updateViewLayout(layout, params);
|
||||||
|
return true;
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
baocun();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
setyc();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setyc() {
|
||||||
|
setup.i = 2;
|
||||||
|
params.flags = lock();
|
||||||
|
layout.setBackground(null);
|
||||||
|
lrcView.setAlpha(0.5f);
|
||||||
|
layout.findViewById(com.muqingbfq.R.id.controlLayout).setVisibility(View.GONE);
|
||||||
|
windowManager.updateViewLayout(layout, params);
|
||||||
|
baocun();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show() {
|
||||||
|
setup.i = 1;
|
||||||
|
params.flags = lock();
|
||||||
|
layout.setBackgroundColor(Color.parseColor("#50000000"));
|
||||||
|
lrcView.setAlpha(1.0f);
|
||||||
|
layout.findViewById(com.muqingbfq.R.id.controlLayout).setVisibility(View.VISIBLE);
|
||||||
|
windowManager.updateViewLayout(layout, params);
|
||||||
|
baocun();
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,8 +54,10 @@ public class NotificationManagerCompat {
|
||||||
setAction("syq"));
|
setAction("syq"));
|
||||||
pendingIntent_xyq = getBroadcast(context, my.
|
pendingIntent_xyq = getBroadcast(context, my.
|
||||||
setAction("xyq"));
|
setAction("xyq"));
|
||||||
|
pendingIntent_lrc = getBroadcast(context, my.
|
||||||
|
setAction("lrc"));
|
||||||
style = new androidx.media.app.NotificationCompat.MediaStyle()
|
style = new androidx.media.app.NotificationCompat.MediaStyle()
|
||||||
.setShowActionsInCompactView(0, 1, 2)
|
.setShowActionsInCompactView(1, 2, 3)
|
||||||
.setMediaSession(bfqkz.mSession.getSessionToken());
|
.setMediaSession(bfqkz.mSession.getSessionToken());
|
||||||
notificationManager = androidx.core.app.NotificationManagerCompat.from(context);
|
notificationManager = androidx.core.app.NotificationManagerCompat.from(context);
|
||||||
notificationBuilder = getNotificationBuilder(context)
|
notificationBuilder = getNotificationBuilder(context)
|
||||||
|
@ -79,10 +81,13 @@ public class NotificationManagerCompat {
|
||||||
zz = bfqkz.xm.zz;
|
zz = bfqkz.xm.zz;
|
||||||
}
|
}
|
||||||
notificationBuilder.mActions.clear();
|
notificationBuilder.mActions.clear();
|
||||||
notificationBuilder.addAction(android.R.drawable.ic_media_previous, "syq", pendingIntent_syq) // #0
|
notificationBuilder
|
||||||
.addAction(bfqkz.mt.isPlaying() ? android.R.drawable.ic_media_pause : android.R.drawable.ic_media_play
|
.addAction(R.drawable.like, "like", pendingIntent_kg) // #0
|
||||||
|
.addAction(R.drawable.syq, "syq", pendingIntent_syq) // #0
|
||||||
|
.addAction(bfqkz.mt.isPlaying() ? R.drawable.bf : R.drawable.zt
|
||||||
, "kg", pendingIntent_kg) // #1
|
, "kg", pendingIntent_kg) // #1
|
||||||
.addAction(android.R.drawable.ic_media_next, "xyq", pendingIntent_xyq)
|
.addAction(R.drawable.xyq, "xyq", pendingIntent_xyq)
|
||||||
|
.addAction(R.drawable.lock, "lrc", pendingIntent_lrc)
|
||||||
.setContentTitle(name)
|
.setContentTitle(name)
|
||||||
.setContentText(zz)
|
.setContentText(zz)
|
||||||
.setOngoing(bfqkz.mt.isPlaying());
|
.setOngoing(bfqkz.mt.isPlaying());
|
||||||
|
@ -91,7 +96,8 @@ public class NotificationManagerCompat {
|
||||||
|
|
||||||
private PendingIntent pendingIntent_kg,
|
private PendingIntent pendingIntent_kg,
|
||||||
pendingIntent_syq,
|
pendingIntent_syq,
|
||||||
pendingIntent_xyq;
|
pendingIntent_xyq,
|
||||||
|
pendingIntent_lrc;
|
||||||
private final String CHANNEL_ID = "muqing_yy_id";
|
private final String CHANNEL_ID = "muqing_yy_id";
|
||||||
|
|
||||||
public void notificationManager_notify() {
|
public void notificationManager_notify() {
|
||||||
|
|
|
@ -79,7 +79,8 @@ public class sz extends AppCompatActivity {
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActivityResultLauncher<Intent> intent = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
|
ActivityResultLauncher<Intent> intent = registerForActivityResult(
|
||||||
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
result -> {
|
result -> {
|
||||||
if (Settings.canDrawOverlays(this)) {
|
if (Settings.canDrawOverlays(this)) {
|
||||||
com.muqingbfq.mq.floating.start(sz.this);
|
com.muqingbfq.mq.floating.start(sz.this);
|
||||||
|
|
352
app/src/main/java/com/muqingbfq/view/LrcView.java
Normal file
352
app/src/main/java/com/muqingbfq/view/LrcView.java
Normal file
|
@ -0,0 +1,352 @@
|
||||||
|
package com.muqingbfq.view;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.text.Layout;
|
||||||
|
import android.text.StaticLayout;
|
||||||
|
import android.text.TextPaint;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.LinearSmoothScroller;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.muqingbfq.R;
|
||||||
|
import com.muqingbfq.main;
|
||||||
|
import com.muqingbfq.mq.gj;
|
||||||
|
import com.muqingbfq.yc;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LrcView extends RecyclerView {
|
||||||
|
private void sc(Object obj) {
|
||||||
|
gj.sc("LRC " + obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<lrc> lrclist = new ArrayList<>();
|
||||||
|
|
||||||
|
static class lrc {
|
||||||
|
String lrc, tlyric;
|
||||||
|
long time;
|
||||||
|
|
||||||
|
public lrc(String lrc, long time) {
|
||||||
|
this.lrc = lrc;
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public lrc(String lrc, String tlyric, long time) {
|
||||||
|
this.lrc = lrc;
|
||||||
|
this.tlyric = tlyric;
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public lrc setTlyric(String str) {
|
||||||
|
this.tlyric = str;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public LrcView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeSet attrs;
|
||||||
|
boolean Lrcline;
|
||||||
|
LinearLayoutManager linearLayoutManager;
|
||||||
|
|
||||||
|
public LrcView(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
this.attrs = attrs;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public LrcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
this.attrs = attrs;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
if (attrs != null) {
|
||||||
|
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.LrcView);
|
||||||
|
TextColor = ta.getColor(R.styleable.LrcView_TextColor,
|
||||||
|
ContextCompat.getColor(getContext(), R.color.text));
|
||||||
|
Lrcline = ta.getBoolean(R.styleable.LrcView_Lrcline, true);
|
||||||
|
ta.recycle();
|
||||||
|
}
|
||||||
|
linearLayoutManager = new LinearLayoutManager(getContext()) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
|
||||||
|
RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
|
||||||
|
smoothScroller.setTargetPosition(position);
|
||||||
|
startSmoothScroll(smoothScroller);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
setLayoutManager(linearLayoutManager);
|
||||||
|
setAdapter(new adaper());
|
||||||
|
setForeground(null);
|
||||||
|
setOverScrollMode(RecyclerView.OVER_SCROLL_NEVER);
|
||||||
|
if (!Lrcline) {
|
||||||
|
addItemDecoration( new RecyclerView.ItemDecoration() {
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||||
|
super.getItemOffsets(outRect, view, parent, state);
|
||||||
|
|
||||||
|
int parentHeight = parent.getHeight();
|
||||||
|
int childHeight = view.getHeight();
|
||||||
|
|
||||||
|
int topMargin = (parentHeight - childHeight) / 2;
|
||||||
|
|
||||||
|
// 设置第一项的顶部间距
|
||||||
|
if (parent.getChildAdapterPosition(view) == 0) {
|
||||||
|
outRect.top = topMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CenterSmoothScroller extends LinearSmoothScroller {
|
||||||
|
|
||||||
|
CenterSmoothScroller(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
|
||||||
|
return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
|
||||||
|
return 100f / displayMetrics.densityDpi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLrc(String a, String b) {
|
||||||
|
setLrc(a);
|
||||||
|
if (TextUtils.isEmpty(b)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
b.trim();
|
||||||
|
String[] lines = b.split("\n");
|
||||||
|
for (String line : lines) {
|
||||||
|
String[] parts = line.split("]");
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
String timeString = parts[0].substring(1);
|
||||||
|
String lyric = parts[1].trim();
|
||||||
|
String[] timeParts = timeString.split(":");
|
||||||
|
if (timeParts.length >= 2) {
|
||||||
|
int minute = Integer.parseInt(timeParts[0]);
|
||||||
|
String[] secondParts = timeParts[1].split("\\.");
|
||||||
|
if (secondParts.length >= 2) {
|
||||||
|
int second = Integer.parseInt(secondParts[0]);
|
||||||
|
int millisecond = Integer.parseInt(secondParts[1]);
|
||||||
|
long time = (long) minute * 60 * 1000 + second * 1000L + millisecond;
|
||||||
|
int currentLineIndex = getCurrentLineIndex(time);
|
||||||
|
lrclist.set(currentLineIndex, lrclist.get(currentLineIndex).setTlyric(lyric));
|
||||||
|
// gj.sc(lyric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLrc(String a) {
|
||||||
|
lrclist.clear();
|
||||||
|
// 去除空格
|
||||||
|
a.trim();
|
||||||
|
if (TextUtils.isEmpty(a)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String[] lines = a.split("\n");
|
||||||
|
for (String line : lines) {
|
||||||
|
String[] parts = line.split("]");
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
String timeString = parts[0].substring(1);
|
||||||
|
String lyric = parts[1].trim();
|
||||||
|
String[] timeParts = timeString.split(":");
|
||||||
|
if (timeParts.length >= 2) {
|
||||||
|
int minute = Integer.parseInt(timeParts[0]);
|
||||||
|
String[] secondParts = timeParts[1].split("\\.");
|
||||||
|
if (secondParts.length >= 2) {
|
||||||
|
int second = Integer.parseInt(secondParts[0]);
|
||||||
|
int millisecond = Integer.parseInt(secondParts[1]);
|
||||||
|
long time = (long) minute * 60 * 1000 + second * 1000L + millisecond;
|
||||||
|
lrclist.add(new lrc(lyric, time));
|
||||||
|
// gj.sc(lyric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class adaper extends RecyclerView.Adapter<VH> {
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.view_lrc, parent, false);
|
||||||
|
TextView textView = inflate.findViewById(R.id.text);
|
||||||
|
textView.setTextColor(TextColor);
|
||||||
|
textView.setTextSize(
|
||||||
|
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20,
|
||||||
|
getResources().getDisplayMetrics()));
|
||||||
|
return new VH(inflate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull VH holder, int position) {
|
||||||
|
if (lrclist.isEmpty()) {
|
||||||
|
holder.textView.setText("纯音乐,请欣赏");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Lrcline) {
|
||||||
|
int currentLineIndex = getCurrentLineIndex();
|
||||||
|
if (currentLineIndex >= 0 && currentLineIndex < lrclist.size()) {
|
||||||
|
|
||||||
|
String text;
|
||||||
|
if (lrclist.size() <= 3) {
|
||||||
|
for (lrc a : lrclist) {
|
||||||
|
if (a.time == 5940000 && a.lrc.equals("纯音乐,请欣赏")) {
|
||||||
|
text = "纯音乐,请欣赏";
|
||||||
|
holder.textView.setText(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lrc currentLrc = lrclist.get(currentLineIndex);
|
||||||
|
text = currentLrc.lrc;
|
||||||
|
if (currentLrc.tlyric != null) {
|
||||||
|
text += "\n" + currentLrc.tlyric;
|
||||||
|
}
|
||||||
|
holder.textView.setText(text);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
lrc lrc = lrclist.get(position);
|
||||||
|
StringBuilder stringBuffer = new StringBuilder();
|
||||||
|
stringBuffer.append(lrc.lrc);
|
||||||
|
if (lrc.tlyric != null) {
|
||||||
|
stringBuffer.append("\n").append(lrc.tlyric);
|
||||||
|
}
|
||||||
|
stringBuffer.append("\n");
|
||||||
|
holder.textView.setAlpha(0.1f);
|
||||||
|
if (getCurrentLineIndex(time) == position) {
|
||||||
|
holder.textView.setAlpha(1.0f);
|
||||||
|
}
|
||||||
|
holder.textView.setText(stringBuffer.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
gj.sc("LrcView.ADAPER.onBindViewHolder" + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
gj.sc(lrclist.size());
|
||||||
|
if (lrclist.size() < 3) {
|
||||||
|
for (lrc a : lrclist) {
|
||||||
|
if (a.time == 5940000 && a.lrc.equals("纯音乐,请欣赏")) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Lrcline) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (lrclist.isEmpty()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return lrclist.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VH extends RecyclerView.ViewHolder {
|
||||||
|
TextView textView;
|
||||||
|
|
||||||
|
public VH(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
textView = itemView.findViewById(R.id.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* @Override
|
||||||
|
public void onDraw(@NonNull Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
setTimeLrc(canvas);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private int getCurrentLineIndex() {
|
||||||
|
int index = -1;
|
||||||
|
for (int i = 0; i < lrclist.size(); i++) {
|
||||||
|
lrc lineLrc = lrclist.get(i);
|
||||||
|
if (lineLrc.time <= time) {
|
||||||
|
index = i;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getCurrentLineIndex(long time) {
|
||||||
|
int index = -1;
|
||||||
|
for (int i = 0; i < lrclist.size(); i++) {
|
||||||
|
lrc lineLrc = lrclist.get(i);
|
||||||
|
if (lineLrc.time <= time) {
|
||||||
|
index = i;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextColor;
|
||||||
|
long time;
|
||||||
|
|
||||||
|
@SuppressLint("NotifyDataSetChanged")
|
||||||
|
public void setTimeLrc(long a) {
|
||||||
|
this.time = a;
|
||||||
|
if (!Lrcline) {
|
||||||
|
int currentLineIndex = getCurrentLineIndex(a);
|
||||||
|
if (currentLineIndex == -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
linearLayoutManager.smoothScrollToPosition(this,
|
||||||
|
new RecyclerView.State(), currentLineIndex);
|
||||||
|
// smoothScrollToPosition(getCurrentLineIndex(a));
|
||||||
|
getAdapter().notifyItemChanged(--currentLineIndex);
|
||||||
|
getAdapter().notifyItemChanged(getCurrentLineIndex(a));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
getAdapter().notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getLrc() {
|
||||||
|
for (lrc a : lrclist) {
|
||||||
|
sc(a.time + ":" + a.lrc + ":" + a.tlyric);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="64dp"
|
android:width="46dp"
|
||||||
android:height="64dp"
|
android:height="46dp"
|
||||||
android:viewportWidth="1024"
|
android:viewportWidth="1024"
|
||||||
android:viewportHeight="1024">
|
android:viewportHeight="1024">
|
||||||
<path
|
<path
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="200dp"
|
android:width="36dp"
|
||||||
android:height="200dp"
|
android:height="36dp"
|
||||||
android:viewportWidth="1024"
|
android:viewportWidth="1024"
|
||||||
android:viewportHeight="1024">
|
android:viewportHeight="1024">
|
||||||
<path
|
<path
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="64dp"
|
android:width="36dp"
|
||||||
android:height="64dp"
|
android:height="36dp"
|
||||||
android:viewportWidth="1024"
|
android:viewportWidth="1024"
|
||||||
android:viewportHeight="1024">
|
android:viewportHeight="1024">
|
||||||
<path
|
<path
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="64dp"
|
android:width="36dp"
|
||||||
android:height="64dp"
|
android:height="36dp"
|
||||||
android:viewportWidth="1024"
|
android:viewportWidth="1024"
|
||||||
android:viewportHeight="1024">
|
android:viewportHeight="1024">
|
||||||
<path
|
<path
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="64dp"
|
android:width="46dp"
|
||||||
android:height="64dp"
|
android:height="46dp"
|
||||||
android:viewportWidth="1024"
|
android:viewportWidth="1024"
|
||||||
android:viewportHeight="1024">
|
android:viewportHeight="1024">
|
||||||
<path
|
<path
|
||||||
|
|
|
@ -64,10 +64,11 @@
|
||||||
app:cardCornerRadius="16dp"
|
app:cardCornerRadius="16dp"
|
||||||
app:cardUseCompatPadding="true" />
|
app:cardUseCompatPadding="true" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
<me.wcy.lrcview.LrcView
|
<com.muqingbfq.view.LrcView
|
||||||
android:id="@+id/lrcView"
|
android:id="@+id/lrcView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
app:Lrcline="false"
|
||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -37,8 +36,6 @@
|
||||||
android:textSize="20sp" />
|
android:textSize="20sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.appbar.MaterialToolbar>
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/fragment_bfq"
|
android:id="@+id/fragment_bfq"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -64,21 +61,115 @@
|
||||||
android:layout_height="256dp"
|
android:layout_height="256dp"
|
||||||
app:cardCornerRadius="16dp"
|
app:cardCornerRadius="16dp"
|
||||||
app:cardUseCompatPadding="true" />
|
app:cardUseCompatPadding="true" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
<me.wcy.lrcview.LrcView
|
<com.muqingbfq.view.LrcView
|
||||||
android:id="@+id/lrcView"
|
android:id="@+id/lrcView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="260dp"
|
||||||
android:layout_weight="3"/>
|
android:layout_weight="2"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:background="@color/bj"
|
||||||
|
android:paddingEnd="20dp"
|
||||||
|
android:paddingTop="6dp"
|
||||||
|
android:paddingBottom="26dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/like"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="42dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/like"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/linearLayout2"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:tint="@color/text"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/download"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/download"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/linearLayout2"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:tint="@color/text"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/control"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/mt_sx"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/syq"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/syq"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/kg"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/kg"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/kg"
|
||||||
|
app:layout_constraintVertical_bias="0.5"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/kg"
|
||||||
|
android:layout_width="46dp"
|
||||||
|
android:layout_height="46dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/zt"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/control"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/xyq"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
android:src="@drawable/xyq"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/kg"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/kg"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/kg"
|
||||||
|
app:layout_constraintVertical_bias="0.5" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/bfq_list_mp3"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/cd"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/bj"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingStart="3dp"
|
app:layout_constraintBottom_toTopOf="@+id/kg"
|
||||||
android:paddingEnd="3dp">
|
tools:layout_editor_absoluteX="20dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/time_a"
|
android:id="@+id/time_a"
|
||||||
|
@ -101,89 +192,6 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/_00_00" />
|
android:text="@string/_00_00" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@color/bj"
|
|
||||||
android:paddingStart="16dp"
|
|
||||||
android:paddingEnd="16dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/like"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:src="@drawable/like"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:tint="@color/text"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/download"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:src="@drawable/download"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:tint="@color/text"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:paddingStart="20dp"
|
|
||||||
android:background="@color/bj"
|
|
||||||
android:paddingEnd="20dp"
|
|
||||||
android:paddingBottom="26dp">
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/control"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:layout_marginEnd="26dp"
|
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:src="@drawable/mt_sx"/>
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/syq"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:layout_marginEnd="12dp"
|
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:src="@drawable/syq"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/kg"
|
|
||||||
android:layout_width="46dp"
|
|
||||||
android:layout_height="46dp"
|
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:src="@drawable/zt"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/xyq"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:layout_marginStart="12dp"
|
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:importantForAccessibility="no"
|
|
||||||
android:src="@drawable/xyq" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/bfq_list_mp3"
|
|
||||||
android:layout_width="36dp"
|
|
||||||
android:layout_height="36dp"
|
|
||||||
android:layout_marginStart="26dp"
|
|
||||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
|
||||||
android:src="@drawable/cd"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
</LinearLayout>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
77
app/src/main/res/layout/float_lrcview.xml
Normal file
77
app/src/main/res/layout/float_lrcview.xml
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="#50000000">
|
||||||
|
|
||||||
|
<com.muqingbfq.view.LrcView
|
||||||
|
android:id="@+id/lrcView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100dp"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:TextColor="@color/purple_200"
|
||||||
|
tools:layout_editor_absoluteX="16dp" />
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/controlLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/lrcView"
|
||||||
|
tools:layout_editor_absoluteX="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView2"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:src="@drawable/like"
|
||||||
|
android:text="喜欢"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/syq"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/syq"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/kg"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/kg"
|
||||||
|
android:layout_width="46dp"
|
||||||
|
android:layout_height="46dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/zt"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/xyq"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/xyq"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/kg"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/lock"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="锁定"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
12
app/src/main/res/layout/view_lrc.xml
Normal file
12
app/src/main/res/layout/view_lrc.xml
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/app_name"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
8
app/src/main/res/values/attrs.xml
Normal file
8
app/src/main/res/values/attrs.xml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?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" />
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
Loading…
Reference in New Issue
Block a user