it-roy-ru.com

Android 5.0 Android: высота работает для просмотра, но не кнопка?

В примерах Android 5.0 из SDK Manager есть образец 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 вместо View или Button по-прежнему дает нам тень, так что это изменение в поведении вводится не на уровне TextView, а скорее на уровне Button.

  3. Как видно из этот вопрос со вчерашнего дня, как мы можем получить Android:elevation для соблюдения Button? Есть ли какое-то значение Android:allowElevationToWorkAsDocumented="true", которое мы должны вставить в тему или что-то еще?

62
CommonsWare

Стиль кнопки по умолчанию в разделе Материал имеет StateListAnimator , который управляет свойствами Android:elevation и Android: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>
119
alanv

По моему опыту с Appcompat v7, работающим на устройстве Lollipop, Button работает с функциями по умолчанию, такими как эффект ряби, рельеф и z-анимация при щелчке, но пропускает их, если в персонализированном свойстве Android:background (как цвет или селектор) установлено значение в элементе xml.

13
GPack

Это потому, что вы устанавливаете фон кнопки вручную, который заменит все ее эффекты. 

Начиная с версии 23.0.0 release AppCompat , существует новый Widget.AppCompat.Button.Colored style, который использует colorButtonNormal вашей темы для отключенного цвета и colorAccent для включенного цвета ,.

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

Если вы хотите использовать цвета, отличные от указанных, вы можете создать новую тему и применить ее к кнопке с помощью Android:theme. Затем вы можете использовать эту тему на всех ваших кнопках, где вы хотите, чтобы тот же эффект.

7
Heisenberg

У меня была похожая проблема, которая, как мне показалось, была связана с неверно раздутыми макетами, но оказалось, что добавление clipToPadding помогло. Это должно быть установлено для родительского ViewGroup, содержащего представление, которое вы хотите отбросить тень.

... Android:clipToPadding="false" ...

5
Stefan Bushev

Это решение работает для всех версий API Android

Создайте тень @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"
0
Shyam Sunder