Material Design & Android 5

最近研究了一下Material Design和Android 5的新特性,这里做下总结归纳。

Material Design在我认为就是类似于卡片一样的设计,当然并不只是卡片,material design可以把一个布局或者控件当做实际生活中得一个卡片来对待。

那么具有以下几个方面的属性(具体参照http://www.google.com/design/spec/material-design/introduction.html 上面某些效果看起来还是挺炫的):

  1. 物理属性——卡片是三维的,在z坐标上只有1dp厚;具有投影,不同高度的投影效果不一样;任何颜色、形状和内容都可以在material上显示且不增加厚度;卡片之间不能相互重叠,相互穿过,阻塞点击触摸事件。
  2. 变换属性——可以改变形状、合并、拆分然后合并,但不可以弯曲和折叠。
  3. 运动属性——可以自然的被创建或者销毁,可以任意移动,用户与material的交互一般通过z轴变化和波纹动画展示

同时material design定义了许多了规范,是经过google产品设计工程师用心总结起来,总体看起来体验蛮炫。具体效果可以参照chrome的新书签,感觉比以前高大上许多。在手机设备上也定义了一些规范,这里只总结个人较为关注和在手机上比较好实现的一些规范。

  布局:layout一般内容距离边界边距为16dp

  可触摸控件:大小一般为48*48dp,实际内容为40*40或者24*24dp

   imageView可以通过设置padding来实现或者让设计截图留好padding

  类似按钮这样的可触摸控件一般可触摸高度为48dp,实际高度为36dp

  那么在安卓内该如何实现这样的按钮?

  It‘s big problem,这里想到了两种方式,但没有完全实现:

  1. 通过自定义背景来设置,
  2. 调用父类View中得setTouchDelegate方法来扩大button的可触摸范围,但一个父类只能设置一个TouchDelegate,当有多个button要实现这样的可触摸范围时,可以考虑继承默认的TouchDelegate类,内部自己定义多个可点击范围来实现对多个button的委托访问。
  3. 听之任之……

material design定义了button控件有三种模式,如下图:

分别为:

  1. Floating action button——官方无实现,我在目前开发设计业没有用到过如果需要使用可以参照github:https://github.com/futuresimple/android-floating-action-button
  2. Raised button——普通的button,5以上通过使用material相关主题实现波纹和阴影效果;5以下不推荐实现波纹效果,Chris Banes回复说“Ripples are highly dependent on Lollipop‘s new RenderThread for performance. As devices before that do not have RT, the performance will be bad.”5以下建议使用Appcompat theme,需要阴影需要自己设置阴影或者使用对应的效果图。
  3. Flat button——1、设置stateListAnimator,elevation,translationZ为0;2、api在11以上设置background为?android:attr/selectableItemBackground(按钮默认颜色为透明);

这三种按钮建议使用频率是 flat button>raised button>floating action button,主要是为了避免过多的层叠

后面还列出一些其他material design列出的规范:

Dividers——1dp thick,opacity 12% black or 12% white

Snackbars & toasts

• Single-line snackbar height: 48dp

• Multi-line snackbar height: 80dp

• Text: Roboto Regular 14sp

• Action button: Roboto Medium 14sp, all-caps text

• Default background fill: #323232 100%

Android 5关于material design实现

以上内容是关于对于material design的一个简单介绍和个人归纳,很多具体规范可以参照官方material design手册,设计应该比码农要关注更多吧,读完可是要费蛮多功夫的。后面的内容是个人使用Android对material design的实现,其中有一部分摘自于网络内容,尤其是图片,算我盗版呗。

首先,Android 5提供了material theme实现了大多数的控件的样式,但是个人推荐使用Appcompat包得Theme.AppCompat,其实际上就是继承了material theme,并实现了对5下部分控件的兼容,material design有以下主题可以选择:

Theme.Material (dark version)

Theme.Material.Light (light version)

Theme.Material.Light.DarkActionBar

Theme.AppCompat

Theme.AppCompat.Light

Theme.AppCompat.Light.NoActionBar

Theme.AppCompat.NoActionBar

其次,要配置调色板,一般可以配置的颜色如图所示:

其代码大概可以是

<resources>
  <style name="AppTheme" parent="android:Theme.Material">
    <item name="android:colorPrimary">@color/primary</item>
    <item name="android:colorPrimaryDark">@color/primary_dark</item>
    <item name="android:colorAccent">@color/accent</item>
  </style>
</resources>

这部分具体在我的demo中如下:

<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- 主要文字颜色 -->
        <item name="android:textColorPrimary">#ffaa66cc</item>

        <!-- 窗口的背景颜色 -->
        <!--<item name="android:windowBackground">@android:color/white</item>-->

        <!-- 默认switch颜色 -->
        <item name="colorSwitchThumbNormal">#ffcc0000</item>
        <item name="colorControlActivated">#ff669900</item>
        <item name="toolbarStyle">@style/MyToolBar</item>
        <item name="switchStyle">@style/MySwitch</item>
        <item name="searchViewStyle">@style/MySearchViewStyle</item>
    </style>

    <style name="AppTheme" parent="@style/AppBaseTheme"/>

MyAppTheme

 <application
        android:name=".common.MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        ...    

AndroidManifest.xml--begin

其中涉及到material design提到的三种组件:

System bar(Status bar) ——即android手机显示电量,时间等状态的系统转太烂;height:24p ,color:一般暗色,也可以设计为应用的一种元素色或者半透明

Android navigation bar —— android的导航栏,这里指左右导航栏,其实安卓手机底部的有返回键、home键的这一栏也称为navigation bar,在屏幕上的时虚拟导航栏,是在手机硬件上得称为硬件导航栏;height:48p,color:同status bar侧边导航;推荐:左导航右是当前页的二级内容 width=Screen width - 56dp;最大width:左320dp,右:全屏

Tools bar -> App bar (Action bar),即系统状态栏下应用的标题栏,过去是action bar,现在一般用toolbar;横屏48dp 竖屏最小56dp,菜单栏一般是一个薄纸片,而不是bar的一个扩展

这里关于系统的状态栏和底部导航栏有些配置,介绍如下:

隐藏StatusBar——1、style定义android:windowFullScreen为true;2、getWindow().addFlags(WindowManager.LayoutParams.FLAY_FULLSCREEN);3、View.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG)

