一直好奇酷狗的皮肤预览是怎么实现的。
难道是另外写了一个一模一样的布局文件,只是宽高不一样?
感觉贼吉尔神奇啊!
记得看完,后面有惊喜
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
想想还是觉得不可能是一个个控件写上去的,一定有某种极其神奇却简单的方法。
方法就是
在这里插入图片描述
Android Canvas的scale,画布缩放/**
* Preconcat the current matrix with the specified scale.
*
* @param sx The amount to scale in X
* @param sy The amount to scale in Y
*/
public void scale(float sx, float sy) {
native_scale(mNativeCanvasWrapper, sx, sy);
} /**
* Preconcat the current matrix with the specified scale.
*
* @param sx The amount to scale in X
* @param sy The amount to scale in Y
* @param px The x-coord for the pivot point (unchanged by the scale)
* @param py The y-coord for the pivot point (unchanged by the scale)
*/
public final void scale(float sx, float sy, float px, float py) {
translate(px, py);
scale(sx, sy);
translate(-px, -py);
}
//x缩放比例,y缩放比例,px,py,缩放中心点,可以设置左顶点或者中心等顶点
canvas.scale(scale, scale, px, py);
只需要2步就能实现仿酷狗皮肤预览缩放效果:
1.先测量期望缩放至的宽高,然后将宽高设置为被缩放View的宽高@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
width_self=getMeasuredWidth();
height_self=getMeasuredHeight(); super.onMeasure(MeasureSpec.makeMeasureSpec(
width_bigview, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height_bigview, MeasureSpec.EXACTLY));
}
2.计算scale缩放比例,如果以宽为基准缩放,那就是期望缩放至的宽度/被缩放View的宽度;如果以高为基准缩放,同理@Override
protected void dispatchDraw(Canvas canvas) { if (basedOnWidthOrHeight) {
scale = (width_self - getPaddingTop() - getPaddingBottom()) * 1f / width_bigview;
} else {
scale = (height_self - getPaddingTop() - getPaddingBottom()) * 1f / height_bigview;
}
PaintFlagsDrawFilter pfd= new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG); /**
* 对canvas设置抗锯齿的滤镜,防止变化canvas引起画质降低
*/
canvas.setDrawFilter(pfd);
canvas.save(); //x缩放比例,y缩放比例,px,py,缩放中心点,可以设置左顶点或者中心等顶点
canvas.scale(scale, scale, px, py); super.dispatchDraw(canvas);
canvas.restore();
}在这里插入代码片
上图:模拟器截图有点模糊,真实手机是没毛病的
在这里插入图片描述
以中心点 为缩放中心
在这里插入图片描述
以左顶点为缩放中心
在这里插入图片描述
完整代码:
在这里插入图片描述
<?xml version="1.0" encoding="utf-8"?>
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scaleType="centerInside"
android:class="lazyload" src="https://img-blog.csdnimg.cn/2022010707514916078.png" data-original="@drawable/pic" />
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="缩放布局" />
public class MainActivity extends BaseActivity { @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
startAppcompatActivity(ScaleViewActivity.class);
}
});
} @Override
public void onClick(View v) {
}
}<?xml version="1.0" encoding="utf-8"?>
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_scale_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
public class ScaleViewActivity extends AppCompatActivity { @Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scale_view);
View layout = LayoutInflater.from(this).inflate(R.layout.activity_main, null);
ScaleFrameLayout scaleFrameLayout = new ScaleFrameLayout(this);
scaleFrameLayout.setLayoutParams(new RelativeLayout.LayoutParams(500,1300));
scaleFrameLayout.addView(layout);// scaleFrameLayout.config(false, ScreenUtils.getScreenWidth(this),ScreenUtils.getScreenHeight(this),// ScreenUtils.getScreenWidth(this)/2,ScreenUtils.getScreenHeight(this)/2);
scaleFrameLayout.config(false, ScreenUtils.getScreenWidth(this),ScreenUtils.getScreenHeight(this),0,0);
RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.activity_scale_view);
relativeLayout.addView(scaleFrameLayout);
}
}public class ScaleFrameLayout extends FrameLayout { private float scale = 1f; private int width_self, height_self; private int width_bigview = 0, height_bigview = 0; private boolean basedOnWidthOrHeight = true;//默认基于宽度,按比例缩放
private Context context; private float px,py;//缩放中心点
public ScaleFrameLayout(Context context) { super(context); this.context = context;
} public ScaleFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); this.context = context;
} public void config(boolean basedOnWidthOrHeight,int width_bigview, int height_bigview,float px, float py) { this.basedOnWidthOrHeight=basedOnWidthOrHeight; this.width_bigview = width_bigview; this.height_bigview = height_bigview; if (this.width_bigview == 0) this.width_bigview = ScreenUtils.getScreenWidth(context); if (this.height_bigview == 0) this.height_bigview = ScreenUtils.getScreenHeight(context); this.px=px; this.py=py;
invalidate();
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec));
width_self=getMeasuredWidth();
height_self=getMeasuredHeight(); super.onMeasure(MeasureSpec.makeMeasureSpec(
width_bigview, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height_bigview, MeasureSpec.EXACTLY));
} @Override
protected void dispatchDraw(Canvas canvas) { if (basedOnWidthOrHeight) {
scale = (width_self - getPaddingTop() - getPaddingBottom()) * 1f / width_bigview;
} else {
scale = (height_self - getPaddingTop() - getPaddingBottom()) * 1f / height_bigview;
}
PaintFlagsDrawFilter pfd= new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG); /**
* 对canvas设置抗锯齿的滤镜,防止变化canvas引起画质降低
*/
canvas.setDrawFilter(pfd);
canvas.save(); //x缩放比例,y缩放比例,px,py,缩放中心点,可以设置左顶点或者中心等顶点
canvas.scale(scale, scale, px, py); super.dispatchDraw(canvas);
canvas.restore();
}
}
其实缩放还有更简单的操作
不需要自定义viewview.setPivotX(ScreenUtils.getScreenWidth(context) / 2);
view.setPivotY(0);
view.setScaleX(scale);
view.setScaleY(scale);
Canvas缩放还可用于广告中,缩放广告View
在这里插入图片描述
作者:小编学IT
链接:https://www.jianshu.com/p/40112957b17b