基于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 ...
随机推荐
- 十大经典排序算法详细总结(含JAVA代码实现)
原文出处:http://www.cnblogs.com/guoyaohua/p/8600214.html 0.排序算法说明 0.1 排序的定义 对一序列对象根据某个关键字进行排序. 0.2 术语说明 ...
- 个渣渣C语言之数组
---恢复内容开始--- 学c语言就知道数组.指针在c中有着特殊的地位.而且是必须掌握的一项知识,学会它会让你受益无穷. 一.数组 1.数组:室友一系列相同元素构成的.它连续的存储在内存中. 2.数组 ...
- [转]laravel DB类SQL语句操作(CURD)
本文转自:https://blog.csdn.net/woshihaiyong168/article/details/52992812 版权声明:本文为勇哥原创文章,转载请注明出处哦!!! https ...
- 第一册:lesson thirty five。
原文: Our village . This is a photograph of our village. Our village is in a valley. It is between to ...
- Linux-bc命令(21)
bc 命令是任意精度计算器语言,通常在linux下当计算器用. 它类似基本的计算器, 使用这个计算器可以做基本的数学运算. bc支持运算有以下几种: + - * / % :加,减,乘,除,取余 a^b ...
- 4.2 explain 之 select_type
一.查询类型,主要用于区别 普通查询.联合查询.子查询等的复杂查询 二.常用常见的类型 1. simple : 简单的select查询,查询中不包含子查询或union 2. primary : 查询中 ...
- (7)Microsoft office Word 2013版本操作入门_常用技巧
1.自定义快速功能栏调整:常用功能按钮可以设置显示到此处.(如图所示的另存为和插入批注功能) 2.word中截图功能: 2.1 截图插入后的图片,可以进行设置 选中图片---点击[格式]可以设置图片 ...
- Java学习笔记之——包
可以利用包,把不同的类分类存放,方便管理 在同一个包下不允许出现同名的类,可以利用分包达到可以出现同名的类 (1)包的创建: 命名:尽量做到不重复 一般:域名倒置作为前缀,再加上功能等分包 eg: ...
- Java自动内存管理机制学习(一):Java内存区域与内存溢出异常
备注:本文引用自<深入理解Java虚拟机第二版> 2.1 运行时数据区域 Java虚拟机在执行Java程序的过程中把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创 ...
- bat文件传递参数
%*是表示命令行传过来的参数,%1表示第一个参数,%2表示第二个参数,以此类推.如执行C:/>hello.bat hello world, %1取出来就是hello %2取出来就是world h ...