点击触摸事件填充整个屏幕

我有这个自定义视图,可以拖动和缩放(DragAndZoomView)。 我用它与另一个自定义视图(CustomGridView),只是画一些矩形。

我的问题是,当我拖动或缩放我的CustomGridView我可以在屏幕上的任何地方,而不是只有当我触摸视图。 这使得它真的很烦人,当我尝试从后面的代码在我的父视图中添加多个这些。

下面是DragAndZoomView的代码:

abstract class DragAndZoomView : View { var useCustomOnTouchEvent = false // States. private val NONE: Byte = 0 private val DRAG: Byte = 1 private val ZOOM: Byte = 2 private var mode = NONE // Matrices used to move and zoom image. private val mMatrix = Matrix() private val matrixInverse = Matrix() private val savedMatrix = Matrix() // Parameters for zooming. private val start = PointF() private val mid = PointF() private var oldDist = 1f private var lastEvent: FloatArray? = null private var lastDownTime = 0L private var mDispatchTouchEventWorkingArray = FloatArray(2) private var mOnTouchEventWorkingArray = FloatArray(2) constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet) : super(context, attrs) constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) override fun dispatchTouchEvent(ev: MotionEvent): Boolean { mDispatchTouchEventWorkingArray[0] = ev.x mDispatchTouchEventWorkingArray[1] = ev.y mDispatchTouchEventWorkingArray = screenPointsToScaledPoints(mDispatchTouchEventWorkingArray) ev.setLocation(mDispatchTouchEventWorkingArray[0], mDispatchTouchEventWorkingArray[1]) return super.dispatchTouchEvent(ev) } /** * Determine the space between the first two fingers */ private fun spacing(event: MotionEvent): Float { val x = event.getX(0) - event.getX(1) val y = event.getY(0) - event.getY(1) return Math.sqrt((x * x + y * y).toDouble()).toFloat() } /** * Calculate the mid point of the first two fingers */ private fun midPoint(point: PointF, event: MotionEvent) { val x = event.getX(0) + event.getX(1) val y = event.getY(0) + event.getY(1) point.set(x / 2, y / 2) } private fun scaledPointsToScreenPoints(a: FloatArray): FloatArray { mMatrix.mapPoints(a) return a } private fun screenPointsToScaledPoints(a: FloatArray): FloatArray { matrixInverse.mapPoints(a) return a } override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { super.onLayout(changed, left, top, left + measuredWidth, top + measuredHeight) if (visibility != GONE) { //layout(left, top, left + measuredWidth, top + measuredHeight) } } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, heightMeasureSpec) if (visibility != GONE) { //measure(widthMeasureSpec, heightMeasureSpec) } } override fun dispatchDraw(canvas: Canvas) { val values = FloatArray(9) mMatrix.getValues(values) canvas.save() canvas.translate(values[Matrix.MTRANS_X], values[Matrix.MTRANS_Y]) canvas.scale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]) super.dispatchDraw(canvas) customOnDraw(canvas) setMeasuredDimension(measuredWidth, measuredHeight) canvas.restore() } abstract fun customOnDraw(canvas: Canvas) //abstract fun CustomOnTouchEvent(event: MotionEvent): Boolean override fun onTouchEvent(event: MotionEvent): Boolean { // use the abstract onTouchEvent if (useCustomOnTouchEvent) //return CustomOnTouchEvent(event) // handle touch events here mOnTouchEventWorkingArray[0] = event.x mOnTouchEventWorkingArray[1] = event.y mOnTouchEventWorkingArray = scaledPointsToScreenPoints(mOnTouchEventWorkingArray) event.setLocation(mOnTouchEventWorkingArray[0], mOnTouchEventWorkingArray[1]) when (event.action and MotionEvent.ACTION_MASK) { MotionEvent.ACTION_DOWN -> { savedMatrix.set(mMatrix) mode = DRAG lastEvent = null val downTime = event.downTime if (downTime - lastDownTime < 300L) { val density = resources.displayMetrics.density if (Math.max(Math.abs(start.x - event.x), Math.abs(start.y - event.y)) < 40f * density) { savedMatrix.set(mMatrix) mid.set(event.x, event.y) mode = ZOOM lastEvent = FloatArray(4) lastEvent!![1] = event.x lastEvent!![0] = lastEvent!![1] lastEvent!![3] = event.y lastEvent!![2] = lastEvent!![3] } lastDownTime = 0L } else { lastDownTime = downTime } start.set(event.x, event.y) } MotionEvent.ACTION_POINTER_DOWN -> { oldDist = spacing(event) if (oldDist > 10f) { savedMatrix.set(mMatrix) midPoint(mid, event) mode = ZOOM } lastEvent = FloatArray(4) lastEvent!![0] = event.getX(0) lastEvent!![1] = event.getX(1) lastEvent!![2] = event.getY(0) lastEvent!![3] = event.getY(1) } MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> { mode = NONE lastEvent = null } MotionEvent.ACTION_MOVE -> { val density = resources.displayMetrics.density if (mode == DRAG) { mMatrix.set(savedMatrix) val dx = event.x - start.x val dy = event.y - start.y mMatrix.postTranslate(dx, dy) mMatrix.invert(matrixInverse) if (Math.max(Math.abs(start.x - event.x), Math.abs(start.y - event.y)) > 20f * density) { lastDownTime = 0L } } else if (mode == ZOOM) { if (event.pointerCount > 1) { val newDist = spacing(event) if (newDist > 10f * density) { mMatrix.set(savedMatrix) val scale = newDist / oldDist mMatrix.postScale(scale, scale, mid.x, mid.y) mMatrix.invert(matrixInverse) } } else { mMatrix.set(savedMatrix) val scale = event.y / start.y mMatrix.postScale(scale, scale, mid.x, mid.y) mMatrix.invert(matrixInverse) } } } } invalidate() return true } } 

这里是CustomGridView的代码:

