zoukankan      html  css  js  c++  java
  • 《云阅》一个仿网易云音乐UI,使用Gank.Io及豆瓣Api开发的开源项目

    CloudReader

    一款基于网易云音乐UI,使用GankIo及豆瓣api开发的符合Google Material Desgin阅读类的开源项目。项目采取的是Retrofit + RxJava + MVVM-DataBinding架构开发。开发中所遇到的各种问题已归纳在这里

    github地址:CloudReader

    效果图

    • 部分效果图

    cloudreader.png
    • gif演示

    cloudreader.gif

    Introduction

    网易云音乐于2013年4月23日正式发布,是一款主打发现和分享,带有浓厚社交基因的网络音乐产品。相信用过的人都知道它给人的体验是极好的,我看过了绝大多数仿写的案例,基本UI都不够细致,于是决定自己动手写一个,起初也不知道具体它是怎么布局的,后来使用SDK提供的工具uiautomatorviewer慢慢分析后再逐渐完善的,争取效果一致~

    模块分析

    干货(gank.io)

    API使用的是动听(轮播图)和代码家的Gank.Io。

    • 每日推荐: 干货集中营推送的每日内容,包括每天一个妹子图,相关Android、IOS等其他干货。每天第12:30之后更新,因为双休不更新所以内容缓存三天网络取不到就取缓存。

    • 福利: Glide加载图片,点击查看大图,支持双指缩放,一下可查看列表的所有图片,再也不用逐个点击每张图啦。

    • 干货订制: 可以筛选自己喜欢干货的类别,有全部、IOS、App、前端、休息视频和拓展资源。

    • 大安卓: 显示安卓的全部资讯。支持下拉刷新方便查看最新的资源。

    电影(豆瓣)

    API是豆瓣提供的,因为限制了每个ip每分钟请求的次数,所以请酌情使用,由此带来的不便请见谅。

    • 电影热映区: 每日更新,展示最新上映的电影热度排行榜。
    • 豆瓣电影Top250: 豆瓣高分电影集锦,让你放心找好片~

    书籍(豆瓣)

    使用的是豆瓣的搜索API。更多订制内容由于时间原因第一版还未添加,第二版会加上。

    • 综合: 检索豆瓣综合类的书籍并展示。
    • 文学: 检索豆瓣文学类的书籍并展示。
    • 生活: 检索豆瓣生活类的书籍并展示。

    抽屉界面

    完全仿网易云音乐抽屉界面,包括诸多细节如透明标题栏,背景透明度,水波纹颜色等。

    • 项目主页:展示项目介绍信息,及内容说明,可以分享给你的好友哦。
    • 扫码下载:扫码即可下载App,帮助您快速试用~
    • 问题反馈:常见问题归纳,反馈地方,联系方式都在这里哦!
    • 关于云阅:更新日志在这里可见,主人是利用工作外时间做的,周期较长,满意的小伙伴给个Star吧,这将是我继续迭代的动力,谢谢~

    What can be learned about this project

    那么,从本项目中你能学到哪些知识呢?

    • 1、干货集中营内容与豆瓣电影书籍内容。
    • 2、高仿网易云音乐歌单详情页。
    • 3、NavigationView搭配DrawerLayout的具体使用。
    • 4、MvvM-DataBing的项目应用。
    • 5、RxBus代替EventBus进行组件之间通讯。
    • 6、ToolBarTabLayout的使用姿势。
    • 7、Glide加载监听,获取缓存,圆角图片,高斯模糊。
    • 8、水波纹点击效果详细使用与适配。
    • 9、RecyclerView下拉刷新上拉加载。
    • 10、基于DataBindingViewHolder
    • 11、基于DataBindingBaseActivityBaseFragment
    • 12、Fragment懒加载模式。
    • 13、透明状态栏使用与版本适配。
    • 14、SwipeRefreshLayout结合RecyclerView下拉刷新上拉加载。
    • 15、CoordinatorLayout + Behavior实现标题栏渐变。
    • 16、NestedScrollView嵌套RecyclerView的使用。

    细节分析 - ToolBar 上的按钮点击效果

    仔细研究的人知道,网易云音乐的UI做的很精致,就拿一个ToolBar为例,上面的每个按钮的点击操作都有各自的效果。这给了用户一个很好的反馈,就是如下的效果:


    toolbar_click.gif

    上图是在android 5.1系统下的效果图。在6.0上搜索的点击效果有些许改变,其他基本类似;5.0以下点击则都表现出一般选择器的效果。

    然而做到以上的效果并不容易,需要你对ToolBar有深入的了解;不仅如此,水波纹的点击效果在不同的主题下是有不同的表现。下面一起来谈谈如何达到以上的效果。

    关于ToolBar的布局

    看到上图我们了解到一个ToolBar上有三种点击效果..

    这就有点尴尬了..不急,我们慢慢来分析。利用SDK下的工具uiautomatorviewer可得知:左边的菜单按钮是ToolBar内部包裹的一个Fragment,其中是一个ImageView和一个小红点;然后中间是HorizontalScrollView,其中是三个ImageView;右边的搜索键则是通过设置Menu菜单而来,这样会有长按弹出“搜索”二字的提示。

    现总结出两个问题:1、ToolBar上按钮的设置;2、不同按钮点击的水波纹效果

    对于1: ToolBar上按钮的设置

    些许研究了ToolBar的使用后得知,可以直接在其内部包裹Imageview外,还可以通过菜单文件设置:

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }

    其中,main.xml内容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:id="@+id/action_search"
            android:icon="@drawable/actionbar_search"// 显示图标
            android:orderInCategory="100"// 菜单显示优先级
            android:title="@string/actionbar_search"// Toast文字“搜索”
            app:showAsAction="always" />// 总是显示,其中还有"never"点击后弹出显示;``ifRoom``根据空间判断是否显示
    </menu>

    然后再找到菜单相应的id处理点击事件:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_search:
    //                Toast.makeText(this, "打开搜索页面", Toast.LENGTH_SHORT).show();
                    return true;
                default:
                    return super.onOptionsItemSelected(item);
            }
     }

    这样就完成了两者点击效果不同的处理。

    对于2:不同按钮点击的水波纹效果

    这里不是使用ripple属性了,而是使用系统自带的点击水波纹选择器,给要产生点击效果的控件设置:

    android:background="?attr/selectableItemBackgroundBorderless"

    然而设置后你会发现所有点击的颜色都是一致的,如果你使用主题:

    theme="@style/Theme.AppCompat.Light.NoActionBar"

    点击效果就会全部是黑灰的,就是中间三个按钮的那种效果,如果想要点击效果是白色的话,需要设置主题:

    theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

    知道这样后我们给不同的布局设置不同的主题就解决了这个问题。最终布局文件:

    <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/colorTheme"
            app:contentInsetStart="0.0dp"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    
            <FrameLayout
                android:id="@+id/ll_title_menu"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:background="?attr/selectableItemBackgroundBorderless"
                android:paddingLeft="15dp"
                android:paddingRight="15dp">
    
                <ImageView
                    android:id="@+id/iv_title_menu"
                    android:layout_width="23dp"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:src="@drawable/titlebar_menu" />
            </FrameLayout>
    
            <HorizontalScrollView
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_gravity="center">
    
                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    app:theme="@style/Theme.AppCompat.Light.NoActionBar">
    
                    <ImageView
                        android:id="@+id/iv_title_gank"
                        android:layout_width="55dp"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:background="?attr/selectableItemBackgroundBorderless"
                        android:src="@drawable/titlebar_disco" />
    
                    <ImageView
                        android:id="@+id/iv_title_one"
                        android:layout_width="55dp"
                        android:layout_height="match_parent"
                        android:background="?attr/selectableItemBackgroundBorderless"
                        android:src="@drawable/titlebar_music" />
    
                    <ImageView
                        android:id="@+id/iv_title_dou"
                        android:layout_width="55dp"
                        android:layout_height="match_parent"
                        android:background="?attr/selectableItemBackgroundBorderless"
                        android:src="@drawable/titlebar_friends" />
    
                </LinearLayout>
    
            </HorizontalScrollView>
    
     </android.support.v7.widget.Toolbar>

    这样就得到了我们想要的效果~
    更多细节优化我会慢慢整理在Wiki文档,或你也可以直接查看源代码。

    DownLoad

     火速跳转


    download.png

    宝贵意见

    如果有任何问题,请到github的issue处写上你不明白的地方,也可以通过下面提供的方式联系我,我会及时给予帮助。另外常见的问题已总结在这里

    Thanks

    Statement

    感谢网易云音乐App提供参考,附上《网易云音乐Android 3.0视觉设计规范文档》。本人是网易云音乐的粉丝,使用了其中的部分素材,并非攻击,如构成侵权请及时通知我修改或删除。大部分数据来自于干货集中营和豆瓣APIV2.0,一切数据解释权都归代码家和豆瓣所有。

    End

    如果你觉得不错,对你有帮助,可以帮忙分享给你更多的朋友,这是给我们最大的动力与支持,同时希望你多多fork,star,follow,我将贡献更多的开源项目O(∩_∩)O~。开源使生活更美好!

    About me

  • 相关阅读:
    Java锁到底锁的到底是哪个对象?什么是锁对象
    什么是正向代理,什么是反向代理
    到底什么是线程安全
    为什么要使用接口,直接写是实现类不行吗
    Nginx配置学习(一)
    Zookeeper集群节点数量为什么要是奇数个?
    Redis 5 单实例数据迁移到Cluster
    Centos8安装Nginx1.18.0
    vmware workstation15 桥接模式互ping不通,虚机可以连通局域网其他机器解决方法
    MongoDB double类型保留2位小数
  • 原文地址:https://www.cnblogs.com/ldq2016/p/6264454.html
Copyright © 2011-2022 走看看