自定义View简单实现图片的手指移动和两指缩放
程序员文章站
2024-03-24 15:48:16
...
先看效果图:
直接上源码:
- 自定义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) {
if (pointerDistance < distance) { //如果上次两指的距离比这次小,说明是放大图片
setImgScale((float) (distance / pointerDistance));
} else if (pointerDistance > distance) { //缩小图片
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>
上一篇: HDU 2046 骨牌铺方格
下一篇: 4.使用 git commit 提交项目