两个surfaceview的重叠效果类似直播效果中的视频和讲义实践
来源:互联网 发布:sql视图删除数据 编辑:程序博客网 时间:2024/06/05 07:00
效果图
首先还是不废话,直接上一张图,有图才有真相,不然大家看半天才发现不是我想要的效果,所以这样浪费大家的时间了
实际应用场景可多了,比如后面是显示相机的数据,前面是一个画板,直播的视频和讲义展示
布局
布局就很简单了,直接让两个surfaceView重叠在一起
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00f" tools:context="cn.woblog.testsurfaceview.MainActivity"> <SurfaceView android:id="@+id/sv" android:layout_width="match_parent" android:layout_height="400dp" /> <RelativeLayout android:id="@+id/rl" android:layout_width="wrap_content" android:layout_height="wrap_content"> <SurfaceView android:id="@+id/sv_mini" android:layout_width="200dp" android:layout_height="200dp" android:clickable="false" android:focusable="false" /> </RelativeLayout></RelativeLayout>
添加要显示的内容
我这里为了测试就没有播放视频或者使用摄像头的数据,而是直接画了一个颜色上去,但是道理都是一样的
sv = (SurfaceView) findViewById(R.id.sv);sfh = sv.getHolder(); //对 surfaceView 进行操作 sfh.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { Canvas c = sfh.lockCanvas(new Rect(0, 0, 600, 600)); //2.开画 Paint p = new Paint(); p.setColor(Color.RED); Rect aa = new Rect(0, 0, 600, 600); c.drawRect(aa, p); //3. 解锁画布 更新提交屏幕显示内容 sfh.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } });
如果到这一步,这两个界面肯定是不会有上图的效果,而是第一个会覆盖第二个,下面是关键代码了
sv_mini.setZOrderOnTop(true);holder.setFormat(PixelFormat.TRANSPARENT);
把最上面的那个surface设置为最上面,并且然他透明,如果不设置透明,那么只能看到顶部的那个surfaceView,其他地方是黑色的。到这里基本解决了然两个surfaceView重叠显示,下面我们来加入拖动效果
使用layout方法
@TargetApi(Build.VERSION_CODES.HONEYCOMB)@Overridepublic boolean onTouch(View v, MotionEvent event) { int ea = event.getAction(); switch (ea) { case MotionEvent.ACTION_DOWN: lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; /** * layout(l,t,r,b) * l Left position, relative to parent t Top position, relative to parent r Right position, relative to parent b Bottom position, relative to parent * */ case MotionEvent.ACTION_MOVE: int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; int left = v.getLeft() + dx; int top = v.getTop() + dy; int right = v.getRight() + dx; int bottom = v.getBottom() + dy; if (left < 0) { left = 0; right = left + v.getWidth(); } if (right > screenWidth) { right = screenWidth; left = right - v.getWidth(); } if (top < 0) { top = 0; bottom = top + v.getHeight(); } if (bottom > screenHeight) { bottom = screenHeight; top = bottom - v.getHeight(); } v.layout(left, top, right, bottom); Log.i("", "position:" + left + ", " + top + ", " + right + ", " + bottom); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: break; } return true;}
使用margin
带添加~
完整代码
package cn.woblog.testsurfaceview;import android.annotation.TargetApi;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PixelFormat;import android.graphics.Rect;import android.os.Build;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.DisplayMetrics;import android.util.Log;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.ViewGroup;import android.widget.RelativeLayout;public class MainActivity extends AppCompatActivity implements View.OnTouchListener { public static final String TAG = "TAG"; private SurfaceView sv; private SurfaceView sv_mini; private SurfaceHolder sfh; private SurfaceHolder holder; private RelativeLayout rl; private int lastX; private int lastY; private int screenWidth; private int screenHeight; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); DisplayMetrics dm = getResources().getDisplayMetrics(); screenWidth = dm.widthPixels; screenHeight = dm.heightPixels - 50; getSupportActionBar().hide(); sv = (SurfaceView) findViewById(R.id.sv); rl = (RelativeLayout) findViewById(R.id.rl); rl.setOnTouchListener(this); sfh = sv.getHolder(); //对 surfaceView 进行操作 sfh.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { Canvas c = sfh.lockCanvas(new Rect(0, 0, 600, 600)); //2.开画 Paint p = new Paint(); p.setColor(Color.RED); Rect aa = new Rect(0, 0, 600, 600); c.drawRect(aa, p); //3. 解锁画布 更新提交屏幕显示内容 sfh.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } });// 自动运行surfaceCreated以及surfaceChanged sv_mini = (SurfaceView) findViewById(R.id.sv_mini);// sv.setZOrderOnTop(false); //这两个方法差不多,设置了就会浮现到顶部,但是,后面的看不见,要像下面设置为透明 sv_mini.setZOrderOnTop(true); sv_mini.setZOrderMediaOverlay(true); holder = sv_mini.getHolder(); holder.setFormat(PixelFormat.TRANSPARENT); sfh.setFormat(PixelFormat.TRANSPARENT); holder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { Canvas c = holder.lockCanvas(new Rect(0, 0, 400, 400)); //2.开画 Paint p = new Paint(); p.setColor(Color.BLUE); Rect aa = new Rect(0, 0, 400, 400); c.drawRect(aa, p); //3. 解锁画布 更新提交屏幕显示内容 holder.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public boolean onTouch(View v, MotionEvent event) { int ea = event.getAction(); switch (ea) { case MotionEvent.ACTION_DOWN: lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; /** * layout(l,t,r,b) * l Left position, relative to parent t Top position, relative to parent r Right position, relative to parent b Bottom position, relative to parent * */ case MotionEvent.ACTION_MOVE: int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; int left = v.getLeft() + dx; int top = v.getTop() + dy; int right = v.getRight() + dx; int bottom = v.getBottom() + dy; if (left < 0) { left = 0; right = left + v.getWidth(); } if (right > screenWidth) { right = screenWidth; left = right - v.getWidth(); } if (top < 0) { top = 0; bottom = top + v.getHeight(); } if (bottom > screenHeight) { bottom = screenHeight; top = bottom - v.getHeight(); } v.layout(left, top, right, bottom); Log.i("", "position:" + left + ", " + top + ", " + right + ", " + bottom); lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: break; } return true; }}
Demo地址下一期会从源码的角度解析为什么会有上述问题存在,敬请期待
1 0
- 两个surfaceview的重叠效果类似直播效果中的视频和讲义实践
- 两个surfaceview的重叠效果类似直播效果中的视频和讲义实践
- 视频直播中的心形漂浮效果
- 使用surfaceview实现直播中的点赞效果
- 两个div的重叠效果,上层透明
- 视频直播时做多场景切换(实现类似切换台的效果)
- 类似直播飘星动画效果
- 两个surfaceview重叠显示
- 类似优酷首页下面分类视频的效果
- 带有重叠布局的效果
- MediaPlayer和SurFaceView播放视频(疯狂Android讲义-李洋)
- MediaPlayer和SurFaceView播放视频(疯狂Android讲义-李洋)
- Swing中用GridBagConstraints和GridBagLayout实现组件重叠的效果
- Android: 扩展WebView 和ViewPager实现viewpager中的水平滑动,类似Gmail的效果
- label中的文字类似跑马灯的效果
- 类似QQ相册的效果
- 一个类似Listview的效果
- 一个类似Listview的效果
- Linux系统Shell编程基础知识储备
- Python进阶之函数式编程
- AIDL简单实现(1)
- iOS中按钮根据tag来区分
- 一些.net命令行工具的使用
- 两个surfaceview的重叠效果类似直播效果中的视频和讲义实践
- 开发软件的流程--软件工程
- AIDL简单实现(2)
- Linux vi 编辑器常见命令的使用
- Git - 【Github教程】史上最全github使用方法:github入门到精通
- 单链表的一些基本操作
- Java 网络IO编程总结(BIO、NIO、AIO均含完整实例代码)
- 欢迎使用CSDN-markdown编辑器
- AngularJS 模块化