安卓5.0安卓: 视图可用,按钮不行?

在 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>

在 Nexus9上,按原样运行样本,我们在圆上得到一个阴影:

ElevationBasic, As Originally Written

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

ElevationBasic, Using a Button

问题是:

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

  2. 哪些类支持 android:elevation,哪些不支持?例如,使用 TextView而不是 ViewButton仍然给我们带来阴影,所以这种行为上的改变不是在 TextView级别上引入的,而是在 Button级别上引入的。

  3. 从昨天的 这个问题中可以看到,我们如何让 android:elevationButton上获得荣誉?是否有一些 android:allowElevationToWorkAsDocumented="true"值,我们必须放在一个主题或东西?

44662 次浏览

“材质”下的默认 Button 样式有一个控制 android:elevationandroid:translationZ属性的 StateListAnimator。可以使用 android:stateListAnimator属性删除现有的动画器或设置自己的动画器。

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


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

默认的 Animator 是在 Button _ state _ list _ anim _ Materials. 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>

根据我在棒棒糖设备上运行 Appcompat v7的经验,Button的默认特性是连锁效应、高度和点击时的 z 动画,但是如果在 xml 元素中设置了个性化的 android:background属性(作为颜色或选择器) ,就会错过这些特性。

我有一个类似的问题,我认为是由于错误的膨胀布局,但似乎增加 clipToPadding的把戏。 这必须设置为包含要投射阴影的视图的父 ViewGroup

Android: clipToPding = “ false” ..

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

AppCompat23.0.0版本中,有一个新的 小部件。应用程序。按钮。彩色样式,它使用主题的 color ButtonNormal 作为禁用的颜色,使用 color Accent 作为启用的颜色。

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

如果您想要不同的颜色比指定您可以创建一个新的主题,并应用它到按钮通过 android:theme。然后你可以在你想要同样效果的所有按钮上使用这个主题。

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

创建一个阴影 @android:drawable/dialog_holo_light_frame & 如果你想自定义背景的颜色而不是白色,然后创建一个图层列表背景与自定义颜色的阴影顶部如下所示

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