【安卓】请教一个自定义View的问题
自定义拖拽缩放的ImageView,现在这样左上右正常不会拖出屏幕外,但是底部可以拖出屏幕外面.该怎样定义这个高度让它不会被拖出底部?试着拿了屏幕的高度设置上去,或者减去导航栏高度也不行.下面是拖出底部的截图和自定义View的代码
自定义view:
public class DragScaleView extends AppCompatImageView implements View.OnTouchListener {protected int screenWidth;
protected int screenHeight;
protected static int lastX;
protected static int lastY;
private int oriLeft;
private int oriRight;
private int oriTop;
private int oriBottom;
private int dragDirection;
private static final int TOP = 0x15;
private static final int LEFT = 0x16;
private static final int BOTTOM = 0x17;
private static final int RIGHT = 0x18;
private static final int LEFT_TOP = 0x11;
private static final int RIGHT_TOP = 0x12;
private static final int LEFT_BOTTOM = 0x13;
private static final int RIGHT_BOTTOM = 0x14;
private static final int TOUCH_TWO = 0x21;
private static final int CENTER = 0x19;
private int offset = 0; //可超出其父控件的偏移量
protected Paint paint = new Paint();
private static final int touchDistance = 80; //触摸边界的有效距离
private static final String TAG = "DragScaleView";
// 初始的两个手指按下的触摸点的距离
private float oriDis = 1f;
private int mZoomWidth; //缩放后的宽
private int mZoomHeight; //缩放后的高
/**
* 初始化获取屏幕宽高
*/
protected void initScreenW_H() {
// screenHeight = getResources().getDisplayMetrics().heightPixels - 40;
int daoHangHeight = getDaoHangHeight(getContext());//80
Log.d(TAG, "initScreenW_H: gao="+daoHangHeight);
// screenHeight = getResources().getDisplayMetrics().heightPixels -daoHangHeight;
screenHeight = getResources().getDisplayMetrics().heightPixels; //todo:这样设置会拖出底部
screenWidth = getResources().getDisplayMetrics().widthPixels;
}
public static int getDaoHangHeight(Context context) {
int result = 0;
int resourceId=0;
int rid = context.getResources().getIdentifier("config_showNavigationBar", "bool", "android");
if (rid!=0){
resourceId = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android");
// CMLog.show("高度:"+resourceId);
// CMLog.show("高度:"+context.getResources().getDimensionPixelSize(resourceId) +"");
return context.getResources().getDimensionPixelSize(resourceId);
}else
return 0;
}
public DragScaleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnTouchListener(this);
initScreenW_H();
}
public DragScaleView(Context context, AttributeSet attrs) {
super(context, attrs);
setOnTouchListener(this);
initScreenW_H();
}
public DragScaleView(Context context) {
super(context);
setOnTouchListener(this);
initScreenW_H();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GRAY);
paint.setStrokeWidth(4.0f);
paint.setStyle(Paint.Style.STROKE);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// setBackgroundResource(R.mipmap.splash);
int action = event.getAction() & MotionEvent.ACTION_MASK;
if (action == MotionEvent.ACTION_DOWN) {
oriLeft = v.getLeft();
oriRight = v.getRight();
oriTop = v.getTop();
oriBottom = v.getBottom();
lastY = (int) event.getRawY();
lastX = (int) event.getRawX();
dragDirection = getDirection(v, (int) event.getX(),
(int) event.getY());
}
if (action == MotionEvent.ACTION_POINTER_DOWN) {
oriLeft = v.getLeft();
oriRight = v.getRight();
oriTop = v.getTop();
oriBottom = v.getBottom();
lastY = (int) event.getRawY();
lastX = (int) event.getRawX();
dragDirection = TOUCH_TWO;
oriDis = distance(event);
}
// 处理拖动事件
delDrag(v, event, action);
invalidate();
return false;
}
/**
* 处理拖动事件
*/
protected void delDrag(View v, MotionEvent event, int action) {
switch (action) {
case MotionEvent.ACTION_MOVE:
int dx = (int) event.getRawX() - lastX;
int dy = (int) event.getRawY() - lastY;
switch (dragDirection) {
case LEFT: // 左边缘
left(v, dx);
break;
case RIGHT: // 右边缘
right(v, dx);
break;
case BOTTOM: // 下边缘
bottom(v, dy);
break;
case TOP: // 上边缘
top(v, dy);
break;
case CENTER: // 点击中心-->>移动
center(v, dx, dy);
break;
case LEFT_BOTTOM: // 左下
left(v, dx);
bottom(v, dy);
break;
case LEFT_TOP: // 左上
left(v, dx);
top(v, dy);
break;
case RIGHT_BOTTOM: // 右下
right(v, dx);
bottom(v, dy);
break;
case RIGHT_TOP: // 右上
right(v, dx);
top(v, dy);
break;
case TOUCH_TWO: //双指操控
float newDist = distance(event);
float scale = newDist / oriDis;
//控制双指缩放的敏感度
int distX = (int) (scale * (oriRight - oriLeft) - (oriRight - oriLeft)) / 50;
int distY = (int) (scale * (oriBottom - oriTop) - (oriBottom - oriTop)) / 50;
if (newDist > 10f) {//当双指的距离大于10时,开始相应处理
left(v, -distX);
top(v, -distY);
right(v, distX);
bottom(v, distY);
}
break;
}
if (dragDirection != CENTER) {
v.layout(oriLeft, oriTop, oriRight, oriBottom);
}
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
dragDirection = 0;
break;
}
Log.d(TAG, "delDrag: x==" + lastX + " ,y=" + lastY);
}
/**
* TODO:最后X坐标值
*/
public static int getLastX() {
return lastX;
}
/**
* TODO:最后Y坐标值
*/
public static int getLastY() {
return lastY;
}
/**
* TODO: 获取缩放后的宽
*/
public int getZoomWidth() {
// ViewGroup.LayoutParams layoutParams = getLayoutParams();
// int width = layoutParams.width;
int width = mZoomWidth;
return width;
}
/**
* TODO: 获取缩放后的高
*/
public int getZoomHeight() {
// ViewGroup.LayoutParams layoutParams = getLayoutParams();
// int width = layoutParams.width;
int height = mZoomHeight;
return height;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
//TODO:
mZoomWidth = w;//获取到修改后的宽
mZoomHeight = h;//获取到修改后的高
}
/**
* 触摸点为中心->>移动
*
* @param v
* @param dx
* @param dy
*/
private void center(View v, int dx, int dy) {
int left = v.getLeft() + dx;
int top = v.getTop() + dy;
int right = v.getRight() + dx;
int bottom = v.getBottom() + dy;
if (left < -offset) {
left = -offset;
right = left + v.getWidth();
}
if (right > screenWidth + offset) {
right = screenWidth + offset;
left = right - v.getWidth();
}
if (top < -offset) {
top = -offset;
bottom = top + v.getHeight();
}
if (bottom > screenHeight + offset) {
bottom = screenHeight + offset;
top = bottom - v.getHeight();
}
Log.d("raydrag", left + " " + top + " " + right + " " + bottom + " " + dx);
v.layout(left, top, right, bottom);
}
/**
* 触摸点为上边缘
*
* @param v
* @param dy
*/
private void top(View v, int dy) {
oriTop += dy;
if (oriTop < -offset) {
//对view边界的处理,如果子view达到父控件的边界,offset代表允许超出父控件多少
oriTop = -offset;
}
if (oriBottom - oriTop - 2 * offset < 200) {
oriTop = oriBottom - 2 * offset - 200;
}
}
/**
* 触摸点为下边缘
*
* @param v
* @param dy
*/
private void bottom(View v, int dy) {
oriBottom += dy;
if (oriBottom > screenHeight + offset) {
oriBottom = screenHeight + offset;
}
if (oriBottom - oriTop - 2 * offset < 200) {
oriBottom = 200 + oriTop + 2 * offset;
}
}
/**
* 触摸点为右边缘
*
* @param v
* @param dx
*/
private void right(View v, int dx) {
oriRight += dx;
if (oriRight > screenWidth + offset) {
oriRight = screenWidth + offset;
}
if (oriRight - oriLeft - 2 * offset < 200) {
oriRight = oriLeft + 2 * offset + 200;
}
}
/**
* 触摸点为左边缘
*
* @param v
* @param dx
*/
private void left(View v, int dx) {
oriLeft += dx;
if (oriLeft < -offset) {
oriLeft = -offset;
}
if (oriRight - oriLeft - 2 * offset < 200) {
oriLeft = oriRight - 2 * offset - 200;
}
}
/**
* 获取触摸点flag
*
* @param v
* @param x
* @param y
* @return
*/
protected int getDirection(View v, int x, int y) {
int left = v.getLeft();
int right = v.getRight();
int bottom = v.getBottom();
int top = v.getTop();
if (x < touchDistance && y < touchDistance) {
return LEFT_TOP;
}
if (y < touchDistance && right - left - x < touchDistance) {
return RIGHT_TOP;
}
if (x < touchDistance && bottom - top - y < touchDistance) {
return LEFT_BOTTOM;
}
if (right - left - x < touchDistance && bottom - top - y < touchDistance) {
return RIGHT_BOTTOM;
}
if (x < touchDistance) {
return LEFT;
}
if (y < touchDistance) {
return TOP;
}
if (right - left - x < touchDistance) {
return RIGHT;
}
if (bottom - top - y < touchDistance) {
return BOTTOM;
}
return CENTER;
}
/**
* 计算两个手指间的距离
*
* @param event 触摸事件
* @return 放回两个手指之间的距离
*/
private float distance(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);//两点间距离公式
}
}
回答
以上是 【安卓】请教一个自定义View的问题 的全部内容, 来源链接: utcz.com/a/103796.html