0.效果图

效果图依次为发现界面顶部,包含首页轮播图,水平滚动的按钮,推荐歌单;然后是发现界面推荐单曲,点击单曲就是直接进入播放界面;最后是全局播放控制条上点击播放列表按钮显示的播放列表弹窗。

1.整体分析

整体使用RecycerView实现,每个不同的块是一个Item,例如:轮播图是一个Item,按钮也是,推荐歌单和下面的歌单是,推荐单曲,还有最后的自定义首页那块也是一样。

提示:之所以把推荐歌单下面的歌单和推荐歌单标题放一个Item,主要是首页要实现自定义顺序功能,更方便管理。

2.轮播图

2.1 布局

<?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.Bannerandroid: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>

2.2 显示数据

//banner
BannerData data = (BannerData) d;Banner bannerView = holder.getView(R.id.banner);BannerImageAdapter<Ad> bannerImageAdapter = new BannerImageAdapter<Ad>(data.getData()) {@Overridepublic 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()));

按钮

3.1 布局

<?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"><LinearLayoutandroid:id="@+id/container"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:paddingHorizontal="@dimen/padding_meddle"></LinearLayout>
</HorizontalScrollView>

3.2 显示数据

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() {@Overridepublic void onClick(View v) {}});layoutParams = new LinearLayout.LayoutParams(itemWidth, ViewGroup.LayoutParams.WRAP_CONTENT);container.addView(binding.getRoot(), layoutParams);
}

4.推荐歌单

4.1 布局

<?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.RecyclerViewandroid:id="@+id/list"android:layout_width="match_parent"android:layout_height="wrap_content"android:paddingHorizontal="@dimen/padding_outer"android:paddingBottom="@dimen/d5" />
</LinearLayout>

4.2 显示数据

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() {@Overridepublic 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());
}

5. 底部

5.1 布局

<?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.LinearLayoutCompatandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_vertical"><TextViewandroid: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" /><TextViewandroid: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.MaterialButtonandroid: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>

5.2 显示数据

holder.getView(R.id.refresh_button).setOnClickListener(v -> discoveryAdapterListener.onRefreshClick());
holder.getView(R.id.custom).setOnClickListener(v -> discoveryAdapterListener.onCustomDiscoveryClick());

6.迷你控制条

他是一个自定义Fragment,哪里要显示就放到哪里就行了。

7.播放列表弹窗

/*** 播放列表对话框*/
public class MusicPlayListDialogFragment extends BaseViewModelBottomSheetDialogFragment<FragmentDialogAudioPlayListBinding> {...@Overrideprotected void initListeners() {super.initListeners();//删除所有按钮点击binding.deleteAll.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//关闭对话框dismiss();//删除全部音乐getMusicListManager().deleteAll();}});//item中子控件点击//删除按钮点击adapter.addChildClickViewIds(R.id.delete);adapter.setOnItemChildClickListener(new OnItemChildClickListener() {@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {//由于这里只有一个按钮点击//所以可以不判断if (R.id.delete == view.getId()) {//删除按钮点击removeItem(position);}}});//循环模式点击binding.loopModel.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//更改循环模式getMusicListManager().changeLoopModel();//显示循环模式showLoopModel();}});//设置item点击事件adapter.setOnItemClickListener(new OnItemClickListener() {@Overridepublic 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()));}
}

感谢你的阅读,更多文章请关注我们,点击,评论,转发支持。

3.Android高仿网易云音乐-首页复杂发现界面布局和功能相关推荐

  1. Android高仿网易云音乐OkHttp+Retrofit+RxJava+Glide+MVC+MVVM

    简介 这是一个使用Java(以后还会推出Kotlin版本)语言,从0开发一个Android平台,接近企业级的项目(我的云音乐),包含了基础内容,高级内容,项目封装,项目重构等知识:主要是使用系统功能, ...

  2. 2.Android高仿网易云音乐-引导界面和广告界面实现

    效果图 效果图依次为图片广告,视频广告,引导界面. 系列文章目录导航 目录 1.实现分析 广告界面就是显示图片和视频,所以可以放一个图片控件,视频控件,然后跳过按钮,提示按钮,WiFi预加载提示都是放 ...

