一.Matrix讲解
Matrix讲解请移步以下博客:
Matrix01
个人总结:
- Matrix是一个3 * 3矩阵(Matrix矩阵 * 原矩阵 =最终的效果),矩阵中的每个数字有不同的含义;通过改变矩阵,可以控制:平移,缩放,错切,旋转
- Matrix混合:pre : 右乘, M‘ = M*A ; post : 左乘, M’ = A*M
- 面向对象方式理解Matrix: Matrix是一个对象,不仅有平移,缩放,错切,旋转等方法(api),还包含各种操作的方法和各种信息;
- 应用:Camare,Canvas,Shader,setPolyToPoly等等;
二.Matrix小练习
public class MatrixImageView extends ImageView {
//缩放模式
private static final int ZOOM = 1;
//默认模式
private static final int NONE = 2;
//距离
private static final float DISTANCE = 10F;
private int mode = NONE;
//缩放中心点
private PointF midIndex;
//前一步操作的Matrix对象
private Matrix preMatrix;
//当前操作的Matrix对象
private Matrix currentMatrix;
//存放Matrix信息的数组
private float[] matrixArray;
//两点间的距离
private float distance;
public MatrixImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
/**
* 初始化
*/
private void init() {
preMatrix = new Matrix();
currentMatrix = new Matrix();
matrixArray = new float[9];
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
midIndex = new PointF(getMeasuredWidth() / 2 , getMeasuredHeight() / 2);
Bitmap bitmap = BitmapFactory.decodeResource(getResources() , R.drawable.meizi);
bitmap = Bitmap.createScaledBitmap(bitmap, getMeasuredWidth(), getMeasuredHeight(), true);
setImageBitmap(bitmap);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
//支持多点触控
switch (event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN://单击
return true;//事件分发
case MotionEvent.ACTION_POINTER_DOWN://第二个点接触屏幕
distance = pointDistance(event);
if (distance > DISTANCE){
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP://单点离开屏幕
scaleXY();
break;
case MotionEvent.ACTION_POINTER_UP://第二个点离开屏幕
break;
case MotionEvent.ACTION_MOVE://滑动
if (mode == ZOOM && event.getPointerCount() == 2){
float v = pointDistance(event);
if (v > DISTANCE){
float scale = v / distance;
currentMatrix.setScale(scale , scale , midIndex.x , midIndex.y);
}
}
break;
}
currentMatrix.getValues(matrixArray);
setImageMatrix(currentMatrix);
return super.onTouchEvent(event);
}
/**
* 计算两个触摸点之间的距离
* @param event
* @return
*/
private float pointDistance(MotionEvent event){
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
/**
* 缩小
*/
private void scaleXY(){
float width = getWidth() * matrixArray[0];
float height = getHeight() * matrixArray[4];
PointF startPoint = new PointF(width, height);
PointF endPoint = new PointF(getWidth(), getHeight());
ValueAnimator valueAnimator = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
valueAnimator.setDuration(500);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF animatedValue = (PointF) animation.getAnimatedValue();
currentMatrix.setScale(animatedValue.x / getWidth(), animatedValue.y / getHeight(), getWidth() / 2, getHeight() / 2);
setImageMatrix(currentMatrix);
}
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
currentMatrix.reset();
setImageMatrix(currentMatrix);
}
});
}
/**
* 自定义估值器
*/
class PointEvaluator implements TypeEvaluator<PointF> {
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
float x = startValue.x + fraction * (endValue.x - startValue.x);
float y = startValue.y + fraction * (endValue.y - startValue.y);
PointF point = new PointF(x, y);
return point;
}
}
}
<com.jiao.matrixdemo.MatrixImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="matrix" />