前言:客户要做一个需求,用户相册的照片选中后放大,这种需求在电视上有很多的应用场景,例如 应用图标获得焦点放大,视频页面的列表,于是先上github找了找(毕竟别人写好了,直接就拿来用,省事),但没找到合适,资源太少了,找到了库很大。于是决定自己弄一个
绘制
此时GridView已经绘制完成了,需要在getChildStaticTransformation((View child, Transformation t)做一些转换,在构造方法初始化设置
public ZoomGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//设置为true,才能调用getChildStaticTransformation()
setStaticTransformationsEnabled(true);
// 允许子类修改绘制顺序
setChildrenDrawingOrderEnabled(true);
}
对选中item进行缩放及缩放过程动画的业务处理
@Override
protected boolean getChildStaticTransformation(View child, Transformation t) {
t.setTransformationType(Transformation.TYPE_MATRIX);
if (child == getSelectedView() && child.isSelected()) {
final int selectedPosition = getSelectedItemPosition();
if (selectedPosition != mSelectedPosition) {
mSelectedPosition = selectedPosition;
mItemScale = 1.0f;
} else {
// 这里会调用多次,直到缩放到指定倍数
mItemScale += (mItemSelectedScale - 1) * 0.1f;
if (mItemSelectedScale < 1) {
if (mItemScale <= mItemSelectedScale) {
mItemScale = mItemSelectedScale;
} else {
// 每次间隔80毫秒绘制,是为了用户看到缩放过程没那么突兀
child.postInvalidateDelayed(80);
}
} else {
if (mItemScale >= mItemSelectedScale) {
mItemScale = mItemSelectedScale;
} else {
child.postInvalidateDelayed(80);
}
}
}
// 对item进行缩放
t.getMatrix().setScale(mItemScale, mItemScale, child.getWidth() / 2.0f, child.getHeight() / 2.0f);
} else {
// 设置未选中item为原来的大小
t.getMatrix().setScale(1.0f, 1.0f);
}
return true;
}
// 改变绘制的顺序,避免放大后会覆盖其他的item
@Override
protected int getChildDrawingOrder(int childCount, int i) {
final int selectedIndex = getSelectedItemPosition() - getFirstVisiblePosition();
if (selectedIndex < 0) {
return i;
}
if (i < selectedIndex) {
return i;
}
if (i == childCount - 1) {
return selectedIndex;
}
return i + 1;
}