Android實現網易雲音樂高仿版流程
效果圖
效果圖依次為發現界面頂部,包含首頁輪播圖,水平滾動的按鈕,推薦歌單;然後是發現界面推薦單曲,點擊單曲就是直接進入播放界面;最後是全局播放控制條上點擊播放列表按鈕顯示的播放列表彈窗。
整體分析
整體使用RecycerView實現,每個不同的塊是一個Item,例如:輪播圖是一個Item,按鈕也是,推薦歌單和下面的歌單是,推薦單曲,還有最後的自定義首頁那塊也是一樣。
提示:之所以把推薦歌單下面的歌單和推薦歌單標題放一個Item,主要是首頁要實現自定義順序功能,更方便管理。
輪播圖
佈局
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_height="wrap_content" android:layout_margin="@dimen/padding_outer"> <com.youth.banner.Banner android:id="@+id/banner" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintDimensionRatio="H,0.389" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
顯示數據
//banner BannerData data = (BannerData) d; Banner bannerView = holder.getView(R.id.banner); BannerImageAdapter<Ad> bannerImageAdapter = new BannerImageAdapter<Ad>(data.getData()) { @Override public void onBindView(BannerImageHolder holder, Ad data, int position, int size) { ImageUtil.show(getContext(), (ImageView) holder.itemView, data.getIcon()); } }; bannerView.setAdapter(bannerImageAdapter); bannerView.setOnBannerListener(onBannerListener); bannerView.setBannerRound(DensityUtil.dip2px(getContext(), 10)); //添加生命周期觀察者 bannerView.addBannerLifecycleObserver(fragment); bannerView.setIndicator(new CircleIndicator(getContext()));
按鈕
佈局
<?xml version="1.0" encoding="utf-8"?> <HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingVertical="@dimen/padding_outer" android:scrollbars="none"> <LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingHorizontal="@dimen/padding_meddle"> </LinearLayout> </HorizontalScrollView>
顯示數據
LinearLayout container = holder.getView(R.id.container); if (container.getChildCount() > 0) { //已經添加瞭 return; } //橫向顯示5個半 float containerWidth = ScreenUtil.getScreenWith(container.getContext()) - DensityUtil.dip2px(container.getContext(), 10 * 2); int itemWidth = (int) (containerWidth / 5.5); DiscoveryButtonBinding binding; LinearLayout.LayoutParams layoutParams; for (IconTitleButtonData it : data.getData()) { binding = DiscoveryButtonBinding.inflate(LayoutInflater.from(getContext())); binding.icon.setImageResource(it.getIcon()); binding.title.setText(it.getTitle()); if (it.getIcon() == R.drawable.day_recommend) { SuperViewUtil.show(binding.more); //顯示日期 binding.more.setText(String.valueOf(SuperDateUtil.currentDay())); } //設置點擊事件 binding.getRoot().setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); layoutParams = new LinearLayout.LayoutParams(itemWidth, ViewGroup.LayoutParams.WRAP_CONTENT); container.addView(binding.getRoot(), layoutParams); }
推薦歌單
佈局
<?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" android:orientation="vertical"> <include layout="@layout/item_discovery_title" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingHorizontal="@dimen/padding_outer" android:paddingBottom="@dimen/d5" /> </LinearLayout>
顯示數據
private void bindSheetData(BaseViewHolder holder, SheetData data) { //設置標題,將標題放到每個具體的item上,好處是方便整體排序 holder.setText(R.id.title, R.string.recommend_sheet); //顯示更多容器 holder.setVisible(R.id.more, true); holder.getView(R.id.more).setOnClickListener(v -> { }); RecyclerView listView = holder.getView(R.id.list); if (listView.getAdapter() == null) { //設置顯示3列 GridLayoutManager layoutManager = new GridLayoutManager(listView.getContext(), 3); listView.setLayoutManager(layoutManager); sheetAdapter = new SheetAdapter(R.layout.item_sheet); //item點擊 sheetAdapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) { if (discoveryAdapterListener != null) { discoveryAdapterListener.onSheetClick((Sheet) adapter.getItem(position)); } } }); listView.setAdapter(sheetAdapter); GridDividerItemDecoration itemDecoration = new GridDividerItemDecoration(getContext(), (int) DensityUtil.dip2px(getContext(), 5F)); listView.addItemDecoration(itemDecoration); } sheetAdapter.setNewInstance(data.getData()); }
底部
佈局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginVertical="@dimen/padding_outer" android:gravity="center_horizontal" android:orientation="vertical"> <androidx.appcompat.widget.LinearLayoutCompat android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical"> <TextView android:id="@+id/refresh_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableLeft="@drawable/refresh" android:gravity="center_vertical" android:text="@string/click_refresh" android:textColor="@color/link" android:textSize="@dimen/text_small" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="@dimen/padding_small" android:text="@string/change_content" android:textColor="@color/black80" android:textSize="@dimen/text_small" /> </androidx.appcompat.widget.LinearLayoutCompat> <com.google.android.material.button.MaterialButton android:id="@+id/custom" style="@style/Widget.MaterialComponents.Button.UnelevatedButton" android:layout_width="wrap_content" android:layout_height="@dimen/d30" android:layout_marginTop="@dimen/padding_outer" android:backgroundTint="?attr/colorSurface" android:insetTop="0dp" android:insetBottom="0dp" android:text="@string/custom_discovery" android:textColor="@color/black80" android:textSize="@dimen/text_small" app:cornerRadius="@dimen/d15" app:elevation="0dp" app:strokeColor="@color/black80" app:strokeWidth="@dimen/d0_5" /> </LinearLayout>
顯示數據
holder.getView(R.id.refresh_button).setOnClickListener(v -> discoveryAdapterListener.onRefreshClick()); holder.getView(R.id.custom).setOnClickListener(v -> discoveryAdapterListener.onCustomDiscoveryClick());
迷你控制條
他是一個自定義Fragment,哪裡要顯示就放到哪裡就行瞭。
播放列表彈窗
/** * 播放列表對話框 */ public class MusicPlayListDialogFragment extends BaseViewModelBottomSheetDialogFragment<FragmentDialogAudioPlayListBinding> { ... @Override protected void initListeners() { super.initListeners(); //刪除所有按鈕點擊 binding.deleteAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //關閉對話框 dismiss(); //刪除全部音樂 getMusicListManager().deleteAll(); } }); //item中子控件點擊 //刪除按鈕點擊 adapter.addChildClickViewIds(R.id.delete); adapter.setOnItemChildClickListener(new OnItemChildClickListener() { @Override public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) { //由於這裡隻有一個按鈕點擊 //所以可以不判斷 if (R.id.delete == view.getId()) { //刪除按鈕點擊 removeItem(position); } } }); //循環模式點擊 binding.loopModel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //更改循環模式 getMusicListManager().changeLoopModel(); //顯示循環模式 showLoopModel(); } }); //設置item點擊事件 adapter.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(BaseQuickAdapter adapter, View view, int position) { //關閉dialog //可以根據具體的業務邏輯來決定是否關閉 dismiss(); //播放點擊的這首音樂 getMusicListManager().play(getMusicListManager().getDatum().get(position)); } }); } private void removeItem(int position) { adapter.removeAt(position); //從列表管理器中刪除 getMusicListManager().delete(position); showCount(); } /** * 顯示循環模式 */ private void showLoopModel() { PlayListUtil.showLoopModel(getMusicListManager().getLoopModel(), binding.loopModel); } private void showCount() { binding.count.setText(String.format("(%d)", getMusicListManager().getDatum().size())); } }
到此這篇關於Android實現網易雲音樂高仿版流程的文章就介紹到這瞭,更多相關Android網易雲音樂內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Android MVVM架構實現RecyclerView列表詳解流程
- RecyclerView實現橫向滾動效果
- Android利用SoundPool實現音樂池
- Android用viewPager2實現UI界面翻頁滾動的效果
- Android ListView仿微信聊天界面