如何理解Android 5.0浮动ios按钮阴影效果的阴影变化

14:56 提问
android5.0以下阴影效果怎么实现?
就是最下面的边框的阴影,给imageview设置elevation在4.4无效。
按赞数排序
用CardView试过吗
其他相似问题Android5.0的Palette(调色板)、视图阴影、着色和裁剪介绍
随着5.0的发布,google带来了Material Design,俗称:材料设计。并带来了一些新的东西,这里就一一介绍这些新的设计元素。
1、Palette(调色板)
在5.0以后的android版本中可以使用调色板来提取颜色,让app的主题颜色动态的适应当前页面的色调,使得你的app整体看起来主题基调和谐统一;下面是官网的介绍和使用说明,先截个图,后面简单翻译下:
palette这是一个可以从image中提取颜色的类,它可以从image中提取及几种不同的色调,如下:
Vibrant : 充满活力的,
Vibrantdark :充满活力的黑
Vibrant light :充满活力的亮
Muted :柔和的
Muted dark : 柔和的黑
Muted light : 柔和的亮
使用Palette可以在Android studio中的gradle添加以下依赖:
compile 'com.android.support:palette-v7:23.4.0'
从示例代码中,我们可以看到:通过传递一个bitmap对象给Palette,并调用他的Palette.generate()静态方法或者在静态方法中添加异步接口的方法来创建一个Palette,接下来就可以使用Palette的getter方法来检索相应的色调,就是是昂面那6中色调;下面显示一段代码,将通过背景图片的柔和色调来改变ActionBar和状态来的色调,使之能够统一,然而并不是所有6种颜色方案都可用,每种颜色方案都返回为Palette.Swatch,如果图片示例包含的颜色不足以产生兼容的方案,则对应的颜色方案可能为null。为了展示这个功能,我们将创建一个图片图块的背景和标题将通过Palette主题话。效果如下:
是不是给人很不一样的感觉了,接下来就介绍代码,如下:
item_list.xml 如下:
适配器中的调色板颜色
ColorfulAdapter.class
package com.world.hello.
import android.content.C
import android.graphics.B
import android.graphics.BitmapF
import android.graphics.C
import android.os.AsyncT
import android.support.v7.graphics.P
import android.util.SparseA
import android.view.LayoutI
import android.view.V
import android.view.ViewG
import android.widget.ArrayA
import android.widget.ImageV
import android.widget.TextV
* Created by chengguo on .
public class ColorfulAdapter extends ArrayAdapter {
private static final int[] IMAGES = {
R.drawable.bricks, R.drawable.flower,
R.drawable.grass, R.drawable.stones,
R.drawable.wood, R.drawable.dog
private static final String[] NAMES = {
&Bricks&, &Flower&,
&Grass&, &Stones&,
&Wood&, &Dog&
private SparseArray mI
private SparseArray mBackgroundC
public ColorfulAdapter(Context context) {
super(context, R.layout.item_list, NAMES);
mImages = new SparseArray(IMAGES.length);
mBackgroundClolors = new SparseArray(IMAGES.length);
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_list, parent, false);
View root = convertView.findViewById(R.id.root);
ImageView imageView = (ImageView) convertView.findViewById(R.id.image);
TextView textView = (TextView) convertView.findViewById(R.id.text);
int imageId = IMAGES[position];
if (mImages.get(imageId) == null) {
new ImageTask().execute(imageId);
textView.setTextColor(Color.BLACK);
imageView.setImageBitmap(mImages.get(imageId));
Palette.Swatch colors = mBackgroundClolors.get(imageId);
if (colors != null) {
root.setBackgroundColor(colors.getRgb());
textView.setTextColor(colors.getTitleTextColor());
textView.setText(NAMES[position]);
return convertV
private class ImageResult {
public int imageId;
public Palette.S
public ImageResult(int imageId, Bitmap image, Palette.Swatch colors) {
this.imageId = imageId;
this.image =
this.colors =
* 因为从磁盘加载图片和使用Palette分析这些图片的过程会花费一些时间,所以我们要在后台执行此工作,
* 以免阻塞主线程太长时间,因此放在AsyncTask中执行
private class ImageTask extends AsyncTask {
protected ImageResult doInBackground(Integer... params) {
int imageId = params[0];
//确保图片缩率图不会太大
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
Bitmap image = BitmapFactory.decodeResource(getContext().getResources(), imageId, options);
Palette colors = Palette.generate(image);
Palette.Swatch selected = colors.getVibrantSwatch();
if (selected == null) {
selected = colors.getMutedSwatch();
return new ImageResult(imageId, image, selected);
protected void onPostExecute(ImageResult imageResult) {
updateImageItem(imageResult);
notifyDataSetChanged();
* 更新一项的颜色
* @param imageResult
private void updateImageItem(ImageResult imageResult) {
mImages.put(imageResult.imageId, imageResult.image);
mBackgroundClolors.put(imageResult.imageId, imageResult.colors);
activity.class
package com.world.hello.
import android.os.B
import android.support.v7.app.AppCompatA
import android.widget.GridV
public class MainActivity extends AppCompatActivity {
private GridView mGridV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGridView = new GridView(this);
mGridView.setNumColumns(2);
mGridView.setAdapter(new ColorfulAdapter(this));
setContentView(mGridView);
2、视图和阴影
在Material Design中很重要的风格就是拟物扁平化,使用阴影和光线,在配合完美的动画,展示出现实生活中的效果,看起来就感觉非常的美丽
以前的UI设计都只有X、Y轴这个两个方向,现在多出来一个垂直于手机屏幕的Z轴,那么设置Z轴的高度,然后配合光线,然后就在UI的下方看到阴影,这样就实现了拟物效果。
View的Z轴由两部分组成,elevation和translationZ,这两个属性都是5.0以后才引入的。elevation是静态的成员,translationZ可以在代码中使用来实现动画效果,他们的关系是:
Z = elevation + translationZ
elevation是在XML布局文件中使用,如果android版本小于5.0设置的elevation是不生效的,只有大于5.0的android设置elevation才行;下面是xm示例
效果图如下:
然而,在java代码中要使用setTranslationZ()来动态改变视图的高度
通常是使用属性动画来为视图高改变的时候增加一个动画效果,例如:
if (flag){
view.animate.translationZ(100);
view.animate.translationZ(0);
3、着色和裁剪
在andorid5.0中还增加了两个非常实用的功能:Tinting(着色)和Clipping(裁剪)
3.1 使用Tinting非常简单,只需要在XML文件中使用tint和tintMode就行了,有几种配合效果,t它的实质是通过修改图像的Alpha遮罩层来修改图像的颜色,从而达到重新着色的目的。对图像处理使用起来非常方便如下:
3.2 Clipping裁剪,它可以改变一个视图的外观,首先,要使用ViewOutlineProvider来修改outline,然后再通过setOutlineProvider将outline作用给视图;下面使用IamgeView通过Clipping裁剪成圆角正方形和一个圆形;示例如下:
package com.example.chengguo.
import android.graphics.O
import android.os.B
import android.support.v7.app.AppCompatA
import android.view.V
import android.view.ViewOutlineP
import android.widget.ImageV
public class MainActivity extends AppCompatActivity {
private ImageView mRectV
private ImageView mCircleV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRectView = (ImageView) findViewById(R.id.image_rect);
mCircleView = (ImageView) findViewById(R.id.image_circle);
//获取outline
ViewOutlineProvider outLine1 = new ViewOutlineProvider() {
public void getOutline(View view, Outline outline) {
//修改outline为特定形状
outline.setRoundRect(0,0,view.getWidth(),view.getHeight(),10);
//获取outline
ViewOutlineProvider outline2 = new ViewOutlineProvider() {
public void getOutline(View view, Outline outline) {
outline.setOval(0,0,view.getWidth(),view.getHeight());
//重新为两个imageView设置外形
mRectView.setOutlineProvider(outLine1);
mCircleView.setOutlineProvider(outline2);floatingactionbutton在5.0下阴影效果没了【android开发吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:116,743贴子:
floatingactionbutton在5.0下阴影效果没了收藏
<android.support.design.widget.FloatingActionButton>android:layout_alignParentEnd=&true&android:layout_alignParentBottom=&true&android:layout_width=&wrap_content&android:layout_height=&wrap_content&app:fabSize=&normal&/>在4.4及以下都有阴影效果,,但是5.0并没有。。自己设置app:elevation也没有用,,,,
达内android开发,开启安卓“薪”时代,前沿安卓课程,120天速成安卓高级工程师,达内android开发,短期打造编程高手!点击申请-达内免费试学&&
没人知道是怎么回事吗
这是个bug,在Android L以上的系统,即values-v21/dimens.xml文件中为FloatingActionButton设置marginBottom和marginRight为一个非零值(如16dp),在低于Android 5.0的系统中设置这两个dimen值为0dp
登录百度帐号推荐应用阴影和剪裁
View的z属性
Material Design建议为了凸显布局的层次,建议使用阴影效果,并且Android L为了简化大家的工作,对View进行了扩展,能使大家非常方便的创建阴影效果:
给View添加了一个新的属性:Z&属性,用于描述视图距离它父视图的高度:
在5.0之前,我们的视图都是二维的,只有x轴和y轴,现在,android新增了z轴。x轴和y轴描述了一个view的大小和位置,而z轴描述了view在父视图上抬起的视觉,体现效果就是阴影。下图的两个view的z属性分别为2dp和8dp的视觉效果:
View的Z属性可以通过elevation和translationZ进行修改。
z = elevation+translationZ
在5.0之前,我们如果想给view添加阴影效果,以体现其层次感,通常的做法是给view设置一个带阴影的背景图片,现在,我们只需要简单的修改view的Z属性,就能让其具备阴影的层次感。
Z属性会扩大view的显示区域,如果它的大小大于或等于父视图的大小,那么它的阴影效果就无法显示了,view并不会因为z属性而把自身缩小腾出空间显示阴影。
Z属性不仅影响着view的阴影效果,还影响着view的绘制顺序,在同一个父view内部,Z属性越小,绘制的时机就越早。也就是优先被绘制,而z属性越大,则绘制时间越晚,后绘制的将会遮盖住先绘制的,只有Z属性相同,才按照添加的顺序绘制。
View的轮廓
在Android的世界里,所有的View都是矩形的,虽然可以给View设置背景圆形的图片,即可在界面显示出圆形的内容,但是View的大小实际上仍然是矩形,并且设置的图片也是实际上也是矩形,只是圆形意外的区域为透明色。
如果系统根据View的大小来为我们生成对应的阴影,有时候就会出现很奇怪的效果。
为了解决该类问题,View增加了一个新的描述来指明内容显示的形状,这就是轮廓。通过shape设置的背景,View会自动根据shape的形状进行轮廓判定,通过color设置的背景,View默认其轮廓和View的大小一样。但是通过图片进行背景设置,View则无法获知轮廓的形状,这个时候就需要我们程序员显示的指定。
在xml布局中,可以通过android:outlineProvider来指定轮廓的判定方式:
none&即使设置了Z属性,也不会显示阴影
background&会按照背景来设置阴影形状
bounds&会按照View的大小来描绘阴影
paddedBounds&和bounds类似,不过阴影会稍微向右偏移一点
在代码中,我们可以通过setOutlineProvider来指定一个View的轮廓:
ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() {
public void getOutline(View view, Outline outline) {
// 可以指定圆形,矩形,圆角矩形,path
outline.setOval(0, 0, view.getWidth(), view.getHeight());
View.setOutlineProvider(viewOutlineProvider );
注意:如果采用图片作为背景,即使在xml布局中指定android:outlineProvider为background也不会显示阴影,只有通过代码中指定轮廓来显示。
View的剪裁
给View指定轮廓,可以决定阴影的显示形状,如果给View指定一个小于自身大小的轮廓,则阴影通常会被View遮住,这个时候View的显示内容并没有因为轮廓的缩小而缩小。
如果想根据轮廓来缩小一个View,则可以通过剪裁。如果一个View指定了轮廓,调用setClipToOutline方法,就可以根据轮廓来剪裁一个View。想要剪裁轮廓,必须要给View先指定轮廓,并且轮廓是可以被剪裁的,目前只有圆形,矩形,圆角矩形支持剪裁,可以通过outline.canClip()来判断一个轮廓是否支持剪裁。
Path剪裁不会改变View的大小,但是如果Path的范围比View要的bounds要小,则剪裁后会改变View的位置,位置偏移和Z属性有关,这可能是一个BUG,view的设计者可能在绘制阴影时根据轮廓偏移了画布,而在绘制完后忘记把画布还原了。
剪裁不会改变View的测量大小和布局大小,也不会改变View的触摸区域,剪裁只是在onDraw的时候对画布做了剪裁处理,剪裁也不同于scale,scale是调整画布matrix的缩放属性,调整后,View仍然能完整显示,而剪裁是缩小画布的剪裁区域,剪裁后我们只能看到View的不一部分。
试图给View一个比较大的轮廓进行剪裁也是不成功的,实验证明剪裁后的View只能比原有体积小。扩大轮廓只会扩大轮廓的绘制区域。
剪裁是一个非常消耗资源的操作,我们不应该用此来做动画效果,如果要实现这样的动画,可以使用Reveal Effect
阅读(...) 评论()2578人阅读
Android UI(9)
解决Android 5.0以上Button自带阴影的问题
自定义个Button的Style,继承@style/Widget.AppCompat.Button.Borderless样式即可。
name="MyButtonStyle" parent="@style/Widget.AppCompat.Button.Borderless"&
& =":textSize"&@dimen/textsize_14&/item&
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:691623次
积分:7545
积分:7545
排名:第2813名
原创:133篇
评论:461条
文章:13篇
阅读:204956
阅读:13171
阅读:32986
(1)(2)(1)(1)(2)(1)(3)(4)(6)(19)(27)(29)(20)(8)(12)(2)

我要回帖

更多关于 android 按钮阴影效果 的文章

 

随机推荐