Android 5.0 android:elevation适用于View,但不适用于Button?


69

在SDK Manager的Android 5.0示例中,有ElevationBasic示例。它显示了两个View对象:一个圆形和一个正方形。该圈子已android:elevation设置为30dp

<?xml version="1.0" encoding="utf-8"?>
<!--
 Copyright 2014 The Android Open Source Project

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent">
    <View
            android:id="@+id/floating_shape"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_marginRight="40dp"
            android:background="@drawable/shape"
            android:elevation="30dp"
            android:layout_gravity="center"/>
    <View
            android:id="@+id/floating_shape_2"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_marginLeft="25dp"
            android:background="@drawable/shape2"
            android:layout_gravity="center"/>
</FrameLayout>

在Nexus 9上,按原样运行示例,我们在圆圈上出现了阴影:

海拔高度,如最初编写的

如果将小部件类更改为Button,而其他所有属性保持原样,则将丢失圆上的阴影:

高度基础,使用按钮

问题:

  1. 为什么android:elevation行为会改变?这不能归因于背景,因为在两种情况下背景都是相同的。

  2. 哪些类支持android:elevation,哪些不支持?例如,使用TextView代替ViewButton仍然给我们阴影,因此,行为的这种变化不是在TextView层次上引入的,而是在Button层次上引入的。

  3. 从昨天的问题中可以看出,我们如何android:elevation在a上获得荣誉Buttonandroid:allowElevationToWorkAsDocumented="true"我们必须在主题中添加一些价值吗?


有趣的问题和发现,您可以与我们分享测试项目的任何变化吗?
罗夫·ツ

2
@Rolfツ:同样,ElevationBasic您可以从SDK Manager下载Android 5.0示例中的示例。我没有编写示例,但已按照Button测试问题中的说明进行了修改。
CommonsWare,2014年

我的坏,我读得有点快;)
罗夫·ツ

Answers:


141

Material下的默认Button样式具有一个StateListAnimator,用于控制android:elevationandroid:translationZ属性。您可以删除现有的动画师或使用该android:stateListAnimator属性设置自己的动画师。

<Button
    ...
    android:stateListAnimator="@null" />

<Button
    ...
    android:stateListAnimator="@anim/my_animator" />

默认的动画师在button_state_list_anim_material.xml中定义。这是显示启用和按下状态的示例:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:state_enabled="true">
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="@integer/button_pressed_animation_duration"
                            android:valueTo="@dimen/button_pressed_z_material"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="elevation"
                            android:duration="0"
                            android:valueTo="@dimen/button_elevation_material"
                            android:valueType="floatType"/>
        </set>
    </item>
    <!-- base state -->
    <item android:state_enabled="true">
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="@integer/button_pressed_animation_duration"
                            android:valueTo="0"
                            android:startDelay="@integer/button_pressed_animation_delay"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="elevation"
                            android:duration="0"
                            android:valueTo="@dimen/button_elevation_material"
                            android:valueType="floatType" />
        </set>
    </item>
    ...
</selector>

谢谢!这使得扁平按钮与pre-L设备看起来一样。
Phuah Yee Keat 2015年

1
@CommonsWare嗨,我用过这个,但是没有显示阴影有帮助吗?
2015年

老兄,您通过使用android:stateListAnimator =“ @ null”拯救了我的性命我修复了z顺序的所有问题
Gilian 2016年

动画师重写这些值在很多层面上都是错误的……:(开发人员完全
不知所措,

13

根据我在Lollipop设备上运行的Appcompat v7的经验,Button可以使用默认功能(如波纹效果,点击时的高程和z动画),但是如果android:background在xml元素中设置了个性化属性(如颜色或选择器),则会错过它们。


这个问题是关于原生Android 5.0的实现,而不是appcompat-v7。不过谢谢!
CommonsWare 2014年

1
也许是相同的,程序兼容性V7继承材质风格,通过平台的主题,如果在Android上运行5
GPack

同样在这里,如果有人知道答案,那将是有帮助的!
米诺

7

这是因为您正在手动设置按钮的背景,它将替换其所有效果。

AppCompat的23.0.0版本开始,有一个新的Widget.AppCompat.Button.Colored样式,该样式将主题的colorButtonNormal用作禁用的颜色,将colorAccent用作启用的颜色。

    <Button
  ...
  style="@style/Widget.AppCompat.Button.Colored" />

如果您想要的颜色与指定的颜色不同,则可以创建一个新主题并将其通过应用于按钮android:theme。然后,您可以在想要相同效果的所有按钮上使用此主题。


这个问题是关于原生Android 5.0的实现,而不是appcompat-v7。不过谢谢!
CommonsWare,2016年

@Heisenberg我尝试添加它,但是它没有在图像按钮上添加阴影。有小费吗?我尝试使用本机ImageButton和AppCompatImageButton。在6.0上测试。
拉胡尔·塞纳尼

6

我有一个类似的问题,我认为这是由于布局错误地导致的,但似乎添加clipToPadding就可以了。必须将其设置为ViewGroup包含要投射阴影的视图的父级。

... android:clipToPadding="false" ...


1

此解决方案适用于Android的所有API版本

创建阴影@android:drawable/dialog_holo_light_frame,如果您想自定义背景颜色而不是白色,请在阴影顶部创建具有可自定义颜色的图层列表背景,如下所示

创建一个单独的可绘制文件white_background_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--the shadow comes from here-->
    <item
        android:bottom="0dp"
        android:drawable="@android:drawable/dialog_holo_light_frame"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp">

    </item>

    <item
        android:bottom="0dp"
        android:left="0dp"
        android:right="0dp"
        android:top="0dp">
        <!--whatever you want in the background, here i preferred solid white -->
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white" />

        </shape>
    </item>
</layer-list>

并使用这个可绘制对象作为背景

android:background="@drawable/shadow"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.