  3. 1.Android高仿网易云音乐-启动界面实现和动态权限处理

    0.效果 效果图依次为启动界面,第一次显示用户协议对话框,动态获取权限. 系列文章目录导航 目录 1.实现分析 启动基本上没有什么难点,但在真实项目逻辑还是比较多:就是布局,然后显示用户协议对话框,动 ...

  4. Android高仿网易云音乐播放界面

    现在很多的播放器的播放界面都是采用光盘的转动,下面是我仿造网易的播放界面.先上两张图: 第一张为播放前的界面,第二张为点击播放按钮的图片.布局文件如下: <RelativeLayout xmln ...

  5. android 仿网易标签切换,高仿网易云音乐客户端的Home页面切换Tabhost-IT蓝豹

    1.高仿网易云音乐客户端的Home页面切换Tabhost 高仿网易云音乐客户端的Home页面切换Tabhost,并且三角形是透明的, 实现方式,自定义AnimTabsView继承 RelativeLa ...

  6. Flutter+FishRedux高仿网易云音乐

    flutter_netease_cloud_music 采用FishRedux框架与开源网易云音乐api开发的高仿网易云音乐APP,技术栈主要是:Flutter+FishRedux,目前主要是偏重AP ...

  7. 新鲜出炉高仿网易云音乐 APP

    我的引语 晚上好,我是吴小龙同学,我的公众号「菜鸟翻身」会推荐 GitHub 上好玩的项目,一分钟 get 一个优秀的开源项目,挖掘开源的价值,欢迎关注我. 项目中成长是最快的,如何成长,就是解决问题 ...

  8. Vue3.0 + typescript 高仿网易云音乐 WebApp

    Vue3.0 + typescript 高仿网易云音乐 WebApp 前言 Vue3.0 的正式发布,让我心动不已,于是尝试用 vue3 实现一个完整的项目,整个项目全部使用了 composition ...

  9. 高仿网易云音乐(vue实战项目)

    高仿网易云音乐(Vue实战项目)

最新文章

  1. mac终端python不能显示中文_Matplotlib为Mac显示中文,ForMac
  2. python每隔2s执行一次hello world!
  3. 安装python3.7和PyCharm专业版
  4. apache配置CA证书通过https通信
  5. 换个视角看中台的对与错
  6. snowflake 使用_如何使用机器学习模型直接从Snowflake进行预测
  7. 欢迎使用CSDN-markdown编辑器111
  8. 使用etop查看系统中进程信息
  9. EJB3.0学习笔记---Bean实现多个接口的情况下定义,访问方式:
  10. 大数据思维与技术——中国大学MOOC课程笔记
  11. php如何开发阅读器,微信小程序阅读器的简单实例开发
  12. 如何查找一篇论文的源代码
  13. 怎么注册自定义域名Email.cn邮箱?
  14. 周爱民对提升程序员自身技术能力的建议
  15. 关于显示器,神马ips、pls、tn的
  16. JavaScript 动态表格操作
  17. 在 Win7 下安装 KB4512506 补丁报告 0x80092004 错误的解决办法
  18. react笔记_07组件实例化对象的三大属性
  19. 华为v5服务器raid设置系统,华为服务器2288hv5raid阵列卡制作
  20. 中国碳酸氢钠市场趋势报告、技术动态创新及市场预测

热门文章

  1. 柚子壁纸为什么自动安装_火爆抖音的时间罗盘壁纸,iPhone和安卓都支持!
  2. Android特效View之二之 闪闪发光Shimmer字体特效
  3. java多个pdf合成一个pdf
  4. 视频调度指挥系统服务器,非常实用的应急指挥中心的视频系统设计方案
  5. ffmpeg 中 -f <format> 字段的意义
  6. 基于RabbitMQ 的 Web MQTT插件进行前端消息实时推送
  7. 电磁波空间传播损耗公式
  8. 东北大学最优化方法与理论第一章知识点总结——预备知识
  9. Fluent软件并行效率测试
  10. java吞食天地中武将_《吞食天地2:重制版》各武将特点及心得