在应用开发中,为了友好的用户体验,我们常常需要在文字旁边添加 ICON,因为用户对图形的感知往往要强于文字,比如这样子:
大多数新手看一眼觉得很简单,使用 ImageView
和 TextView
组合即可。
的确,这是一种很简单的方法,但如上图中使用 GridLayout
来展示多个子项,明明 ICON 和文字属于同一项,组合写法会导致代码成倍增加,再加上需要用一个父容器(如 LinearLayout
)来包裹这两个子项,布局文件就如老太太的裹脚布——又长又臭。
当然,你也可以把这个组合抽取出来,做成 Adapter
通用,尽管布局清晰了,但逻辑代码也增加不少。
实际上,Android 本身就为 TextView
提供了此功能,我们只需一行代码就可以使用:
<TextView
...
android:drawableTop="@drawable/ic_drawable" />
该属性可以为 TextView
在某一方向上添加对应的 Drawable
,其他方向只需修改属性中的方向名称即可。
AppCompat
提供了一些 Compat
属性,所以你也可以这样写:
<TextView
...
app:drawableTopCompat="@drawable/ic_drawable" />
如果你想调整 Drawable
和文字的间隔,可以使用这个属性:
<TextView
...
android:drawablePadding="16dp"
app:drawableTopCompat="@drawable/ic_drawable" />
当 Drawable
尺寸过大时,你可能会注意到 Drawable
和文字并不是居中的,这时你要牢记,这个 Drawable
也是 TextView
的一部分:
对于 View
或 ViewGroup
内部元素的对齐方式,我们通常可以使用:
<TextView
...
android:gravity="center"
app:drawableTopCompat="@drawable/ic_drawable" />
假如你需要在逻辑代码中动态修改该 Drawable
,同样提供支持:
textView.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_drawable), null, null, null);
setCompoundDrawablesWithIntrinsicBounds()
方法接收四个参数,分别是四个方向上的 Drawable
资源,在对应方向传入所需的 Drawable
即可。
该方法同时也支持以资源 ID 的方式传入 Drawable
,所以也可以这样写:
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_drawable, 0, 0, 0);
当你觉得这个功能挺好用时,假如美工让你调整一下 Drawable
的大小,你可能一下子就懵了,似乎找不到这个属性,还不如 ImageView
和 TextView
组合来得方便呀。
的确,在布局文件中没有调整 Drawable
尺寸的属性,但你要记得,这是一个 Drawable
,既然是 Drawable
,我们就可以通过逻辑代码控制它的尺寸:
Drawable drawable = getResources().getDrawable(R.drawable.ic_account);
drawable.setBounds(0, 0, 180, 180); // 设置图片的大小
textView.setCompoundDrawables(drawable, null, null, null); // 设置图片的位置
Drawable
的 setBounds()
方法接收四个参数,四个坐标形成一个矩形,Drawable
将在被绘制在这个矩形区域内。
接着调用的 setCompoundDrawables()
和上面提到的 setCompoundDrawablesWithIntrinsicBounds()
类似,将 Drawable
传入到对应位置即可。
另外我们知道,EditText
实际上是继承于 TextView
的,那么 EditText
也会有相同的属性,所以我们可以轻而易举的实现类似的功能:
属性和方法基本和 TextView
一致,不再重复贴代码。