自定义View简单实现图片的手指移动和两指缩放

先看效果图:

直接上源码:

  • 自定义View类
public class MyView extends View {
    private Matrix matrix;
    private Bitmap bitmap;
    private Paint paint;
    private float currentX,currentY;     //当前手指所在屏幕的位置坐标
    private double pointerDistance=-1;   //两指间的距离
    private boolean isScaling=false;    //是否正在缩放,用来区分位移和缩放的行为
    private float imgScale=1;           //图片要缩放的比例
    public MyView(Context context) {
        super(context);
        init();
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        matrix.reset();
        //参数1:宽度缩放比;参数2:高度缩放比;参数3:旋转中心点的x点值;参数4:旋转中心点的y点值
        //这里是等比例缩放,并将中心点设为图片中心
        matrix.postScale(imgScale,imgScale,currentX-(bitmap.getWidth()*imgScale)/2,currentY-(bitmap.getHeight()*imgScale)/2);
        canvas.save();
        canvas.concat(matrix);
        //参数1:位图;参数2:图片左上角点的x点值;参数3:图片左上角点的y点值
        //这里设置为图片在屏幕中心
        canvas.drawBitmap(bitmap,currentX-(bitmap.getWidth()*imgScale)/2,currentY-(bitmap.getHeight()*imgScale)/2,paint);
        canvas.restore();
    }

    private void init(){    //初始化控件
        matrix=new Matrix();
        bitmap= BitmapFactory.decodeResource(getResources(),R.mipmap.avatar);   //设置图片
        paint=new Paint();
        currentX=Constants.SCREEN_WIDTH/2;
        currentY=Constants.SCREEN_HEIGHT/2;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x=event.getX();
        float y=event.getY();
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                pointerDistance=-1;
                break;
            case MotionEvent.ACTION_MOVE:
                if(event.getPointerCount()==2) {    //是否是两个手指在按屏幕
                    isScaling=true;
                    if(touchBitmap(x,y)){   //是否手指处在图片内部
                        float x1=event.getX(1);
                        float y1=event.getY(1);
                        double distance=Math.sqrt((x-x1)*(x-x1)+(y-y1)*(y-y1));
                        if(pointerDistance>0) {
                            setImgScale((float) (distance / pointerDistance));//设置缩放比例
                        }
                        pointerDistance=distance;
                    }
                }else{  //单指
                    if(!isScaling && touchBitmap(x,y)){   //不在缩放图片 并且 手指处在图片内部
                        currentX=x;
                        currentY=y;
                        invalidate();
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                isScaling=false;
                break;
        }
        return true;
    }

    public void initPosition(int width,int height){ //设置初始时的View中心点位置
        currentX=width;
        currentY=height;
    }

    private boolean touchBitmap(float x,float y){   //是否手指处在图片内部
        return x>=currentX-(bitmap.getWidth()*imgScale)/2&&x<=currentX+(bitmap.getWidth()*imgScale)/2
                &&y>=currentY-(bitmap.getHeight()*imgScale)/2&&y<=currentY+(bitmap.getHeight()*imgScale)/2;
    }

    private void setImgScale(float scale){      //设置缩放比例
        imgScale=imgScale*scale;
        invalidate();
    }
}
  • 在MainActivity中的使用
public class MainActivity extends AppCompatActivity {
    private MyView myView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initWindow();
        initView();
    }

    private void initView(){
        myView=findViewById(R.id.myview);
        //设置View的中心点位置
        myView.initPosition(Constants.SCREEN_WIDTH/2,Constants.SCREEN_HEIGHT/2);
    }

    private void initWindow(){  //获取屏幕尺寸
        Display display=getWindowManager().getDefaultDisplay();
        Constants.SCREEN_WIDTH=display.getWidth();
        Constants.SCREEN_HEIGHT=display.getHeight();
    }

}
  • 最后是布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--这里改成自己的包名-->
    <com.myviewtext.MyView
        android:id="@+id/myview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

猜你喜欢

转载自blog.csdn.net/zz51233273/article/details/107203730