Skip to content
景彬 edited this page Oct 29, 2021 · 11 revisions

CloudReader - 云阅

  一款基于网易云音乐UI,使用GankIo及豆瓣api开发的符合Google Material Desgin阅读类的开源项目。项目采取的是Retrofit + RxJava + MVVM-DataBinding架构开发。

2015年1月16日,网易云音乐荣膺百度中国好应用“年度优秀视觉设计奖”。这是一个跨 iPhone、Android、Web、PC、iPad、WP8、Mac、Win10UWP、Linux九大平台的音乐客户端。针对不同的平台有不同的设计规则,就我所知,Android版本基本符合Material Desgin设计原则,可以说的上是行业典范;IOS也针对其系统有另一套设计,如典型化的底部四个菜单按钮。

这里主要记录项目的细节优化~

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>

这样就得到了我们想要的效果~

侧边栏上的MaterialDesign

参考Material Desgin中文文档介绍,对于侧边栏也就是文档里的边框,有一套推荐的尺寸。值得注意的是Google只是推荐使用这套设计风格,意思是,如果你没有更好的UI设计,尽量按这套设计风格来做。我觉得网易云音乐是青出于蓝而胜于蓝,打破规则的前提是理解规则。

说了这么多废话,进入正题~

首先看官方推荐尺寸: 边框

然后大家可以对照着查看网易云音乐的侧边栏布局,就会发现,基本遵循了,而且还优化一下,对于头像部分显示太高,反而感觉不太搭配。当然这只是我一名Android程序员的愚见,哈哈。

元素

当时布局的时候只是猜他的尺寸,后来想到去参考官方的设计规则来设计,使用了官方的尺寸后再看效果,发现基本和网易云音乐的侧边栏一致了。

网易云音乐的侧边栏效果:

wangyi.png

自己实现的侧边栏效果:

yunyue.png

其中,头部的背景高度和背景透明度都有微调。才能达到舒适的效果(无耻的暴露了id(~ ̄▽ ̄)~)。