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, запустив образец как есть, мы получаем тень на круге:
Если мы изменим класс виджета на Button
оставляя все остальные атрибуты как есть, мы теряем тень на круге:
Вопросы:
Почему
android:elevation
поведение меняется? Это не может быть связано с фоном, потому что в обоих случаях это один и тот же фон.Какие классы поддерживают
android:elevation
а чего нет? Например, используяTextView
вместоView
или жеButton
до сих пор дает нам тень, так что это изменение в поведении не вводится наTextView
уровень, а точнее наButton
уровень.Как видно из вчерашнего вопроса, как мы получаем
android:elevation
быть удостоенным чести наButton
? Есть ли некоторыеandroid:allowElevationToWorkAsDocumented="true"
значение, которое мы должны положить в тему или что-то?
5 ответов
Стиль кнопки по умолчанию в разделе Материал имеет 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>
По моему опыту с Appcompat v7, работающим на устройстве Lollipop, Button
работает с функциями по умолчанию, такими как волновой эффект, рельеф и z-анимация при нажатии, но пропускает их, если установлен персонализированный android:background
свойство (как цвет или селектор) в элементе xml.
Это потому, что вы устанавливаете фон кнопки вручную, который заменит все ее эффекты.
Начиная с версии 23.0.0 AppCompat, появился новый стиль Widget.AppCompat.Button.Colored, который использует colorButtonNormal вашей темы для отключенного цвета и colorAccent для включенного цвета.
<Button
...
style="@style/Widget.AppCompat.Button.Colored" />
Если вы хотите использовать цвета, отличные от указанных, вы можете создать новую тему и применить ее к кнопке с помощью android:theme
, Затем вы можете использовать эту тему на всех ваших кнопках, где вы хотите, чтобы тот же эффект.
У меня была похожая проблема, которая, как мне показалось, была связана с неправильно раздутыми макетами, но оказалось, что добавление clipToPadding
сделал трюк. Это должно быть установлено для родителя ViewGroup
содержащий вид, который вы хотите отбросить тень.
...
android:clipToPadding="false"
...
Это решение работает для всех версий 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"