 data class CustomGridViewAttributes( var numberOfRows: Int = 1, var numberOfColumns: Int = 1, var cellSize: Int = 200, var paintColor: Int = Color.RED, var spaceBetweenCells: Int = 0 ) private var rectangleList: ArrayList<Rect>? = null private var paint: Paint? = null private var paintColor = Color.RED private var cellSize = 200 private var numberOfRows = 1 private var currentNumberOfColumns = -1 private var currentSpaceBetweenCells = -1 var numberOfColumns = 1 var spaceBetweenCells = 5 constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { val a = context.theme.obtainStyledAttributes(attrs, R.styleable.CustomGridView, 0, 0) try { numberOfRows = a.getInteger(R.styleable.CustomGridView_numberOfRows, 1) numberOfColumns = a.getInteger(R.styleable.CustomGridView_numberOfColumns, 1) cellSize = a.getInteger(R.styleable.CustomGridView_cellSize, 200) paintColor = a.getInteger(R.styleable.CustomGridView_color, Color.RED) spaceBetweenCells = a.getInteger(R.styleable.CustomGridView_spaceBetweenCells, 5) } finally { a.recycle() } } constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) constructor(context: Context, attrs: CustomGridViewAttributes) : super(context) { numberOfRows = attrs.numberOfRows numberOfColumns = attrs.numberOfColumns cellSize = attrs.cellSize paintColor = attrs.paintColor spaceBetweenCells = attrs.spaceBetweenCells useCustomOnTouchEvent = false } private fun setRectangleList() { // Setup the rectangles var createNewRectangles: Boolean = false if (currentSpaceBetweenCells != spaceBetweenCells && !createNewRectangles) createNewRectangles = true if (currentNumberOfColumns != numberOfColumns && !createNewRectangles) createNewRectangles = true if (!createNewRectangles) return currentNumberOfColumns = numberOfColumns rectangleList = ArrayList() repeat(numberOfRows) { i -> repeat(numberOfColumns) { j -> val left = j * (cellSize + spaceBetweenCells) val top = i * (cellSize + spaceBetweenCells) val right = left + cellSize val bottom = top + cellSize val rectangle = Rect(left, top, right, bottom) (rectangleList as ArrayList<Rect>).add(rectangle) } } } private fun setPaint() { // set paints color and style if (paint != null) return paint = Paint() (paint as Paint).color = paintColor (paint as Paint).style = Paint.Style.STROKE } override fun customOnDraw(canvas: Canvas) { setRectangleList() setPaint() rectangleList!!.forEach { canvas.drawRect(it, paint) } } } 

最后,我用来添加视图到父级的方法:

 private fun setCurrentRow() { model.currentRowView = CustomGridView(context, CustomGridView.CustomGridViewAttributes( numberOfColumns = model.colNumber, spaceBetweenCells = model.spaceBetweenCells )) context.findViewById<RelativeLayout>(R.id.shelf_editing_mainLayout) .addView(model.currentRowView) } 

那么我怎样才能使它不像最近添加的视图那样充满整个屏幕,而只是那个,它的绘制?