隐藏NavigationBar(API 14)——view.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

设置颜色(API 21)——getWindow().setStatusBarColor(…);getWindow().setNavigationBarColor();

设置透明(API 14)

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)

可以通过View的一些常量来改变屏幕的一些特性(View.setSystemUiVisibility(UiOptions)(API 11)),具体如下(隐藏系统栏和低能模式会在有app bar时失效):

SYSTEM_UI_FLAG_FULLSCREEN   全屏隐藏系统状态栏 (lean back)模式

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN   全屏但是不隐藏系统状态栏

SYSTEM_UI_FLAG_HIDE_NAVIGATION 全屏并隐藏导航栏

SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 全屏不隐藏导航栏

SYSTEM_UI_FLAG_LOW_PROFILE 低能状态

SYSTEM_UI_FLAG_LAYOUT_STABLE 保持状态栏和导航栏布局稳定,类似于invisible

SYSTEM_UI_FLAG_IMMERSIVE immersive 模式

SYSTEM_UI_FLAG_IMMERSIVE_STICKY  不清除flag的immersive模式,过一段时间隐藏的系统栏和导航栏会再次自动隐藏

具体效果参照demo的StatusBarActivity。

Ripple效果(波纹效果)

  1. 其他控件可以设置背景为?android:attr/selectableItemBackground(API 11)或者?android:attr/selectableItemBackgroundBorderless(API 21),点击触摸颜色可以通过android:colorControlHighlight(API 21)来设置
  2. 使用ViewAnimationUtils.createCircularReveal来实现
  3. 新建一个RippleDrawable资源,赋值给backgroud。

