效果图

效果图依次为发现界面顶部,包含首页轮播图,水平滚动的按钮,推荐歌单;然后是发现界面推荐单曲,点击单曲就是直接进入播放界面;最后是全局播放控制条上点击播放列表按钮显示的播放列表弹窗。
整体分析
整体使用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网易云音乐内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!