NotSerializableException: java.util.ArrayList$SubList

本文探讨了在使用Java集合的subList方法时遇到的NotSerializableException错误,并提供了详细的解决方案。通过实例化新的ArrayList并传入subList结果,可以避免序列化错误。

使用集合调用subList时,提示NotSerializableException报错信息

java.io.NotSerializableException: java.util.ArrayList$SubList
	at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
	at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
	at com.briup.client.ClientSendImpl.run(ClientSendImpl.java:30)

subList()方法返回的集合是不可序列化的。

解决方法

new ArrayList<T>(list.subList(begin,length)) ;
package com.weishitech.qichechangtingyinyue.fragment.home; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.PointF; import android.graphics.Rect; import android.os.Bundle; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearSmoothScroller; import androidx.recyclerview.widget.RecyclerView; import com.hfd.common.base.BaseFragment; import com.hfd.common.net.GenericsCallback; import com.hfd.common.net.HttpBuiler; import com.hfd.common.net.JsonGenericsSerializator; import com.hfd.common.net.Url; import com.hfd.common.util.ToastUtil; import com.weishitech.qichechangtingyinyue.R; import com.weishitech.qichechangtingyinyue.bean.MusicBean; import com.weishitech.qichechangtingyinyue.bean.MusicCache; import com.weishitech.qichechangtingyinyue.bean.NavigationSource; import com.weishitech.qichechangtingyinyue.fragment.Adapter.PrivateAdapter; import com.weishitech.qichechangtingyinyue.fragment.Adapter.QyAdapter; import com.weishitech.qichechangtingyinyue.fragment.Adapter.SongTopAdapter; import com.weishitech.qichechangtingyinyue.fragment.Adapter.XzAdapter; import com.weishitech.qichechangtingyinyue.fragment.lilv.LiLvFragment; import com.weishitech.qichechangtingyinyue.utils.DisplayUtils; import com.weishitech.qichechangtingyinyue.utils.LeftGravitySnapHelper; import com.weishitech.qichechangtingyinyue.utils.MusicPlayerManager; import com.weishitech.qichechangtingyinyue.utils.OnMultiClickListener; import com.weishitech.qichechangtingyinyue.utils.RotationAnimatorHelper; import com.weishitech.qichechangtingyinyue.utils.ThemeManager; import com.weishitech.qichechangtingyinyue.view.FixedSideSnapHelper; import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import okhttp3.Call; /** * 高端语音导航首页 */ public class HomeFragment extends BaseFragment { // UI Views private RecyclerView rv, sr_rv, qy_rv, xz_rv; private ImageView iv_ss, iv_gd, sr_start, qy_start, xz_start, iv_bf; private TextView tv_time, tv_song_name; private LinearLayout line; private RelativeLayout relative,relative1,relative2,relative3; // Managers & Helpers private MusicPlayerManager playerManager; private ThemeManager themeManager; private RotationAnimatorHelper rotationHelper; private boolean isUserAuthorizedPlayback = false; // 用户是否已授权播放(点击/滑动) private boolean isMainPlaybackActive = false; // 是否由主流程控制播放状态 private int lastPlayedPosition = -1; // Data & State private SongTopAdapter songTopAdapter; private List<MusicBean.DataBean> musicDataList = new ArrayList<>(); private List<MusicBean.DataBean> privateSongList;//私人播放列表字段 private List<MusicBean.DataBean> qySongList;//轻音乐播放列表字段 private List<MusicBean.DataBean> xzSongList;//小众音乐播放列表字段 private GestureDetector gestureDetector; private PrivateAdapter privateAdapter; @Override protected int setLayout() { return R.layout.fragment_home; } @Override protected void initView() { iv_ss = fvbi(R.id.iv_ss); iv_gd = fvbi(R.id.iv_gd); iv_bf = fvbi(R.id.iv_bf); rv = fvbi(R.id.rv); sr_rv = fvbi(R.id.sr_rv); qy_rv = fvbi(R.id.qy_rv); xz_rv = fvbi(R.id.xz_rv); sr_start = fvbi(R.id.sr_start); qy_start = fvbi(R.id.qy_start); xz_start = fvbi(R.id.xz_start); tv_time = fvbi(R.id.tv_time); tv_song_name = fvbi(R.id.tv_song_name); line = fvbi(R.id.line); relative = fvbi(R.id.relative); relative1 = fvbi(R.id.relative1); relative2 = fvbi(R.id.relative2); relative3 = fvbi(R.id.relative3); // 初始化组件 playerManager = MusicPlayerManager.getInstance(); //单例获取 themeManager = new ThemeManager(); rotationHelper = new RotationAnimatorHelper(); // 跑马灯 tv_song_name.setEllipsize(TextUtils.TruncateAt.MARQUEE); tv_song_name.setSingleLine(true); tv_song_name.setSelected(true); tv_song_name.setFocusable(true); tv_song_name.setFocusableInTouchMode(true); setupGestureListener(); // 滑动手势换肤 iv_bf.setImageResource(themeManager.getPlayIconRes()); // 默认显示蓝色“播放”图标 if (NavigationSource.isDirectClick()) { NavigationSource.clear(); // 清理,防止影响下一次 } } @Override protected void initClick() { // 搜索跳转 iv_ss.setOnClickListener(v -> toClass(SearchActivity.class)); // 播放/暂停按钮 iv_bf.setOnClickListener(v -> { if (musicDataList.isEmpty()) { ToastUtil.showShortToast("暂无歌曲可播放"); return; } if (playerManager.isPlaying() && isMainPlaybackActive) { playerManager.pause(); // 如果暂停了主播放,可以视为退出主控模式(可选) isMainPlaybackActive = false; } else { isMainPlaybackActive = true; // 标记为主控模式 int pos = findBestObscuredItem(rv, DisplayUtils.dp2px(requireContext(), 50f)); if (pos == RecyclerView.NO_POSITION) pos = 0; playMusicAtPosition(pos); } updatePlayButtonIcon(); // 只有主控才更新 iv_bf }); //私人音乐播放按钮点击 sr_start.setOnClickListener(v -> playPrivateFirstSong()); //轻音乐播放按钮点击 qy_start.setOnClickListener(v -> playQingyinFirstSong()); //小众音乐播放按钮点击 xz_start.setOnClickListener(v -> playXiaoZhongFirstSong()); relative1.setOnClickListener(new OnMultiClickListener() { @Override public void onMultiClick(View v) { if (privateSongList == null || privateSongList.isEmpty()) { ToastUtil.showShortToast("暂无数据"); return; } // 标记为「非直接来源」 NavigationSource.setSource(NavigationSource.FROM_MUSIC_LIST); Bundle bundle = new Bundle(); bundle.putString("type", "私人专属好歌"); bundle.putSerializable("song_list", new ArrayList<>(privateSongList)); // 拷贝一份 toClass(MusicListActivity.class, bundle); } }); relative2.setOnClickListener(new OnMultiClickListener() { @Override public void onMultiClick(View v) { if (qySongList == null || qySongList.isEmpty()) { ToastUtil.showShortToast("暂无数据"); return; } // 标记为「非直接来源」 NavigationSource.setSource(NavigationSource.FROM_MUSIC_LIST); Bundle bundle = new Bundle(); bundle.putString("type", "轻音乐"); bundle.putSerializable("song_list", new ArrayList<>(qySongList)); toClass(MusicListActivity.class, bundle); } }); relative3.setOnClickListener(new OnMultiClickListener() { @Override public void onMultiClick(View v) { if (xzSongList == null || xzSongList.isEmpty()) { ToastUtil.showShortToast("暂无数据"); return; } // 标记为「非直接来源」 NavigationSource.setSource(NavigationSource.FROM_MUSIC_LIST); Bundle bundle = new Bundle(); bundle.putString("type", "小众音乐"); bundle.putSerializable("song_list", new ArrayList<>(xzSongList)); toClass(MusicListActivity.class, bundle); } }); } @Override protected void initData() { updateTimeGreeting(); musicAppInfo(); playerManager.setOnPlaybackStateChangedListener(new MusicPlayerManager.OnPlaybackStateChangedListener() { @Override public void onPlaying(int position) { if (!playerManager.isPlayingFromPrivate()) { updatePlayButtonIcon(); } else { String tag = playerManager.getCurrentPlaylistTag(); if ("private".equals(tag)) { int idx = playerManager.getCurrentExternalIndex(); privateAdapter.updatePlayingPosition(idx, true); updateExternalPlayButtons(); // 同步顶部按钮 } } startRotationForCurrentItem(position); } @Override public void onPaused() { if (!playerManager.isPlayingFromPrivate()) { updatePlayButtonIcon(); } else { String tag = playerManager.getCurrentPlaylistTag(); if ("private".equals(tag)) { int idx = playerManager.getCurrentExternalIndex(); privateAdapter.updatePlayingPosition(idx, false); } } rotationHelper.stopRotation(); } @Override public void onCompletion() { String currentTag = playerManager.getCurrentPlaylistTag(); if ("private".equals(currentTag)) { // 正在播放私人列表 boolean hasNext = playerManager.playNextInExternalList(); if (hasNext) { int nextIdx = playerManager.getCurrentExternalIndex(); privateAdapter.updatePlayingPosition(nextIdx, true); updateExternalPlayButtons(); } else { // 循环播放第一首 playerManager.playFromExternalList(requireContext(), privateSongList, 0, "private"); privateAdapter.updatePlayingPosition(0, true); } } // 其他 tag 可扩展(如 qingyin、xiaozhong) else { // 默认行为:播放主列表下一首 playNextSong(); } rotationHelper.stopRotation(); } @Override public void onError(String errorMsg) { ToastUtil.showShortToast(errorMsg); if (playerManager.isPlayingFromPrivate()) { privateAdapter.clearPlayingState(); } else { updatePlayButtonIcon(); } rotationHelper.stopRotation(); } }); } private void updateTimeGreeting() { Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); String greeting; if (hour >= 5 && hour < 11) greeting = "HI,早上好"; else if (hour == 11 || hour == 12 || (hour >= 13 && hour < 18)) greeting = "HI,下午好"; else greeting = "HI,晚上好"; tv_time.setText(greeting); } private void musicAppInfo() { HashMap<String, String> map = new HashMap<>(); showDialog(); HttpBuiler.getInfo(Url.music, map).build().execute( new GenericsCallback<MusicBean>(new JsonGenericsSerializator()) { @Override public void onError(Call call, Exception e, int id) { dissmiss(); ToastUtil.showShortToast(e.getMessage()); } @Override public void onResponse(MusicBean response, int id) { dissmiss(); if ("0".equals(response.getCode()) && response.getData() != null && !response.getData().isEmpty()) { musicDataList = response.getData(); // 缓存主歌单 MusicCache.setMainMusicList(musicDataList); setupMusicRecyclerView(); notifyLiLvFragmentRefresh(); } else { ToastUtil.showShortToast("暂无歌曲数据"); } } }); } private void setupMusicRecyclerView() { songTopAdapter = new SongTopAdapter(); rv.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); rv.setAdapter(songTopAdapter); // 设置播放状态回调(用于封面旋转) songTopAdapter.setOnPlayStateChangedListener((position, coverView) -> { rotationHelper.stopRotation(); rotationHelper.startRotation(coverView); }); // 必须在设置 adapter 后再初始化滚动逻辑 setupSnappingAndPlayback(rv, songTopAdapter); // 最后设置数据 songTopAdapter.setList(musicDataList); //点击top条目跳转到歌词页面 songTopAdapter.setOnItemClickListener((position, dataBean) -> { // 标记为「直接点击」来源 NavigationSource.setSource(NavigationSource.DIRECT_CLICK); // 创建 Bundle 传递数据 Bundle bundle = new Bundle(); bundle.putString("title", dataBean.getTitle()); bundle.putString("singer", dataBean.getSinger()); bundle.putString("cover_url", dataBean.getCover()); bundle.putString("music_url", dataBean.getMusic()); bundle.putString("time", dataBean.getSongTime()); bundle.putInt("position", position); bundle.putInt("total_count", musicDataList.size()); // 跳转到 LyricsActivity toClass(LyricsActivity.class, bundle); }); //私人音乐适配器 // 从第三个元素(索引=2)开始,取最多20首歌曲 int start = 3; // 第三个元素的索引 int end = Math.min(start + 20, musicDataList.size()); // 最多取20首,且不能越界 if (start >= musicDataList.size()) { privateSongList = new ArrayList<>(); // 防止越界 ToastUtil.showShortToast("起始位置超出列表范围"); } else { privateSongList = new ArrayList<>(musicDataList.subList(start, end)); } privateAdapter = new PrivateAdapter(); privateAdapter.setMainPlayButtonUpdater(isPlaying -> { Log.d("11111111",""+isPlaying); iv_bf.setImageResource(isPlaying ? themeManager.getPauseIconRes() : themeManager.getPlayIconRes()); }); // 设置点击事件:点击 item 播放该歌曲 privateAdapter.setOnItemClickListener((position, dataBean) -> { playerManager.playFromExternalList(requireContext(), privateSongList, position, "private"); playerManager.setPlayingFromPrivate(true); ToastUtil.showShortToast("播放: " + dataBean.getTitle()); }); // 设置横向 Grid 布局:每行3个 GridLayoutManager gridLayoutManager = new GridLayoutManager(requireContext(), 3, RecyclerView.HORIZONTAL, false); sr_rv.setLayoutManager(gridLayoutManager); sr_rv.setAdapter(privateAdapter); privateAdapter.setList(privateSongList); // <<< 添加吸附效果 >>> new LeftGravitySnapHelper().attachToRecyclerView(sr_rv); //轻音乐 // 确保 musicDataList 不为 null 且有数据 if (musicDataList == null || musicDataList.isEmpty()) { return; } int qystart = 5; int count = 6; int qyend = Math.min(qystart + count, musicDataList.size()); qySongList = new ArrayList<>(musicDataList.subList(qystart, qyend)); QyAdapter qyAdapter = new QyAdapter(); // 设置横向 Grid 布局:每行3个 GridLayoutManager gridLayoutManagers = new GridLayoutManager(requireContext(), 2); qy_rv.setLayoutManager(gridLayoutManagers); qy_rv.setAdapter(qyAdapter); qyAdapter.setList(qySongList); //小众音乐 // 确保 musicDataList 不为 null 且有数据 if (musicDataList == null || musicDataList.isEmpty()) { return; } int xzstart = 8; int xzcount = 6; int xzend = Math.min(xzstart + xzcount, musicDataList.size()); xzSongList = new ArrayList<>(musicDataList.subList(xzstart, xzend)); XzAdapter xzAdapter = new XzAdapter(); // 设置横向 Grid 布局:每行3个 xz_rv.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false)); xz_rv.setAdapter(xzAdapter); xzAdapter.setList(xzSongList); } private void setupSnappingAndPlayback(RecyclerView rv, SongTopAdapter adapter) { LinearLayoutManager layoutManager = (LinearLayoutManager) rv.getLayoutManager(); if (layoutManager == null) return; int fixedTargetX = DisplayUtils.dp2px(requireContext(), 50f); FixedSideSnapHelper snapHelper = new FixedSideSnapHelper(fixedTargetX); snapHelper.attachToRecyclerView(rv); AtomicInteger lastPlayedPosition = new AtomicInteger(RecyclerView.NO_POSITION); final boolean[] isFirstLayoutDone = {false}; // <<< 添加标志位 // 延迟标记“首次布局已完成” rv.post(() -> isFirstLayoutDone[0] = true); rv.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); isUserAuthorizedPlayback = true; // 关键:只有完成首次布局后才允许自动播放 if (!isFirstLayoutDone[0]) { return; } int pos = findBestObscuredItem(recyclerView, fixedTargetX); if (pos != RecyclerView.NO_POSITION && pos != lastPlayedPosition.get()) { playMusicAtPosition(pos); lastPlayedPosition.set(pos); } dispatchVisualFeedback(recyclerView, adapter); } @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); boolean isPlayingBefore = playerManager.isPlaying(); if (newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING) { if (isPlayingBefore) { playerManager.pause(); rotationHelper.stopRotation(); updatePlayButtonIcon(); } } if (newState == RecyclerView.SCROLL_STATE_IDLE && isPlayingBefore) { playerManager.resume(); startRotationForCurrentItem(playerManager.getCurrentPlayingPosition()); updatePlayButtonIcon(); } } }); setupOneWayScroll(rv, requireContext()); } private int findBestObscuredItem(RecyclerView rv, int fuzzyRightEdge) { LinearLayoutManager lm = (LinearLayoutManager) rv.getLayoutManager(); if (lm == null) return RecyclerView.NO_POSITION; int bestPos = RecyclerView.NO_POSITION; float minDiff = Float.MAX_VALUE; for (int i = 0; i < lm.getChildCount(); i++) { View child = lm.getChildAt(i); if (child == null) continue; int left = lm.getDecoratedLeft(child); int right = lm.getDecoratedRight(child); int width = right - left; if (right <= 0 || left >= fuzzyRightEdge) continue; // 无交集 int overlapStart = Math.max(left, 0); int overlapEnd = Math.min(right, fuzzyRightEdge); int overlapWidth = Math.max(0, overlapEnd - overlapStart); float coveredRatio = (float) overlapWidth / width; float diff = Math.abs(coveredRatio - 0.5f); if (coveredRatio >= 0.3f && coveredRatio <= 0.7f && diff < minDiff) { minDiff = diff; bestPos = lm.getPosition(child); } } return bestPos; } @SuppressLint("SetTextI18n") private void playMusicAtPosition(int position) { if (position == RecyclerView.NO_POSITION || position >= musicDataList.size()) return; MusicBean.DataBean bean = musicDataList.get(position); nextSkin(); // 每次播放新歌就换主题 playerManager.play(requireContext(), position, bean.getMusic()); //使用 post() 延迟更新 adapter,避免在 layout 过程中修改 rv.post(() -> { songTopAdapter.updatePlayingPosition(position); // 同时更新底部显示 tv_song_name.setText(bean.getTitle() + "-" + bean.getSinger()); ToastUtil.showShortToast("播放: " + bean.getTitle()); }); } private void playNextSong() { int nextPos = playerManager.getCurrentPlayingPosition() + 1; if (nextPos < musicDataList.size()) { playMusicAtPosition(nextPos); scrollToTriggerPosition(nextPos, rv); } else { ToastUtil.showShortToast("已播放完全部歌曲"); } } private void scrollToTriggerPosition(int targetPos, RecyclerView rv) { LinearLayoutManager lm = (LinearLayoutManager) rv.getLayoutManager(); if (lm == null) return; LinearSmoothScroller scroller = new LinearSmoothScroller(requireContext()) { @Override public PointF computeScrollVectorForPosition(int targetPosition) { return lm.computeScrollVectorForPosition(targetPosition); } @Override public int calculateDxToMakeVisible(View view, int snapPreference) { int center = (lm.getDecoratedLeft(view) + lm.getDecoratedRight(view)) / 2; int targetX = DisplayUtils.dp2px(requireContext(), 50f); return targetX - center; } @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { return 150f / displayMetrics.densityDpi; } }; scroller.setTargetPosition(targetPos); lm.startSmoothScroll(scroller); } private void dispatchVisualFeedback(RecyclerView rv, SongTopAdapter adapter) { LinearLayoutManager lm = (LinearLayoutManager) rv.getLayoutManager(); if (lm == null) return; int targetX = DisplayUtils.dp2px(requireContext(), 100f); for (int i = 0; i < rv.getChildCount(); i++) { View child = rv.getChildAt(i); if (child == null) continue; int centerX = (lm.getDecoratedLeft(child) + lm.getDecoratedRight(child)) / 2; float distance = Math.abs(centerX - targetX); if (distance > 600) continue; // float alpha = 1.0f - Math.min(1.0f, distance / 300f); // float scale = 0.8f + 0.2f * (1.0f - Math.min(1.0f, distance / 200f)); // child.setAlpha(alpha); // child.setScaleX(scale); // child.setScaleY(scale); } } private void setupOneWayScroll(RecyclerView rv, Context context) { final boolean[] hasScrolledLeft = {false}; final float[] startX = {0f}; rv.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() { @Override public boolean onInterceptTouchEvent(@NonNull RecyclerView recyclerView, @NonNull MotionEvent e) { switch (e.getAction()) { case MotionEvent.ACTION_DOWN: startX[0] = e.getX(); break; case MotionEvent.ACTION_MOVE: float dx = e.getX() - startX[0]; if (dx < -20 && !hasScrolledLeft[0]) { hasScrolledLeft[0] = true; } if (hasScrolledLeft[0] && dx > 15) { Toast.makeText(context, "暂只支持左滑操作", Toast.LENGTH_SHORT).show(); return true; } break; } return false; } }); } private void setupGestureListener() { gestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { float diffX = e2.getX() - e1.getX(); if (Math.abs(diffX) > Math.abs(e2.getY() - e1.getY())) { if (Math.abs(diffX) > 100 && Math.abs(velocityX) > 100) { nextSkin(); // 滑动换肤 return true; } } return false; } }); View.OnTouchListener touchListener = (v, event) -> gestureDetector.onTouchEvent(event); line.setOnTouchListener(touchListener); relative.setOnTouchListener(touchListener); } private void nextSkin() { themeManager.nextTheme(); applyCurrentTheme(); ToastUtil.showShortToast("切换到主题 " + (themeManager.getCurrentThemeIndex() + 1)); } private void applyCurrentTheme() { if (!isAdded()) return; // Fragment 已 detach,不执行 boolean isPlaying = playerManager.isPlaying(); themeManager.applyThemeTo(line, relative, iv_bf, isPlaying); } /** * 更新主播放按钮图标(根据实际播放状态) */ private void updatePlayButtonIcon() { if (!isAdded()) return; boolean isPlaying = playerManager.isPlaying(); iv_bf.setImageResource(isPlaying ? themeManager.getPauseIconRes() : themeManager.getPlayIconRes()); } private void startRotationForCurrentItem(int position) { // 先停止任何正在进行的动画 rotationHelper.stopRotation(); // 获取 ViewHolder RecyclerView.ViewHolder vh = rv.findViewHolderForAdapterPosition(position); if (vh == null) { // item 当前不可见,可以延迟执行或跳过 return; } ImageView coverView = vh.itemView.findViewById(R.id.iv_song_logo); if (coverView != null) { rotationHelper.startRotation(coverView); // 开始旋转 } } /** * 将所有外部播放按钮重置为“播放”状态(UI 层) */ private void resetAllExternalButtons() { sr_start.setImageResource(R.mipmap.img_bf); qy_start.setImageResource(R.mipmap.img_bf); xz_start.setImageResource(R.mipmap.img_bf); } /** * 播放私人专属歌单 */ private void playPrivateFirstSong() { if (privateSongList == null || privateSongList.isEmpty()) { ToastUtil.showShortToast("暂无私人歌曲"); return; } boolean isPlaying = playerManager.isPlaying(); boolean isFromThisList = "private".equals(playerManager.getCurrentPlaylistTag()); // 如果正在播放本列表 → 暂停,并将按钮改为“播放” if (isPlaying && isFromThisList) { playerManager.pause(); sr_start.setImageResource(R.mipmap.img_bf); // 主动改为“播放” ToastUtil.showShortToast("已暂停"); return; } // 如果已暂停本列表(tag 匹配但未播放)→ 继续播放 if (!isPlaying && isFromThisList) { playerManager.resume(); sr_start.setImageResource(R.mipmap.img_zt); // 主动改为“暂停” privateAdapter.updatePlayingPosition(playerManager.getCurrentExternalIndex(), true); ToastUtil.showShortToast("继续播放: " + privateSongList.get(playerManager.getCurrentExternalIndex()).getTitle()); return; } // ★★★ 新播放:不是本列表 → 先重置所有按钮 resetAllExternalButtons(); // 开始新播放 playerManager.playFromExternalList(requireContext(), privateSongList, 0, "private"); playerManager.setPlayingFromPrivate(true); // 更新 UI privateAdapter.updatePlayingPosition(0, true); sr_start.setImageResource(R.mipmap.img_zt); // 设为“暂停” ToastUtil.showShortToast("播放私人歌曲: " + privateSongList.get(0).getTitle()); updatePlayButtonIcon(); // iv_bf 变成“暂停”图标 } /** * 播放轻音乐歌单 */ private void playQingyinFirstSong() { if (qySongList == null || qySongList.isEmpty()) { ToastUtil.showShortToast("暂无轻音乐"); return; } boolean isPlaying = playerManager.isPlaying(); boolean isFromThisList = "qingyin".equals(playerManager.getCurrentPlaylistTag()); // 如果正在播放本列表 → 暂停,并将按钮改为“播放” if (isPlaying && isFromThisList) { playerManager.pause(); qy_start.setImageResource(R.mipmap.img_bf); // ✅ 主动改为“播放” ToastUtil.showShortToast("已暂停"); return; } // 如果已暂停本列表 → 继续播放,按钮变“暂停” if (!isPlaying && isFromThisList) { playerManager.resume(); qy_start.setImageResource(R.mipmap.img_zt); // ✅ 主动改为“暂停” ToastUtil.showShortToast("继续播放: " + qySongList.get(0).getTitle()); return; } // ★★★ 新播放:不是本列表 → 先重置所有按钮 resetAllExternalButtons(); // 开始播放 playerManager.playFromExternalList(requireContext(), qySongList, 0, "qingyin"); playerManager.setPlayingFromPrivate(true); // 更新 UI qy_start.setImageResource(R.mipmap.img_zt); // 设为“暂停” rotationHelper.stopRotation(); MusicBean.DataBean firstSong = qySongList.get(0); ToastUtil.showShortToast("播放轻音乐: " + firstSong.getTitle()); updatePlayButtonIcon(); // iv_bf 变成“暂停”图标 } /** * 播放小众歌单 */ private void playXiaoZhongFirstSong() { if (xzSongList == null || xzSongList.isEmpty()) { ToastUtil.showShortToast("暂无小众歌曲"); return; } boolean isPlaying = playerManager.isPlaying(); boolean isFromThisList = "xiaozhong".equals(playerManager.getCurrentPlaylistTag()); // 如果正在播放本列表 → 暂停 if (isPlaying && isFromThisList) { playerManager.pause(); xz_start.setImageResource(R.mipmap.img_bf); ToastUtil.showShortToast("已暂停"); return; } // 如果已暂停本列表 → 继续播放 if (!isPlaying && isFromThisList) { playerManager.resume(); xz_start.setImageResource(R.mipmap.img_zt); ToastUtil.showShortToast("继续播放: " + xzSongList.get(0).getTitle()); return; } // 新播放 → 重置所有按钮 resetAllExternalButtons(); // 开始播放 playerManager.playFromExternalList(requireContext(), xzSongList, 0, "xiaozhong"); playerManager.setPlayingFromPrivate(true); // 更新 UI xz_start.setImageResource(R.mipmap.img_zt); rotationHelper.stopRotation(); ToastUtil.showShortToast("播放小众歌曲: " + xzSongList.get(0).getTitle()); updatePlayButtonIcon(); // iv_bf 变成“暂停”图标 } /** * 根据当前播放状态和来源,同步更新所有外部播放按钮的图标 */ private void updateExternalPlayButtons() { boolean isPlaying = playerManager.isPlaying(); String currentTag = playerManager.getCurrentPlaylistTag(); // 私人专属 if (isPlaying && "private".equals(currentTag)) { sr_start.setImageResource(R.mipmap.img_zt); } else { sr_start.setImageResource(R.mipmap.img_bf); } // 轻音乐 if (isPlaying && "qingyin".equals(currentTag)) { qy_start.setImageResource(R.mipmap.img_zt); } else { qy_start.setImageResource(R.mipmap.img_bf); } // 小众音乐 if (isPlaying && "xiaozhong".equals(currentTag)) { xz_start.setImageResource(R.mipmap.img_zt); } else { xz_start.setImageResource(R.mipmap.img_bf); } } @Override public void onDestroy() { // playerManager.release(); rotationHelper.stopRotation(); super.onDestroy(); } @Override public void onResume() { super.onResume(); Log.d("HomeFragment", "onResume called, source = " + NavigationSource.getSource()); // 只有是从「直接点击」进入 LyricsActivity 再返回,才执行以下逻辑 if (NavigationSource.isDirectClick()) { updatePlayButtonIcon(); applyCurrentTheme(); if (playerManager.isPlaying() && !playerManager.isPlayingFromPrivate()) { int currentPos = playerManager.getCurrentPlayingPosition(); syncToCurrentPlayingItem(currentPos); } // 可选:清除标记,避免下次误判 NavigationSource.clear(); } else { // 其他路径返回,不执行自动滚动和高亮 updatePlayButtonIcon(); // 至少更新按钮状态 Log.d("HomeFragment", "非直接路径返回,跳过 syncToCurrentPlayingItem"); } } /** * 滚动并高亮当前正在播放的歌曲 */ private void syncToCurrentPlayingItem(int position) { if (songTopAdapter == null || rv == null || musicDataList == null || position >= musicDataList.size()) { return; } LinearLayoutManager layoutManager = (LinearLayoutManager) rv.getLayoutManager(); if (layoutManager == null) return; // 目标 x 坐标:距离左边 50dp int targetX = DisplayUtils.dp2px(requireContext(), 50f); LinearSmoothScroller scroller = new LinearSmoothScroller(requireContext()) { @Override public PointF computeScrollVectorForPosition(int targetPosition) { return layoutManager.computeScrollVectorForPosition(targetPosition); } @Override public int calculateDxToMakeVisible(View view, int snapPreference) { // 正确调用:通过 layoutManager 调用 int left = layoutManager.getDecoratedLeft(view); int right = layoutManager.getDecoratedRight(view); int center = (left + right) / 2; // 返回需要移动的距离 return targetX - center; } @Override protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) { // 控制滚动速度:越小越快 return 100f / displayMetrics.densityDpi; // 可调 } }; scroller.setTargetPosition(position); layoutManager.startSmoothScroll(scroller); // 延迟查找 ViewHolder 并启动旋转 rv.postDelayed(() -> { RecyclerView.ViewHolder vh = rv.findViewHolderForAdapterPosition(position); if (vh != null) { ImageView coverView = vh.itemView.findViewById(R.id.iv_song_logo); if (coverView != null) { rotationHelper.stopRotation(); rotationHelper.startRotation(coverView); } } }, 350); // 等待滚动接近完成 } private void notifyLiLvFragmentRefresh() { // 假设你通过某种方式获取到 LiLvFragment 实例 // 方法一:通过 Activity 管理 Fragment lilvFragment = getParentFragmentManager().findFragmentByTag("LILV_FRAGMENT"); if (lilvFragment instanceof LiLvFragment) { ((LiLvFragment) lilvFragment).refreshData(); } } } package com.weishitech.qichechangtingyinyue.fragment.home; import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; import com.hfd.common.base.BaseActivity; import com.weishitech.qichechangtingyinyue.R; import com.weishitech.qichechangtingyinyue.fragment.Adapter.SectionsPagerAdapter; public class SearchActivity extends BaseActivity { private ViewPager2 viewPager; private TabLayout tabLayout; @Override protected int setLayout() { return R.layout.activity_search; } @Override protected void setView() { tabLayout = fvbi(R.id.tab_layout); viewPager = fvbi(R.id.view_pager); } @Override protected void setData() { // 设置适配器 SectionsPagerAdapter adapter = new SectionsPagerAdapter(this); viewPager.setAdapter(adapter); // 允许预加载相邻页面(保持它们活跃) viewPager.setOffscreenPageLimit(1); // 设置 PageMargin 和 PageTransformer 实现“露出三分之一” viewPager.setPageTransformer((page, position) -> { float width = page.getWidth(); float offset = position * (width * 0.2f); // 控制偏移量 page.setTranslationX(-offset); }); // 将 TabLayout 与 ViewPager2 绑定 new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> { tab.setText(adapter.getTitle(position)); }).attach(); } @Override protected void setClick() { } }点击fragment页面iv_ss控件把fragment页面的privateSongList和qySongList传到SearchActivity
最新发布
12-05
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值