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

时间:2014-11-22 17:32:47

标签: android android-5.0-lollipop

在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上,按原样运行样本,我们在圆圈上看到一个阴影:

ElevationBasic, As Originally Written

如果我们将窗口小部件类更改为Button,将所有其他属性保留为原样,则会丢失圆圈上的阴影:

ElevationBasic, Using a Button

问题:

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

  2. 哪些类支持android:elevation,哪些不支持?例如,使用TextView代替ViewButton仍然会为我们提供投影,因此行为更改不会在TextView级别引入,而是在Button级别。

  3. 从昨天的this question可以看出,我们如何才能android:elevation获得Button的荣誉?我们必须在主题中添加一些android:allowElevationToWorkAsDocumented="true"值吗?

5 个答案:

答案 0 :(得分:121)

“材质”下的默认“按钮”样式具有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>

答案 1 :(得分:13)

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

答案 2 :(得分:7)

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

AppCompat 23.0.0 版本开始,有一个新的 Widget.AppCompat.Button.Colored 样式,它使用了您的主题为禁用颜色的colorButtonNormal和启用颜色的colorAccent。

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

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

答案 3 :(得分:5)

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

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

答案 4 :(得分:0)

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

制作影子@android:drawable/dialog_holo_light_frame&amp;如果你想自定义背景颜色而不是白色,那么在阴影顶部创建一个可自定义颜色的图层列表背景,如下所示

创建一个单独的可绘制文件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>

并将此drawable用作此背景

android:background="@drawable/shadow"