效果图
首先还是不废话,直接上一张图,有图才有真相,不然大家看半天才发现不是我想要的效果,所以这样浪费大家的时间了
实际应用场景可多了,比如后面是显示相机的数据,前面是一个画板,直播的视频和讲义展示
布局
布局就很简单了,直接让两个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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
添加要显示的内容
我这里为了测试就没有播放视频或者使用摄像头的数据,而是直接画了一个颜色上去,但是道理都是一样的
sv = (SurfaceView) findViewById(R.id.sv);sfh = sv.getHolder(); sfh.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { Canvas c = sfh.lockCanvas(new Rect(0, 0, 600, 600)); Paint p = new Paint(); p.setColor(Color.RED); Rect aa = new Rect(0, 0, 600, 600); c.drawRect(aa, p); sfh.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } });
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
如果到这一步,这两个界面肯定是不会有上图的效果,而是第一个会覆盖第二个,下面是关键代码了
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;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
使用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(); sfh.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { Canvas c = sfh.lockCanvas(new Rect(0, 0, 600, 600)); Paint p = new Paint(); p.setColor(Color.RED); Rect aa = new Rect(0, 0, 600, 600); c.drawRect(aa, p); sfh.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); sv_mini = (SurfaceView) findViewById(R.id.sv_mini); 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)); Paint p = new Paint(); p.setColor(Color.BLUE); Rect aa = new Rect(0, 0, 400, 400); c.drawRect(aa, p); 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; }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
Demo地址下一期会从源码的角度解析为什么会有上述问题存在,敬请期待