您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
真正意义上解决键盘弹起或者关闭时候对可移动view的影响
发布时间:2021-07-04 13:46:55编辑:雪饮阅读()
这里有一个可拖拽可以8个角度拖拽的view,其实现是以canvas的。但是在之前曾经遇到一个问题,就是当在遇到界面中有EditText时候并且触发了其聚焦等行为导致键盘弹起或者关闭的时候就会导致这个可以拖拽的view之前的拖拽的位置以及自身调整的大小就都被重置为默认的位置与尺寸了。
那么解决方案也很简单呢。
下面这个就是DragScaleView.java就是上面的自定义view的实现:
package com.example.penguinvideoedit.videodelogo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import androidx.customview.widget.ViewDragHelper;
public class DragScaleView extends View implements View.OnTouchListener {
protected int screenWidth;
protected int screenHeight;
protected int videoViewHeight;
protected int lastX;
protected int lastY;
protected int oriLeft;
protected int oriRight;
protected int oriTop;
protected 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 CENTER = 0x19;
protected int offset = 20;
protected Paint paint = new Paint();
/**
* 初始化获取屏幕宽高
*/
protected void initScreenW_H() {
screenHeight = getResources().getDisplayMetrics().heightPixels - 40;
screenWidth = getResources().getDisplayMetrics().widthPixels;
}
public DragScaleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnTouchListener(this);
initScreenW_H();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
}
public DragScaleView(Context context, AttributeSet attrs) {
super(context, attrs);
setOnTouchListener(this);
initScreenW_H();
}
public DragScaleView(Context context) {
super(context);
setOnTouchListener(this);
initScreenW_H();
}
int last_ds_left;
int last_ds_top;
int last_ds_width;
int last_ds_height;
int act_num;
public void saveds(int last_ds_left, int last_ds_top,int last_ds_width,int last_ds_height){
this.last_ds_left=last_ds_left;
this.last_ds_top=last_ds_top;
this.last_ds_width=last_ds_width;
this.last_ds_height=last_ds_height;
this.act_num++;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.RED);
//設置紅色邊框粗細
paint.setStrokeWidth(4.0f);
paint.setStyle(Paint.Style.STROKE);
/*
* 參數1紅色框默認距離左邊距離
* 參數2紅色框默認距離頂部距離
* 參數3右邊
* 參數4底部
* */
canvas.drawRect(offset, offset, getWidth() - offset, getHeight()- offset, paint);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
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());
}
// 处理拖动事件
delDrag(v, event, action);
invalidate();
return false;
}
/**
* 处理拖动事件
*
* @param v
* @param event
* @param action
*/
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;
}
if (dragDirection != CENTER) {
v.layout(oriLeft, oriTop, oriRight, oriBottom);
}
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:
dragDirection = 0;
break;
}
LinearLayout.LayoutParams lpFeedback = new LinearLayout.LayoutParams(
v.getWidth(), v.getHeight());
lpFeedback.leftMargin = v.getLeft();
lpFeedback.topMargin = v.getTop();
v.setLayoutParams(lpFeedback);
}
/**
* 触摸点为中心->>移动
*
* @param v
* @param dx
* @param dy
*/
public 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();
}
Log.i("屏幕高度", String.valueOf(screenHeight));
Log.i("videoViewHeight", String.valueOf(videoViewHeight));
/*
if (bottom > screenHeight + offset) {
bottom = screenHeight + offset;
top = bottom - v.getHeight();
}
*/
if (bottom > videoViewHeight + offset) {
bottom = videoViewHeight + offset;
top = bottom - v.getHeight();
}
v.layout(left, top, right, bottom);
saveds(this.getLeft(),this.getTop(),this.getCutWidth(),this.getCutHeight());
}
/**
* 触摸点为上边缘
*
* @param v
* @param dy
*/
public void top(View v, int dy) {
oriTop += dy;
if (oriTop < -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
*/
public 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
*/
public 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 < 40 && y < 40) {
return LEFT_TOP;
}
if (y < 40 && right - left - x < 40) {
return RIGHT_TOP;
}
if (x < 40 && bottom - top - y < 40) {
return LEFT_BOTTOM;
}
if (right - left - x < 40 && bottom - top - y < 40) {
return RIGHT_BOTTOM;
}
if (x < 40) {
return LEFT;
}
if (y < 40) {
return TOP;
}
if (right - left - x < 40) {
return RIGHT;
}
if (bottom - top - y < 40) {
return BOTTOM;
}
return CENTER;
}
/**
* 获取截取宽度
*
* @return
*/
public int getCutWidth() {
return getWidth() - 2 * offset;
}
/**
* 获取截取高度
*
* @return
*/
public int getCutHeight() {
return getHeight() - 2 * offset;
}
}
这里标红的地方就是关键,就是每次该view移动或者变换自身尺寸之后,就要重新设置下自身的layout,而这里用的是线性布局,所以也就是说这个view的直接上级也必须是线性布局才可以。
关键字词:view,归位,键盘弹起
相关文章
- surfaceView的顯示與隱藏
- androidStudio出現错误:This view is not constrained.
- 安卓彈窗dialog中實現listview
- 安卓用ExpandableListView二级列表代替listview嵌套實
- 安卓listview實現加載獨立的xml佈局及listview的嵌套
- 1. IVideoView显示模块架构讲解和代码创建~1
- 6. 使用NDK通过GLSurfaceView双缓冲空间复制完成视频
- 85_采用html编辑界面ui&java_javascript代码的互相调
- 70_android下的视频播放器&surfaceview&holder
- 29_listview的点击事件&通过debug 知道方法参数的含义