基于SurfaceView的可拖动视频控件
视频播放控件(一) 可拖动,变换SurfaceView
public class DragSurfaceView extends SurfaceView implements View.OnTouchListener {
protected int screenWidth;
protected int screenHeight;
protected int lastX;
protected 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 CENTER = 0x19;
private int offset = 20; /**
* 初始化获取屏幕宽高
*/
protected void initScreenW_H() {
screenHeight = getResources().getDisplayMetrics().heightPixels - 40;
screenWidth = getResources().getDisplayMetrics().widthPixels;
Log.i("DragViewTAG", "DragSurfaceView.initScreenW_H: screenWidth="+screenWidth+", screenHeight="+screenHeight);
}
public DragSurfaceView(Context context) {
super(context);
setOnTouchListener(this);
initScreenW_H();
} public DragSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
setOnTouchListener(this);
initScreenW_H();
} public DragSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setOnTouchListener(this);
initScreenW_H();
} @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);
if(action==MotionEvent.ACTION_UP){
dragDirection=0;
}
invalidate();
return true;
} /**
* 获取触摸点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;
} /**
* 处理拖动事件
*
* @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;
default:
break;
}
v.layout(oriLeft, oriTop, oriRight, oriBottom);
// if (dragDirection != CENTER) {
// v.layout(oriLeft, oriTop, oriRight, oriBottom);
// }
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
Log.i("DragViewTAG", "DragSurfaceView.delDrag:ACTION_MOVE direction="+dragDirection+", left="+oriLeft+", top="+oriTop+", right="+oriRight+", bottom="+oriBottom);
break;
case MotionEvent.ACTION_UP:
ViewGroup.LayoutParams newLayoutParams = getNewLayoutParams();
if(newLayoutParams!=null){
Log.i("DragViewTAG", "DragSurfaceView.delDrag:ACTION_UP width="+newLayoutParams.width+", height="+newLayoutParams.height);
setLayoutParams(newLayoutParams);
}else {
Log.e("DragViewTAG", "DragSurfaceView.delDrag: 父组件类型?");
v.layout(oriLeft, oriTop, oriRight, oriBottom);
}
break;
default:
break;
}
} private ViewGroup.LayoutParams getNewLayoutParams(){
if(getLayoutParams() instanceof RelativeLayout.LayoutParams){
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)getLayoutParams( );
lp.leftMargin = oriLeft;
lp.topMargin = oriTop;
lp.width = oriRight-oriLeft;
lp.height = oriBottom-oriTop;
return lp;
}else if(getLayoutParams() instanceof FrameLayout.LayoutParams) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
lp.leftMargin = oriLeft;
lp.topMargin = oriTop;
lp.width = oriRight - oriLeft;
lp.height = oriBottom - oriTop;
return lp;
}
return null;
} /**
* 触摸点为中心->>移动
*
* @param v
* @param dx
* @param dy
*/
private void center(View v, int dx, int dy) {
oriLeft += dx;
oriTop += dy;
oriRight += dx;
oriBottom += dy;
Log.i("DragViewTAG", "DragSurfaceView.center: v.left="+v.getLeft()+", v.top="+v.getTop());
if (oriLeft < -offset) {
Log.e("DragViewTAG", "DragSurfaceView.center: 左侧越界, left="+oriLeft+", offset="+offset);
oriLeft = -offset;
oriRight = oriLeft + v.getWidth();
}
if (oriRight > screenWidth + offset) {
Log.e("DragViewTAG", "DragSurfaceView.center: 右侧越界, right="+oriRight+", screenWidth="+screenWidth+", offset="+offset);
oriRight = screenWidth + offset;
oriLeft = oriRight - v.getWidth();
}
if (oriTop < -offset) {
Log.e("DragViewTAG", "DragSurfaceView.center: 顶部越界, top="+oriTop+", offset="+offset);
oriTop = -offset;
oriBottom = oriTop + v.getHeight();
}
if (oriBottom > screenHeight + offset) {
Log.e("DragViewTAG", "DragSurfaceView.center: 底部越界, bottom="+oriBottom+", screenHeight="+screenHeight+", offset="+offset);
oriBottom = screenHeight + offset;
oriTop = oriBottom - v.getHeight();
}
// v.layout(left, top, right, bottom); } /**
* 触摸点为上边缘
*
* @param v
* @param dy
*/
private 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
*/
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;
}
} /**
* 获取截取宽度
*
* @return
*/
public int getCutWidth() {
return getWidth() - 2 * offset;
} /**
* 获取截取高度
*
* @return
*/
public int getCutHeight() {
return getHeight() - 2 * offset;
}
}
基于SurfaceView的可拖动视频控件的更多相关文章
- 关于intouch/ifix嵌入视频控件并使用(海康,大华)
2017年下半年项目开始接触利用intouch工控软件来进行项目二次开发.其中关于驱动的问题始终是上位机的重中之重,暂且不表(嘿嘿--),首先遇到的问题就是在弹窗中嵌入视频控件,监控设备的开停状态.经 ...
- 基于存储过程的MVC开源分页控件--LYB.NET.SPPager
摘要 现在基于ASP.NET MVC的分页控件我想大家都不陌生了,百度一下一大箩筐.其中有不少精品,陕北吴旗娃杨涛大哥做的分页控件MVCPager(http://www.webdiyer.com/)算 ...
- FineUI 基于 ExtJS 的专业 ASP.NET 控件库
FineUI 基于 ExtJS 的专业 ASP.NET 控件库 http://www.fineui.com/
- cocos2d-x视频控件VideoPlayer的用户操作栏进度条去除(转载)
目前遇到两个问题: (1)视频控件移除有问题,会报异常. (2)视频控件有用户操作栏,用户点击屏幕会停止视频播放. 对于第一个问题,主要是移除控件时冲突引起的,目前简单处理是做一个延时处理,先stop ...
- 基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串、list集合(MVC5)<二>
上篇博客给大家介绍了基于Bootstrap的JQuery TreeView树形控件,数据支持json字符串.list集合(MVC5)<一>, 其中的两种方式都显得有些冗余.接着上篇博客继续 ...
- 可以创建专业的客户端/服务器视频会议应用程序的音频和视频控件LEADTOOLS Video Conferencing SDK
LEADTOOLS Video Streaming Module控件为您创建一个自定义的视频会议应用程序和工具提供所有需要的功能.软件开发人员可以使用Video Streaming Module SD ...
- 基于Qt的第三方库和控件
====================== 基于Qt的第三方库和控件 ====================== libQxt -------- http://dev.libqxt.o ...
- 基于存储过程的MVC开源分页控件
基于存储过程的MVC开源分页控件--LYB.NET.SPPager 摘要 现在基于ASP.NET MVC的分页控件我想大家都不陌生了,百度一下一大箩筐.其中有不少精品,陕北吴旗娃杨涛大哥做的分页控件M ...
- android--------自定义视频控件(视频全屏竖屏自动切换)
android播放视频也是常用的技术,今天分享一个自定义视频控件,支持自定义控制 UI,全屏播放, 可以实现自动横竖屏切换的控件,跟随手机的位置而,重力感应自动切换横竖屏. 效果图: 代码下载Gi ...
随机推荐
- 浅谈基于WOPI协议实现跨浏览器的Office在线编辑解决方案
如今,基于Web版的Office 在线预览与编辑功能已成为一种趋势,而关于该技术的实现却成为了国内大部份公司的技术挑战,挑战主要存在于两方面: 其一:目前国内乃至微软本身,还没有相对较为完善的解决方案 ...
- JavaScript之函数(上)
在编程语言中,无论是面向过程的C,兼备面过程和对象的c++,还是面向对象的编程语言,如java,.net,php等,函数均扮演着重要的角色.当然,在面向对象编程语言JavaScript中(严格来说,J ...
- Hibernate学习(八)———— Hibernate检索策略(类级别,关联级别,批量检索)详解
序言 很多看起来很难的东西其实并不难,关键是看自己是否花费了时间和精力去看,如果一个东西你能看得懂,同样的,别人也能看得懂,体现不出和别人的差距,所以当你觉得自己看了很多书或者学了很多东西的时候,你要 ...
- 教你如何在React及Redux项目中进行服务端渲染
服务端渲染(SSR: Server Side Rendering)在React项目中有着广泛的应用场景 基于React虚拟DOM的特性,在浏览器端和服务端我们可以实现同构(可以使用同一份代码来实现多端 ...
- MyBatis学习总结(三)——多表关联查询与动态SQL
在上一章中我们学习了<MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射>,这一章主要是介绍一对一关联查询.一对多关联查询与动态SQL等内容. 一.多表关联查询 表与 ...
- 如何加入Microsoft Teams 技术社区
作者:陈希章 时间:2018-11-19 概述 这个手册适合没有Office 365 账号的用户,你可以使用免费版立即开始使用Microsoft Teams,并且与微软的产品组专家,以及来自两岸三 ...
- Java 学习笔记 反射与迭代器
反射 使用反射获得类 Class cls = Class.forName("全类名") //包括包名 Class cls = xx.Class;//xx代表类名 使用反射获得构造方 ...
- WarShall算法
1.引言 图的连通性问题是图论研究的重要问题之一,在实际中有着广泛的应用.例如在通信网络的联通问题中,运输路线的规划问题等等都涉及图的连通性.因此传递闭包的计算需要一个高效率的算法,一个著名的算法就是 ...
- 当前主流电脑的BIOS调出键
[组装电脑主板] 主板品牌 启动按键 华硕主板 F8 技嘉主板 F12 微星主板 F11 映泰主板 F9 梅捷主板 ESC或F12 七彩虹主板 ESC或F11 华擎主板 F11 斯巴达 ...
- mysql zip安装
管理员运行cmd,进入bin目录1.在my.ini(mysql解压目录下)文件中复制下面内容 [client] port = 3306 [mysql] default-character-set=ut ...