zoukankan      html  css  js  c++  java
  • PTZView

    效果图以及相关的两张图片资源:

    实现步骤:

    1. 继承View
    2. 重写onTouchEvent,根据触摸坐标计算角度
    3. 重写onDraw,根据角度旋转并绘制图片

    代码如下:

      1 import android.annotation.SuppressLint;
      2 import android.content.Context;
      3 import android.content.res.Resources;
      4 import android.graphics.Bitmap;
      5 import android.graphics.BitmapFactory;
      6 import android.graphics.Canvas;
      7 import android.graphics.Matrix;
      8 import android.graphics.Paint;
      9 import android.util.AttributeSet;
     10 import android.view.MotionEvent;
     11 import android.view.View;
     12 
     13 import androidx.annotation.IntDef;
     14 
     15 /**
     16  * 自定义云台控件
     17  * <p>2020-06-02: create by zenghm
     18  */
     19 public class PTZView extends View {
     20 
     21     public static final int NONE = 0;
     22     public static final int TOP = 1;
     23     public static final int BOTTOM = 2;
     24     public static final int LEFT = 3;
     25     public static final int RIGHT = 4;
     26 
     27     @IntDef({NONE, LEFT, TOP, RIGHT, BOTTOM})
     28     public @interface Direction {
     29     }
     30 
     31     public interface DirectionChangedListener {
     32         /**
     33          * 方向变化回调
     34          *
     35          * @param oldDirection 之前的方向
     36          * @param curDirection 当前的方向
     37          */
     38         void onDirectionChanged(PTZView view, @Direction int oldDirection, @Direction int curDirection);
     39     }
     40 
     41     private DirectionChangedListener mListener;
     42     @Direction
     43     private int mDirection = NONE;
     44     private float mCenterX, mCenterY;
     45     private float mAngel = 0;
     46 
     47     private Bitmap mDefaultBitmap;
     48     private Bitmap mPressBitmap;
     49     private Matrix mMatrix = new Matrix();
     50     private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     51 
     52     public PTZView(Context context) {
     53         this(context, null, 0);
     54     }
     55 
     56     public PTZView(Context context, AttributeSet attrs) {
     57         this(context, attrs, 0);
     58     }
     59 
     60     public PTZView(Context context, AttributeSet attrs, int defStyle) {
     61         super(context, attrs, defStyle);
     62         // 加载资源
     63         Resources res = context.getResources();
     64         mDefaultBitmap = BitmapFactory.decodeResource(res, R.drawable.ptz_default);
     65         mPressBitmap = BitmapFactory.decodeResource(res, R.drawable.ptz_press);
     66     }
     67 
     68     public void setOnDirectionChangedListener(DirectionChangedListener listener) {
     69         mListener = listener;
     70     }
     71 
     72     @Override
     73     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
     74         super.onSizeChanged(w, h, oldw, oldh);
     75         mCenterX = (float) w / 2;
     76         mCenterY = (float) h / 2;
     77     }
     78 
     79     @Override
     80     protected void onDraw(Canvas canvas) {
     81         super.onDraw(canvas);
     82         Bitmap bitmap = isPressed() ? mPressBitmap : mDefaultBitmap;
     83         // 计算图片缩放
     84         float sx = (float) getWidth() / bitmap.getWidth();
     85         float sy = (float) getHeight() / bitmap.getHeight();
     86         // 设置变换矩阵(缩放、旋转)
     87         mMatrix.reset();
     88         mMatrix.postScale(sx, sy);
     89         mMatrix.postRotate(-mAngel, mCenterX, mCenterY);
     90         // 绘制图片
     91         canvas.drawBitmap(bitmap, mMatrix, mPaint);
     92     }
     93 
     94     @SuppressLint("ClickableViewAccessibility")
     95     @Override
     96     public boolean onTouchEvent(MotionEvent event) {
     97         //super.onTouchEvent(event);
     98         if (!isEnabled())
     99             return false;
    100 
    101         switch (event.getAction()) {
    102             case MotionEvent.ACTION_DOWN:
    103                 setPressed(true);
    104                 postInvalidate();
    105                 break;
    106 
    107             case MotionEvent.ACTION_UP:
    108             case MotionEvent.ACTION_CANCEL:
    109                 if (mListener != null) {
    110                     mListener.onDirectionChanged(this, mDirection, NONE);
    111                 }
    112                 mDirection = NONE;
    113                 mAngel = 0;
    114                 setPressed(false);
    115                 postInvalidate();
    116                 break;
    117 
    118             case MotionEvent.ACTION_MOVE:
    119                 // 计算角度
    120                 float x = event.getX() - mCenterX;
    121                 float y = mCenterY - event.getY();
    122                 mAngel = (float) (Math.atan2(y, x) / Math.PI * 180);
    123                 // 重新绘制
    124                 postInvalidate();
    125                 // 根据角度判断方向
    126                 int direction;
    127                 if (mAngel > -45 && mAngel <= 45) {
    128                     direction = LEFT;
    129                 } else if (mAngel > 45 && mAngel <= 135) {
    130                     direction = TOP;
    131                 } else if (mAngel <= -45 && mAngel > -135) {
    132                     direction = BOTTOM;
    133                 } else {
    134                     direction = RIGHT;
    135                 }
    136                 // 回调方向变化
    137                 if (mListener != null && mDirection != direction) {
    138                     mListener.onDirectionChanged(this, mDirection, direction);
    139                 }
    140                 mDirection = direction;
    141                 break;
    142 
    143             default:
    144                 break;
    145         }
    146         return true;
    147     }
    148 }

     【注】可以通过自定义属性传入图片,增强控件的自定义能力。自定义属性不在本文的讨论范围。

    谢谢阅读,如有谬误,多谢指正。

  • 相关阅读:
    centos7.3 安装 mysql5.7.13
    linux下MySQL的启动与访问
    使用jquery修改display属性
    浏览器在线预览pdf、txt、office文件
    查看java的jar包源码
    邮件群发器
    公司招聘asp.net程序员(已过期)
    javascript面向对象,实现namespace,class,继承,重载
    javascript window.close() 去掉那讨厌的确认对话框
    如果注定要分别
  • 原文地址:https://www.cnblogs.com/zenghm/p/13041892.html
Copyright © 2011-2022 走看看