基于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 ...
随机推荐
- 使用3D Slicer对图像进行配准
在进行深度学习之前,我们需要图像进行一些预处理操作,其中配准是很重要的一环,以下将介绍使用软件3D Slicer来进行图像配准 3D Slicer是(1)一个软件平台,用以图像分析(包括配准和实时编辑 ...
- 【Go】优雅的读取http请求或响应的数据-续
原文链接:https://blog.thinkeridea.com/201902/go/you_ya_de_du_qu_http_qing_qiu_huo_xiang_ying_de_shu_ju_2 ...
- Docker在Linux上运行NetCore系列(四)使用私有Nuget与多个本地包引用运行ASPNetCore
转发请注明此文章作者与路径,请尊重原著,违者必究. 本篇文章演示了使用Dockerfile在Linux(ubuntu16.04)系统上构建ASPNetCore应用,并且在一个解决方案中存在多个项目之间 ...
- WPF 故事版例子
Storyboard std = new Storyboard(); DoubleAnimation a = new DoubleAnimation(); a.From =0; a.To =400; ...
- dotnetcore-officeaddin-toolbox : Office 365 Add-in开发人员的工具箱
在上一篇文章(.NET Core开源行动:一键创建Excel Add-in) 中我给大家展示了一套为Office 365 Add-in开发人员准备的模板库,你可以通过 dotnet new excel ...
- async,await,Task 的一些用法
async,await,Task 的一些用法 private void Form1_Load(object sender, EventArgs e) { Display(); } public asy ...
- nginx常用命令参数
命令行参数: 常用命令: -c filename:设置配置文件. -t :不运行,而仅仅测试配置文件.nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件. -s :传递一个信 ...
- sqlserver 2008R2新建数据库时报错,提示无法获得数据库"model"上的排它锁
刚新装了个sqlserver2008 R2,在建立数据库时候报错,提示无法获得数据库"model"上的排它锁.解决办法如下: 打开查询页面,执行下面的语句即可. use maste ...
- [转] 快速部署Tomcat项目的Shell脚本
为了做集群测试,在每台机器上装了3个tomcat,每次发布项目的时候都要反复敲一些命令,重启tomcat之前先检查tomcat进程有没有停掉,没有还要手动kill该进程. 发布次数多了,操作就比较繁琐 ...
- pullMsg有感
开发功能过程中,始终会有些东西是确认的,比如美丑.业务是否合理.对错. 如果明知道不合理,却按照已有规定.框架.设计去开发,其实是不够职业. 好的做法是朝对的方向去push,并落地: 次之是去push ...