自定义View实现图片热区效果
我司主要从事工业物联网领域软件的开发,现有个需求,在外废品处理时需要对产品的不良位置进行标记,点选图片实现图片网格的着色功能。
需求是通过自定义view来实现,实现思路如下:
首先将点击的小方格对象实例化,创建小方格PointBean对象
/** * 图片上的点 */ public class PointBean { private int x_max; private int x_mix; private int y_min; private int y_max; private String picPointName; public String getPicPointName() { return picPointName; } public void setPicPointName(String picPointName) { this.picPointName = picPointName; } public int getX_max() { return x_max; } public void setX_max(int x_max) { this.x_max = x_max; } public int getX_mix() { return x_mix; } public void setX_mix(int x_mix) { this.x_mix = x_mix; } public int getY_min() { return y_min; } public void setY_min(int y_min) { this.y_min = y_min; } public int getY_max() { return y_max; } public void setY_max(int y_max) { this.y_max = y_max; } }
继承ImageView,捕捉对控件点击的坐标,在坐标内进行矩形的绘制
public class CustomImageView extends android.support.v7.widget.AppCompatImageView { private boolean firstDrawBl = true; List<Rectangle> rectangleList = new ArrayList<>(); List<PointBean> pointList = new ArrayList<>(); //对图片的横坐标和纵坐标进行解析 String [] h_name = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P"}; String [] l_name = {"1","2","3","4","5","6","7","8","9","10","11","12"}; private onPointClickListener onPointClickListener; //设置对点击事件的监听 public void setOnChosePoint(onPointClickListener pointListener){ this.onPointClickListener = pointListener; } public CustomImageView(Context context){ super(context); } public CustomImageView(Context context, @Nullable AttributeSet attrs){ super(context,attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ Drawable d = getDrawable(); if(d!=null){ // ceil not round - avoid thin vertical gaps along the left/right edges int width = MeasureSpec.getSize(widthMeasureSpec); //高度根据使得图片的宽度充满屏幕计算而得 int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth()); setMeasuredDimension(width, height); }else{ super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } //利用(Canvas与Paint)绘制显示的内容 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); int left = getLeft(); int right = getRight(); int top = getTop(); int bottom = getBottom(); Log.e("msgCustomView","左面坐标:"+left+"右面坐标:"+right); Log.e("msgCustomView","上面坐标:"+top+"下面坐标:"+bottom); for(Rectangle rectangle:rectangleList){
//绘制矩形方格 rectangle.drawSelf(canvas,paint); }
//对图片进行横竖分隔解析成小方格 if(firstDrawBl){ int wk = right -left; int hk = bottom-top; int positionX = left+wk/18; for(int i=0;i<16;i++){ int positionY = top+hk/14; for(int j=0;j<12;j++){ PointBean pointBean = new PointBean(); pointBean.setX_mix(positionX); pointBean.setX_max(positionX+wk/18); pointBean.setY_min(positionY); pointBean.setY_max(positionY+hk/14); positionY = positionY+hk/14; pointBean.setPicPointName(h_name[i]+"_"+l_name[j]); pointList.add(pointBean); } positionX = positionX+wk/18; } firstDrawBl = false; } } //处理控件的触摸事件 @Override public boolean onTouchEvent(MotionEvent event) { //获取手指的行为 int action = event.getAction(); int action_code = action&0xff; //手指的下标Index int pointIndex = action>>8; //获取手指的坐标 float x = event.getX(pointIndex); float y = event.getY(pointIndex); Log.e("自定义控件","点击坐标:"+"("+x+","+y+")"); //获取手指的名字ID int pointerId = event.getPointerId(pointIndex); // if(action_code>=5){ // action_code-=5; // } switch (action_code){ case MotionEvent.ACTION_DOWN://按下 for(PointBean pointBean:pointList){ if(x<pointBean.getX_max()&&x>pointBean.getX_mix()&&y>pointBean.getY_min()&&y<pointBean.getY_max()){ Rectangle rectangle = new Rectangle(pointBean, pointerId); rectangleList.add(rectangle); onPointClickListener.onChoose(pointBean.getPicPointName()); } } break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE: break; }
//对view进行重新布局绘制 invalidate(); return true; } //定义接口,将点击事件坐标回调 public interface onPointClickListener{ public void onChoose(String pointName); } }
矩形对象的绘制
/** * 绘画矩形对象 */ public class Rectangle { private int xMin; private int xMax; private int yMin; private int yMax; private int poinitId; int red; int green; int blue; Random random = new Random(); public Rectangle(PointBean pointBean,int pointId){ this.xMin = pointBean.getX_mix(); this.xMax = pointBean.getX_max(); this.yMin = pointBean.getY_min(); this.yMax = pointBean.getY_max(); this.poinitId = pointId; red = random.nextInt(255); green = random.nextInt(255); blue = random.nextInt(255); } public void drawSelf(Canvas canvas, Paint paint){ paint.setColor(Color.rgb(red,green,blue)); // canvas.drawCircle(x,y,r,paint); Log.e("图片绘制图片","x坐标:"+xMin+"y坐标:"+yMin+"x大坐标:"+xMax+"y大坐标"+yMax); canvas.drawRect(xMin,yMin,xMax,yMax,paint); } }