<ripple xmlns:android="http://schemas.android.com/apk/res/android"?        android:color="@android:color/holo_red_dark">?    <item?        android:drawable="@android:color/holo_green_dark"/>?</ripple>`

ripple drawable

兼容的使用Android 5.0新特性

  • 使用AppCompat-v7包和Theme.Appcompat主题,提供了以下控件的兼容性,(极力推荐,对于不满意的地方只要去修改style就好了):

Everything provided by AppCompat’s toolbar (action modes, etc)

EditText

Spinner

CheckBox

RadioButton

SwitchCompat

CheckedTextView

  • 定义不同的styles,这种方式还好,可以同时继承一个低版本的父类style,然后不同机型实现不同效果

res/values/styles.xml.

  

<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <!-- 主要文字颜色 -->
        <item name="android:textColorPrimary">#ffaa66cc</item>
        <item name="android:textColorHighlight">@color/abc_primary_text_material_dark</item>

        <item name="colorPrimaryDark">#ffaa66cc</item>
        <item name="colorPrimary">#ffaa66cc</item>
        <item name="colorAccent">?attr/colorAccent</item>
        <!-- 窗口的背景颜色 -->
        <!--<item name="android:windowBackground">@android:color/white</item>-->

        <!-- 默认switch颜色 -->
        <item name="colorSwitchThumbNormal">#ffcc0000</item>
        <item name="colorControlActivated">#ff669900</item>
        <item name="toolbarStyle">@style/MyToolBar</item>
        <item name="switchStyle">@style/MySwitch</item>
        <item name="searchViewStyle">@style/MySearchViewStyle</item>
        <item name="editTextStyle">@style/Widget.AppCompat.EditText</item>
        <item name="buttonStyle">@style/MyButton</item>
        <item name="dialogTheme">@style/Theme.AppCompat.Light.Dialog</item>
    </style>

style

res/values-v21/styles.xml.

<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="AppTheme" parent="@style/AppBaseTheme">
        <!-- 系统状态栏 颜色-->
        <item name="android:colorPrimaryDark">@android:color/holo_green_dark</item>
        <!-- 底部导航栏颜色 -->
        <item name="android:navigationBarColor">@android:color/holo_purple</item>

        <item name="android:colorAccent">?attr/colorAccent</item>
        <!-- 触摸颜色,包括button ripple 背景-->
        <item name="android:colorControlHighlight">@android:color/holo_red_dark</item>
    </style>

</resources>

style-v21

  • 定义不同的布局,如果真的是布局会有不同,感觉大事不妙,在现在的技术基础上,只要是两份相同的布局文件便会遇到维护性难的问题,所以最好还是保持一致性,如果某些新特性需要修改的话还是建议使用代码来实现,可以采取工厂模式实现不同版本特性的抽离:

res/layout/my_activity.xml

res/layout-v21/my_activity.xml

  

Android 5新控件

RecyclerView

RecyclerView是官方首先推出来的一个大控件,官方希望关于展示集合类型的数据均用Recyclerview来实现,可以用来替代listview和gridview;他对比listview和gridview有以下特点

  • 抽象出了viewholder来缓存view,recyclerview直接管理的时viewholder,不再是view
  • 对比listview,gridview,它更高效,拥有更大的灵活性,方便的使用不同类型的数据,提供辅助类配置动画
  • 但是需要写更多的代码,没有默认的adapter提供,除了scroll监听不提供其他监听
  • 通过Adapter的细粒度的封装使得效率提高,譬如增、删、改某个元素或者某个范围的元素通过调用notifyItemChanged(int position)、notifyItemInserted(int position)、notifyItemMoved(int fromPosition, int toPosition)、notifyItemRangeChanged(int positionStart, int itemCount)等方法实现,不再像listview必须一次性通知更改全部集合元素。

简单使用:

StaggeredGridLayoutManager指布局按照瀑布流模式来排列布局

 1 private void initRecycler() {
 2         // use this setting to improve performance if you know that changes
 3
 4         RecyclerView.LayoutManager layoutManager = new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL);
 5         RecyclerView.LayoutManager layoutManager1 = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
 6         RecyclerView.LayoutManager layoutManager2 = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
 7         RecyclerView.LayoutManager layoutManager3 = new GridLayoutManager(this, 3);
 8         mRecyclerView.setLayoutManager(layoutManager);
 9         mRecyclerView.setAdapter(new Adapter(Arrays.asList("button & background", "status bar & nav bar",
10                 "cardView & ripple", "toolbar", "switchCompat", "exit", "add1", "add2")));
11         // in content do not change the layout size of the RecyclerView
12         mRecyclerView.setHasFixedSize(false);
13     }

recyclerView init

  1 private class Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener {
  2         private List<String> list;
  3         private OnItemClickListener listener;
  4
  5         public Adapter(List<String> list) {
  6             super();
  7             this.list = new ArrayList<>(list);
  8             listener = new OnItemClickListener() {
  9                 @Override
 10                 public void onItemClick(View v, int layoutPosition) {
 11                     onClick(v);
 12                 }
 13             };
 14         }
 15
 16         @Override
 17         public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
 18             Context context = parent.getContext();
 19             if (viewType == 1) {
 20                 ImageView imageView = new ImageView(context);
 21                 imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 150));
 22                 return new MyViewHolder(new ImageView(context));
 23             }
 24             Button btn = new Button(context);
 25             btn.setMinHeight((int) (context.getResources().getDisplayMetrics().density * (36 + random.nextInt(36) + 0.5f)));
 26             return new MyViewHolder(btn);
 27         }
 28
 29         @Override
 30         public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
 31             if (position != getItemCount() - 1) {
 32                 ((Button) holder.itemView).setText(list.get(position));
 33             } else {
 34                 ((ImageView) holder.itemView).setImageResource(R.mipmap.ic_launcher);
 35             }
 36         }
 37
 38         @Override
 39         public int getItemViewType(int position) {
 40             if (position == getItemCount() - 1) {
 41                 return 1;
 42             }
 43             return super.getItemViewType(position);
 44         }
 45
 46         @Override
 47         public int getItemCount() {
 48             return list == null ? 0 : list.size() + 1;
 49         }
 50
 51         public void add(int position, String str) {
 52             list.add(position, str);
 53             notifyItemInserted(position);
 54         }
 55
 56         public void delete(int position) {
 57             list.remove(position);
 58             notifyItemRemoved(position);
 59         }
 60
 61         @Override
 62         public void onClick(View v) {
 63             int index;
 64             switch ((String) v.getTag()) {
 65             case "button & background":
 66                 if (Utils.hasLollipop()) {
 67                     getWindow().setExitTransition(new Fade());
 68                 }
 69
 70                 startActivity(
 71                         new Intent(HomeActivity.this, ButtonActivity.class),
 72                         ActivityOptions.makeCustomAnimation(HomeActivity.this, android.R.anim.fade_in,
 73                                 android.R.anim.slide_out_right).toBundle());
 74                 break;
 75             case "status bar & nav bar":
 76                 startActivity(new Intent(HomeActivity.this, StatusBarActivity.class));
 77                 break;
 78             case "cardView & ripple":
 79                 startActivity(new Intent(HomeActivity.this, CardViewActivity.class));
 80                 break;
 81             case "toolbar":
 82                 startActivity(new Intent(HomeActivity.this, ToolBarActivity.class));
 83                 break;
 84             case "switchCompat":
 85                 startActivity(new Intent(HomeActivity.this, SwitchActivity.class));
 86                 break;
 87             case "exit":
 88                 exit();
 89                 break;
 90             case "delete 1":
 91                 delete(list.indexOf("delete 1"));
 92                 break;
 93             case "delete 2":
 94                 delete(list.indexOf("delete 2"));
 95                 break;
 96             case "add1":
 97                 index = list.indexOf("delete 1");
 98                 if (index < 0) {
 99                     add(list.indexOf("add1"), "delete 1");
100                 }
101                 break;
102             case "add2":
103                 index = list.indexOf("delete 2");
104                 if (index < 0) {
105                     add(list.indexOf("add1"), "delete 2");
106                 }
107                 break;
108             }
109         }
110
111         private class MyViewHolder extends RecyclerView.ViewHolder {
112             public MyViewHolder(View itemView) {
113                 super(itemView);
114
115                 if (listener != null) {
116                     itemView.setOnClickListener(new View.OnClickListener() {
117                         @Override
118                         public void onClick(View v) {
119                             if (v.getTag() == null) {
120                                 v.setTag(list.get(getLayoutPosition()));
121                             }
122                             listener.onItemClick(v, getLayoutPosition());
123                         }
124                     });
125                 }
126             }
127
128             @Override
129             public String toString() {
130                 return super.toString();
131             }
132         }
133     }

定义Adapter

其中,onCreateViewHolder方法用来创建对应的Viewholder,onBindViewHolder用来指定当viewholder被绑定时该做什么操作,getItemViewType方法指定数据类型,好生成不同类型的View。

PS:

Recyclerview内部定义的position有两种position,他们在大多时候相同,仅在某些情况下不一致,如下:

  • layout position: 指的是你所能看到的item的position.
  • adapter position: item在adapter的position,只在调用adapter.notify*时会不同(两者大概差16ms),获取该position的方法可能会返回NO_POSITION或者null.

CardView

官方上说list大多数情况是瓷砖,四角方方正正,但cardview是真的卡片。那么CardView在android的实现其实可以设置圆角自带阴影的FrameLayout,适用情况:文字内容在三行以上,一个布局有两个以上的动作事件;其他情况请酌情考虑使用list,不要滥用。以下是几个要点:

  • cardView在5以下使用了padding来绘制阴影,所以cardview的padding在5以下无效,建议使用setContentPadding(int, int, int, int) 来设置内容和边界的padding
  • 如果给cardview指定了准确的大小,那么cardview在5以前和5以后的版本会有一些差别,可以通过兼容的resource来解决该差异,也可以通过setUseCompatPadding(true)来设置5以后的cardview也使用内部padding来解决该差异
  • 通过设置 setCardElevation(float)来改变海拔高度,同时改变阴影大小;只改变阴影大小,不改变z坐标使用 setMaxCardElevation(float)

Palette

palette是官方给的一个新API,可以从一个图片抽取6种不同元素的颜色,这个API使得android的界面可以显得更加富有变化和活泼,比如在一个listview中,抽取每个item的图片来作为这个item的标题栏,来区分这个item和其他item的颜色分类;或者抽从app的一个主要图片抽取颜色赋予到status bar等等。

官方的这个类只提供了6种颜色,其实也是提取某些范围的颜色值,提取出来的颜色是完全不透明的。具体用法如下:

 1 build = Palette.from(((BitmapDrawable) getResources().getDrawable(R.mipmap.ic_launcher)).getBitmap())
 2                 .maximumColorCount(16).resizeBitmapSize(192);
 3 build.generate(new Palette.PaletteAsyncListener() {
 4                 @Override
 5                 public void onGenerated(Palette palette) {
 6                     Palette.Swatch swatch = palette.getVibrantSwatch();
 7                     int tc = swatch.getTitleTextColor(), bc = swatch.getBodyTextColor();
 8                     if (Utils.hasLollipop()) {
 9                         getWindow().setStatusBarColor(swatch.getRgb());
10                     }
11                 }
12             });

PS:建议使用22.1以上的support包,效率会提升5倍以上

AppCompatActivity & Toolbar

AppCompatActivity用来代替ActionBarActivity,提供在安卓所有版本一致性的App bar,即Toolbar。AppCompatActivity要求使用Theme.AppCompact主题或者该主题的子类。以后建议使用AppCompatActivity来当做所有activity的父类。

那么现在有个问题,我们为什么要使用toolbar,我个人总结了以下三点原因:

  1. google推material design,toolbar作为一个重点来推,他们认为这样的设计是一个好的设计
  2. toolbar提供了之前actionbar几乎所有的功能(有些被废弃但依然很强大),有利于保持设计的一致性,并且保持了灵活性和扩展性
  3. toolbar是个类似于RelativeLayout的viewgroup,子view支持layout_gravity属性,可以自由扩展;以前需要费劲的扩展actionbar的瓶颈已经不复存在,你想怎么扩展就怎么扩展!

那么ToolBar默认提供了哪些强大的功能:

  1. 和DrawerLayout良好配合实现“抽屉”导航栏
  2. 提供可折叠的视图(CollapsibleActionView),官方已提供searchview的实现。
  3. 提供了action provider,可以展示一个子菜单,官方提供了ShareActionProvider,MediaRouteActionProvider

以下三张图分别展示了这三个功能,具体示例和实现可以参照demo

toolbar默认元素图如下:

如果希望toolbar充当如图系统中的app bar,那么需要在OnCreate中调用setSupportActionBar(toolbar),这时toolbar即成为系统的app bar,拥有action bar绝大多数功能。

设置NavigationIcon,需在setSupportActionBar后调用toolbar.setNavigationIcon;

设置Logo,主标题和副标题调用setLogo、setTitle、setSubTitle即可。如果不希望显示toolbar自带的标题,那么可以设置标题为"",注意为null无效;或者设置getSupportActionBar().setDisplayShowTitleEnabled(false);

设置toolbar的NavigationIcon随着drawerlayout的抽屉变化而改变图标,设置getSupportActionBar().setDisplayHomeAsUpEnabled(true)和getSupportActionBar().setHomeButtonEnabled(true);

设置右侧菜单,需在activity的onCreateOptionsMenu方法中设置自己的菜单,然后可以在onOptionsItemSelected方法中捕获到每个菜单被选择到得到的事件,也可以toolbar自己设置监听;

额外的一些分享

退出系统

在android 5要退出应用一般启动app的一个singleTop的activity,然后再finish这个activity。在android 5以上不推荐由我们来退出程序,应该交给系统来完成这样的工作,如果在android 5还是需要这样的功能,可以通过下面简单的代码实现:

1 List<ActivityManager.AppTask> list = activityManager.getAppTasks();
2 ?for (ActivityManager.AppTask appTask : list) {?    appTask.finishAndRemoveTask();?
3 }

exit

判断当前activity是否正在运行

在android 5以前都是通过拿getRuningTask来获取相关信息,但是现在android 5认为这个方法会泄露隐私,因此废弃了getRuningTask等方法,因此在android 5以上需要通过runningAppProcessInfo来获取相关信息,具体代码如下:

1 boolean isOnForeGround = false;?List<ActivityManager.RunningAppProcessInfo> pList =activityManager.getRunningAppProcesses();?for(ActivityManager.RunningAppProcessInfo processInfo : pList){?    if(processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND){?
2 for(String activityPack : processInfo.pkgList){?            if(activityPack.equals(context.getPackageName())){?                isOnForeGround = true;?
3 return;?
4 }?
5         }
6 ?    }?}

activity is foreground ?

更改背景的透明度和灰度(API 1)

即更改如弹出dialog默认的背景,可以由下面代码来做

1 WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();?
2 lp.alpha = 0.5f;
3 lp.dimAmount = 0.6f;?
4 dialog.getWindow().setAttributes(lp);?dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND,?        WindowManager.LayoutParams.FLAG_DIM_BEHIND);

dim background

大概总结这么多,demo下载地址

https://github.com/jonyChina162/LollipopTest

里面还有我自己做的一个ppt

时间: 2024-10-03 15:24:52

Material Design & Android 5的相关文章

android 5.0 Material Design酷炫风格的开源项目集合

一.前言 Android 5.0上线有一个段时间了,估计小伙伴们都看到了Android5.0界面上相比前面几个版本有了很大的突破,给人一种非常酷炫,平滑的跳转,生动的界面切换,全新的感觉,Android用户终于可以感叹,Google升级了这么多个版本终于像样的搞了一回界面.开发者们看到这些优美的动画也要大户过瘾啊.github上面的高人们都已经饥渴难耐了出了写出了各种好用,炫丽的特效,我们今天就来看一下都有哪些可以用比较爽的开源项目. Material Menu 项目地址:https://git

material design 的android开源代码整理

https://github.com/navasmdc/MaterialDesignLibrary#progress-bar-indeterminate-determinate Material Design Android Library How to use Components Buttons Flat Button Rectangle Button Float Button Float small button Switches CheckBox Switch Progress indi

创建Material Design风格的Android应用--应用主题

昨天正式发布了android 5,同时android developer网站也更新了,增加了创建Material Design风格的Android应用指南,也更新了Support Library,在support library增加了一些Material Design风格的控件和动画等,这里给大家简单介绍一下怎样开发material design风格的Android应用. android 5使用Material Design风格 android提供了三种Material Design风格Them

[翻译]Android 5.0之应用中实现材料设计—Material Design

上午的时候在刷Google+,看到了Abraham Williams转发了一篇强文,是Android Developers网站新发的一篇博客—Implementing Material Design in your Android App.觉得很前卫,对于新发布的Android版本号Android 5.0是一个很好的学习和了解的机会,所以就花了些时间把它翻译了下来,希望对自己.对其它人有所启发. 因为翻译Android开发博客和API也只是业余爱好,水平有限,其中不免有不准确的地方,所以把原文地

Android Material Design学习之RecyclerView代替 ListView

前言 # Android Material Design越来越流行,以前很常用的 ListView 现在也用RecyclerView代替了,实现原理还是相似的.笔者实现一下 RecyclerView,代码比较简单,适合初学者,如有错误,欢迎指出. 源码地址(欢迎star) https://github.com/studychen/SeeNewsV2 本文链接 http://blog.csdn.net/never_cxb/article/details/50495505,转载请注明出处. 复习 L

Android Material Design之在RecyclerView中嵌套CardView实现

前言: 第一眼就爱上了Android的Material Design风格.以前倒对Android的界面风格不那么喜欢,扁平化的界面设计真是好看. 其实,这个嵌套操作在实现上并没有什么难点.可是,我还在Eclipse上没有试验成功.后来换到Android Studio上就OK了.以下是实现过程. 笔者开发环境: 系统:Windows 7 旗舰版 IDE:Android Studio v1.0 工具包:cardview-v7-21.0.0.aar recyclerview-v7-21.0.0.aar

Material Design 开发利器:Android Design Support Library 介绍

转自:https://blog.leancloud.cn/3306/ Android 5.0 Lollipop 是迄今为止最重大的一次发布,很大程度上是因为 material design —— 这是一门新的设计语言,它刷新了整个 Android 的用户体验.但是对于开发者来说,要设计出完全符合 material design 哲学的应用,是一个很大的挑战.Android Design Support Library 对此提供了很好的支持,里面汇集了很多重要的 material design 控

创建Material Design风格的Android应用--使用自定义动画

动画在Material Design设计中给用户反馈放用户点击时,并且在程序用户界面中提供连贯的视觉.Material主题为按钮(Button)和activity的转换提供了一些默认的动画,在android5.0(api 21)和更高的版本,你可以自定义这些动画和创建一个新动画: Touch feedback(触摸反馈) Circular Reveal(循环揭露效果) Activity transitions(Activity转换效果) Curved motion(曲线运动) View stat

创建Material Design风格的Android应用--使用Drawable

以下Drawables的功能帮助你在应用中实现Material Design: 图片资源着色 在android 5.0(api 21)和更高版本,可以着色bitmap和.9 png 通过定义透明度遮盖.你可以着色通过使用颜色资源或者主题的属性去解析颜色资源(比如,?android:attr/colorPrimary).通常我们创建一次,然后资源自适应主题. 你可以给BitmapDrawable或NinePatchDrawable对象着色使用setTint()方法.你可以可以在布局文件中使用and