GitHub_https://github.com/AnJiaoDe/Scale-Master
APKdemo_https://github.com/AnJiaoDe/Scale-Master/blob/master/app/build/outputs/apk/app-debug.apk
Always wondering how cool Dog skin preview works. Did you write an identical layout file with different width and height? Feels like the thief Jill is amazing!
Think about it or feel that it is impossible to write up a control, there must be some extremely magical but simple method. Approach is to
Android Canvas scale, Canvas scaling
/**
* 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);
}Copy the code
//x scale, y scale, px,py, scale center point, you can set the left vertex or center vertex
canvas.scale(scale, scale, px, py);
Just 2 steps to get a cool dog skin preview zoom effect:
1. Measure the desired width and height, and then set the width and height to the width and height of the View being scaled
@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));
}Copy the code
2. Calculate the scale scale. If the scale is based on the width, that is the desired width/the width of the View being scaled. Same thing if you scale in height
@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. SetDrawFilter (PFD); canvas.save(); // canvas. Scale (scale, scale, px,py); // Canvas. super.dispatchDraw(canvas); canvas.restore(); }Copy the code
Insert the code slice hereCopy the code
Image above: The emulator screenshot is a little blurry, the real phone is fine
Use the center point as the zoom center
Scale with the left vertex as the center
Complete code:
<? The XML version = "1.0" encoding = "utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/layout" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ImageView android:id="@+id/iv" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:scaleType="centerInside" android:src="@drawable/pic" /> <Button android:id="@+id/btn" Android :layout_width="match_parent" Android: Layout_height ="wrap_content" Android :text=" zoom layout "/> </LinearLayout>Copy the code
public class MainActivity extends BaseActivity { @Override protected 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) { } }Copy the code
<? The XML version = "1.0" encoding = "utf-8"? > <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_scale_view" android:layout_width="match_parent" android:layout_height="match_parent"> </RelativeLayout>Copy the code
public class ScaleViewActivity extends AppCompatActivity { @Override protected 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 (500130)); 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); }}Copy the code
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; // Default width based, scale 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. SetDrawFilter (PFD); canvas.save(); // canvas. Scale (scale, scale, px,py); // Canvas. super.dispatchDraw(canvas); canvas.restore(); }}Copy the code
Canvas zooming can also be used in ads, zooming the AD View
Welcome to contact, correct, criticize and quarrel if you have any questions
GitHub
Common open source libraries for Android development
Jane’s book
Wechat official account
QQ group