原生ImageView可设置的scaleType有fitCenter、fitEnd、fitXY、centerInside等。
有时候,会有"fitBottom"+centerInside的需求。
效果如下图:
ps:控件的background设置为红色,用于感知控件宽高。
实现的原理是重写ImageView的onDraw方法。在绘制drawable的时候,如果图片宽高小于控件的宽高,那么就将图片绘制于控件底部居中位置,否则按父类的逻辑去绘制。
代码如下:(用法跟ImageView一样,该咋用就咋用。)
class FitBottomImageView : AppCompatImageView {
private var mVWidth: Int = 0
private var mVHeight: Int = 0
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
//获取控件的宽高
mVWidth = measuredWidth
mVHeight = measuredHeight
}
override fun onDraw(canvas: Canvas) {
val imageDrawable = drawable ?: return
val bounds = imageDrawable.bounds
//获取图片的宽高
val width = bounds.width()
val height = bounds.height()
if (width > mVWidth || height > mVHeight) {
//按原生的逻辑去绘制
super.onDraw(canvas)
} else {//图片的宽高小于控件的宽高
//底部居中位置绘制
canvas.save()
canvas.translate(((mVWidth - width) / 2).toFloat(), (mVHeight - height).toFloat())
imageDrawable.draw(canvas)
canvas.restore()
}
}
}