Android 5.0:俯视图,但不支持按钮?

时间:2023-01-17 14:07:25

In the Android 5.0 samples from the SDK Manager, there is the ElevationBasic sample. It shows two View objects: a circle and a square. The circle has android:elevation set to 30dp:

在SDK管理器的Android 5.0示例中,有一个ElevationBasic示例。它显示两个视图对象:一个圆和一个正方形。圆有android:海拔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>

On a Nexus 9, running the sample as-is, we get a drop shadow on the circle:

在Nexus 9上,按原样运行,我们会得到圆形上的投影:

Android 5.0:俯视图,但不支持按钮?

If we change the widget class to Button, leaving all other attributes as-is, we lose the drop shadow on the circle:

如果我们将widget类更改为Button,保留所有其他属性不变,我们就会丢失圆形上的投影:

Android 5.0:俯视图,但不支持按钮?

The questions:

的问题:

  1. Why is the android:elevation behavior changing? It cannot be due to the background, because it is the same background in both cases.

    为什么android:提升行为改变了?这不能归因于背景,因为两种情况都是相同的背景。

  2. Which classes support android:elevation, and which do not? For example, using TextView instead of View or Button still gives us the drop shadow, so this change in behavior is not introduced at the TextView level, but rather at the Button level.

    哪些类支持android:海拔,哪些不支持?例如,使用TextView而不是View或Button仍然会给我们留下阴影,因此这种行为上的改变不会在TextView级别引入,而是在按钮级别引入。

  3. As seen in this question from yesterday, how do we get android:elevation to be honored on a Button? Is there some android:allowElevationToWorkAsDocumented="true" value that we have to put in a theme or something?

    从昨天的问题中可以看出,我们如何让android:在按钮上显示高度?是否有一些android: allowelevationtoworkasdocumentation =“true”值,我们必须放入主题或其他东西?

5 个解决方案

#1


115  

The default Button style under Material has a StateListAnimator that controls the android:elevation and android:translationZ properties. You can remove the existing animator or set your own using the android:stateListAnimator property.

材料下的默认按钮样式有一个StateListAnimator,它控制android:elevation和android:translationZ properties。您可以删除现有的动画器,或者使用android:stateListAnimator属性设置自己的动画器。

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

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

The default animator is defined in button_state_list_anim_material.xml. Here is a sample showing the enabled and pressed states:

默认动画器在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>

#2


10  

In my experience with Appcompat v7 running on Lollipop device, Button works with default features as ripple effect, elevation and z-animation on click, but misses them if is set a personalized android:background property (as color or selector) in xml element.

根据我在Lollipop设备上运行Appcompat v7的经验,按钮使用默认的功能,如纹波效果、高程和z动画,但如果设置一个个性化的android:背景属性(作为颜色或选择器)在xml元素中,就会忽略它们。

#3


7  

This is because you are setting the background of the button manually which will replace all its effects.

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

As of the version 23.0.0 release of AppCompat, there is a new Widget.AppCompat.Button.Colored style which uses your theme's colorButtonNormal for the disabled color and colorAccent for the enabled color.

在AppCompat的23.0.0版本中,有一个新的Widget.AppCompat.Button。彩色样式,使用主题的colorButtonNormal表示禁用的颜色和启用的颜色。

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

If you want different colors than specified you can create a new theme and apply it to the button via android:theme. Then you can use this theme on all your buttons where you want same effect.

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

#4


4  

I had a similar problem i thought was due to wrongly inflated layouts, but it appeared that adding clipToPadding did the trick. This must be set to the parent ViewGroup containing the view you want to cast a shadow.

我有一个类似的问题,我认为是由于错误的膨胀布局,但是添加cliptopadd起到了作用。必须将其设置为包含要投射阴影的视图的父视图组。

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

…android:clipToPadding = " false "……

#5


0  

This solution works for all the API versions of Android

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

Create a shadow @android:drawable/dialog_holo_light_frame & if you want to customize the color of the background instead of white then create a layer-list background with customizable color on top of the shadow as shown below

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

Create a separate drawable file white_background_shadow.xml

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

and use this drawable as the background like this

用这个可绘制的作为背景

android:background="@drawable/shadow"

#1


115  

The default Button style under Material has a StateListAnimator that controls the android:elevation and android:translationZ properties. You can remove the existing animator or set your own using the android:stateListAnimator property.

材料下的默认按钮样式有一个StateListAnimator,它控制android:elevation和android:translationZ properties。您可以删除现有的动画器,或者使用android:stateListAnimator属性设置自己的动画器。

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

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

The default animator is defined in button_state_list_anim_material.xml. Here is a sample showing the enabled and pressed states:

默认动画器在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>

#2


10  

In my experience with Appcompat v7 running on Lollipop device, Button works with default features as ripple effect, elevation and z-animation on click, but misses them if is set a personalized android:background property (as color or selector) in xml element.

根据我在Lollipop设备上运行Appcompat v7的经验,按钮使用默认的功能,如纹波效果、高程和z动画,但如果设置一个个性化的android:背景属性(作为颜色或选择器)在xml元素中,就会忽略它们。

#3


7  

This is because you are setting the background of the button manually which will replace all its effects.

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

As of the version 23.0.0 release of AppCompat, there is a new Widget.AppCompat.Button.Colored style which uses your theme's colorButtonNormal for the disabled color and colorAccent for the enabled color.

在AppCompat的23.0.0版本中,有一个新的Widget.AppCompat.Button。彩色样式,使用主题的colorButtonNormal表示禁用的颜色和启用的颜色。

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

If you want different colors than specified you can create a new theme and apply it to the button via android:theme. Then you can use this theme on all your buttons where you want same effect.

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

#4


4  

I had a similar problem i thought was due to wrongly inflated layouts, but it appeared that adding clipToPadding did the trick. This must be set to the parent ViewGroup containing the view you want to cast a shadow.

我有一个类似的问题,我认为是由于错误的膨胀布局,但是添加cliptopadd起到了作用。必须将其设置为包含要投射阴影的视图的父视图组。

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

…android:clipToPadding = " false "……

#5


0  

This solution works for all the API versions of Android

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

Create a shadow @android:drawable/dialog_holo_light_frame & if you want to customize the color of the background instead of white then create a layer-list background with customizable color on top of the shadow as shown below

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

Create a separate drawable file white_background_shadow.xml

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

and use this drawable as the background like this

用这个可绘制的作为背景

android:background="@drawable/shadow"