图片热区点击的实现

有时我们需要根据点击图片的不同位置响应不同的事件,即通常所说的图片热区点击

1、前期准备:要实现热区点击,需要提前测量好原始图片上每块区域的边界点坐标,组成一个坐标数组,用以检测点击是否在某个区域内和绘制点击时的覆盖物

2、加载图片并计算实际显示的图片缩放比例

imageView.post(new Runnable(){
    @Override
    public void run() {
        int boundWidth = imageView.getDrawable().getBounds().width();
        int boundHeight = imageView.getDrawable().getBounds().height();
        Log.i("henry","boundWidth:"+boundWidth + " | boundHeight:" + boundHeight);
        Log.i("henry","ImageViewWidth:"+imageView.getDrawable() + " | ImageViewHeight:" + imageView.getHeight());
        //获取imageViewImage的变换矩阵
        Matrix matrix = imageView.getImageMatrix();
        float[] values = new float[9];
        matrix.getValues(values);
        //获取ImageXY方向的缩放
        float scaleX = values[0];
        float scaleY = values[4];
        //获取ImageX,Y方向的移动
        float transX = values[2];
        float transY = values[5];

3、根据图片缩放比例重新计算区域的边界坐标点

//计算实际显示的区域path坐标
int[] xj = getResources().getIntArray(R.array.map_xj);
int[] xz = getResources().getIntArray(R.array.map_xz);

float[] xjf = new float[xj.length];
float[] xzf = new float[xz.length];

for(int i = 0; i < xj.length; i++){
    if(i % 2 == 0){
        xjf[i] = (xj[i] * scaleX + transX);
    }else{
        xjf[i] = (xj[i] * scaleY + transY);
    }
}

for(int i = 0; i < xz.length; i++){
    if(i % 2 == 0){
        xzf[i] = (xz[i] * scaleX + transX);
    }else{
        xzf[i] = (xz[i] * scaleY + transY);
    }
}


4、重写onTouchEvent()事件,监听用户按下的坐标点,并判断坐标点是否在某个区域内

case MotionEvent.ACTION_DOWN:
    checkClickArea(event);
    if(baseAreaBean != null){
        invalidate();
    }
    return true;

/**
 * 检测点击区域
 */
private void checkClickArea(MotionEvent event){
    for(BaseAreaBean areaBean : areaPaths){
        RectF rectF = new RectF();
        areaBean.path.computeBounds(rectF,true);
        Region region = new Region();
        region.setPath(areaBean.path,new Region((int)rectF.left,(int)rectF.top,(int)rectF.right,(int)rectF.bottom));
        if(region.contains((int)event.getX(),(int)event.getY())){
            baseAreaBean = areaBean;
            break;
        }
    }
}

5、若用户按下位置处于某个区域,重写onDraw()方法,绘制区域覆盖物

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if(baseAreaBean != null){
        Paint paint = new Paint();
        paint.setARGB(0xAA,0xB2,0xB2,0xB2);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawPath(baseAreaBean.path,paint);
    }
}

6、在up事件中响应用户操作

case MotionEvent.ACTION_UP:
    //触发点击事件
    if(baseAreaBean != null && onAreaClickListener != null){
        onAreaClickListener.onAreaClick(baseAreaBean);
    }
    //将当前点击区域置空
    baseAreaBean = null;
    invalidate();
    break;


你可能感兴趣的:(Android进阶)