如何自定义FloatingActionButton的大小
Google最近为了让开发者更好的更规范的应用Material Design设计思想,特意放出了android support design library,里面含有更多Material Design的标志性组件,其中最常用的就是那个圆形按钮,叫做Floating Action Button,可以简称为FAB。一个使用该控件的例子为:
<android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:layout_marginLeft="25dp" android:layout_gravity="start|top" app:borderWidth="0dp" app:fabSize="normal" app:elevation="4dp" android:scaleType="center" android:src="@drawable/btn_menu" />
注意,在跟布局中需要配置app这个命令空间:
xmlns:app="http://schemas.android.com/apk/res-auto"
这里关注FAB的app:fabSize这个属性,它是用来规定大小,但是发现只有两个值:mini和normal,默认情况下官方推荐的宽高是56dp,但是如果设计师需要你显示一个比较大一些的FAB,比如100dp(这里发现将fabSize设置成normal或者mini都很小),该怎么办?
第一反应是修改layout_height和layout_width这两个属性,将他们设置成100dp,最后却发现成了这个怂样:
看来改变上述两个属性是不行的,那么我们来看FloatingActionButton的源码,在它的构造函数中,有下列代码:
ShadowViewDelegate delegate = new ShadowViewDelegate() { public float getRadius() { return (float)FloatingActionButton.this.getSizeDimension() / 2.0F; } public void setShadowPadding(int left, int top, int right, int bottom) { FloatingActionButton.this.mShadowPadding.set(left, top, right, bottom); FloatingActionButton.this.setPadding(left + FloatingActionButton.this.mContentPadding, top + FloatingActionButton.this.mContentPadding, right + FloatingActionButton.this.mContentPadding, bottom + FloatingActionButton.this.mContentPadding); } public void setBackgroundDrawable(Drawable background) { FloatingActionButton.super.setBackgroundDrawable(background); } }; if(VERSION.SDK_INT >= 21) { this.mImpl = new FloatingActionButtonLollipop(this, delegate); } else { this.mImpl = new FloatingActionButtonEclairMr1(this, delegate); }
这里的mImpl是一个FloatingActionButtonImpl的实现类,FloatingActionButton大部分的操作实际上都是在操作这个mImpl,这个mImpl在被new出来的时候会判断当前环境是不是API level大于等于21(实际上在小于21的时候,他用drawable绘制了一层阴影从而有类似于21以上的evevation的效果),随后创建mImpl的时候传入了delegate这个参数,ShadowViewDelegate实际上就是个drawable的包装类。我们看getRadius这个实现方法,显然它是计算半径的,所以要想定制FAB的宽高,得要从这里找文章。
具体看getSizeDimension这个方法:
final int getSizeDimension() { switch(this.mSize) { case 0: default: return this.getResources().getDimensionPixelSize(dimen.fab_size_normal); case 1: return this.getResources().getDimensionPixelSize(dimen.fab_size_mini); } }
原来app:fabSize实际上是在调用fab_size_normal和fab_size_mini这两个dimen的值,相应的对应了normal和mini这两种情况,那么我们可以想到在我们的代码中国同样定义这两个dimen值对原来的进行覆盖,于是我们在醒目代码的dimen.xml中定义:
<resources> <dimen name="fab_size_normal">100dp</dimen> </resources>
这个时候再看效果:
修改成功
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?