android - Android - 更改高度时阴影大小不受影响
问题描述
我正在开发一个针对 android Lollipop 及更高版本的 Android 应用程序,我查看了海拔属性以在元素(即按钮、卡片和底部导航视图)下实现阴影。
我面临的问题是,在android:elevation
XML 中更改值时,阴影大小不受影响。我尝试并阅读的内容:
- 我读过除非视图有背景,否则海拔不起作用,我的背景确实有(发布在下面)。
- SO周围的其他问题表明它们根本没有阴影,在我的情况下,我确实在视图下有一个阴影,但它的大小不受海拔属性的影响。
关于代码,您可以在我的按钮样式和片段布局下方找到。
按钮样式
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:app="http://schemas.android.com/apk/res-auto">
<style name="Search" parent="@android:style/Widget.Button">
<item name="android:gravity">center_vertical|start</item>
<item name="android:textColor">@color/lightText</item>
<item name="android:textSize">@dimen/main_search_textSize</item>
<item name="android:background">@drawable/main_search</item>
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:text">@string/search</item>
<item name="android:elevation">@dimen/main_search_elevation</item>
<item name="android:drawableStart">@drawable/ic_main_search</item>
<item name="android:paddingLeft">@dimen/main_search_padding</item>
<item name="android:paddingRight">@dimen/main_search_padding</item>
<item name="android:drawablePadding">@dimen/main_search_padding</item>
</style>
</resources>
片段布局
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingStart="@dimen/activity_horizontal_margin"
android:paddingEnd="@dimen/activity_horizontal_margin"
android:background="@color/lightBackground"
android:clipToPadding="false">
<androidx.appcompat.widget.AppCompatButton
style="@style/Search"
android:layout_width="match_parent"
android:layout_height="@dimen/main_search_height"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
尺寸.xml
<resources>
<dimen name="activity_horizontal_margin">24dp</dimen>
<dimen name="activity_vertical_margin">24dp</dimen>
<dimen name="main_nav_icon_padding">6dp</dimen>
<dimen name="main_search_height">54dp</dimen>
<dimen name="main_search_marginTop">72dp</dimen>
<dimen name="main_search_elevation">24dp</dimen>
<dimen name="main_search_padding">16dp</dimen>
<dimen name="main_search_textSize">20sp</dimen>
</resources>
这就是我得到的(无论高程属性是什么):
请注意,长按按钮时阴影会发生变化,并且不会以任何方式被剪裁。
因此,任何想法似乎是什么问题?
解决方案
嘿,你的问题似乎真的很有用,所以我决定试一试。我希望这对你有帮助,如果有人有更好的方法发布它。
首先,我认为主要问题是您使用的 Button Style 有一些StateListAnimator控制按钮的高度,因此无论您设置什么值作为高度,它都会被覆盖。最简单的解决方案是简单地添加
<item name="android:stateListAnimator">@null</item>
到您的自定义“搜索”样式,现在该按钮将显示您正在使用<item name="android:elevation">@dimen/main_search_elevation</item>
相同样式设置的高程。
但这就像一个静态视图,当你点击或长按等时,它会给你一个提升的外观,但没有很酷的动画变化。
为了拥有这些动画,您需要使用 ObjectAnimator 创建自定义StateListAnimator。我创建了一个作为示例。创建 android 资源目录animator
并添加一个 xml 文件,您将在其中编写所需的自定义动画。
这是我创建的custom_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--For when your button is pressed-->
<item
android:state_enabled="true"
android:state_pressed="true">
<set>
<objectAnimator
android:duration="300"
android:propertyName="translationZ"
android:valueTo="12dp"
android:valueType="floatType" />
<objectAnimator
android:duration="300"
android:propertyName="elevation"
android:valueTo="12dp"
android:valueType="floatType" />
</set>
</item>
<!--For when your button is in its normal state-->
<item android:state_enabled="true">
<set>
<objectAnimator
android:duration="300"
android:propertyName="translationZ"
android:valueTo="4dp"
android:valueType="floatType" />
<objectAnimator
android:duration="300"
android:propertyName="elevation"
android:valueTo="4dp"
android:valueType="floatType" />
</set>
</item>
</selector>
您需要根据您的要求设置自定义尺寸,以了解按钮何时处于其基本状态以及何时被按下。我分别使用了4dp
和,12dp
因为它似乎绰绰有余
就是这样,现在您只需将其作为 stateListAnimator 添加到您的样式中
<item name="android:stateListAnimator">@animator/custom_animator</item>
它应该可以工作。请注意,在这种情况下,android:elevation
只有在您的动画师中定义的值才会反映。因此,您可以删除<item name="android:elevation">@dimen/main_search_elevation</item>
它,因为它不需要。
参考了一些关于 SO 的媒体和其他帖子的博客,以了解这一切是如何工作的。试试这个,让我们知道它是否对你有用。
推荐阅读
- postgresql - Oracle 和 Postgres 客户端代码在同一个任务中?
- biztalk - 根据值将 Biztalk 平面文件消息分批成单独的分组平面文件
- html - 联系表格的定位问题(试图居中)
- amazon-redshift - 如何使用多个 DDL 语句执行文件
- redux - 在数组 redux 中更新数组
- r - 尝试安装 R 包“生命周期”时 loadNamespace 出错
- excel - 对活动单元格上方的单元格范围求和,单元格范围间隔为 3 列
- python - 如何使用 Python 将图像插入到现有 Word 文档中的特定位置?
- powerbi - 如何自定义 Power BI 模板应用的数据集
- c - 如何避免 // c 词法分析器使用 flex 的注释