需求:视频通话界面,两个surfaceView一个显示本端的视图,另一个显示对端的视图,由于显示比例的问题总会存在一个覆盖另一个的问题,为保证用户体验,规定小的覆盖大的视图上面,且点击小的视图可切花为大图视图居中,达到两个视图切花的功能。简单写一个demo完成功能的测试需求,为了较少文章的篇幅,视图的内容用回执矩形代替(实际开发中显示的是本地照相采集的数据和对端经过opgl处理的数据)
简单的布局
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
|
<? 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" > < RelativeLayout android:id = "@+id/remote_rl" android:layout_width = "fill_parent" android:layout_height = "wrap_content" > < SurfaceView android:id = "@+id/remote_view" android:layout_width = "match_parent" android:layout_height = "match_parent" </RelativeLayout> android:layout_gravity="center" /> </ RelativeLayout > < RelativeLayout android:id = "@+id/local_rl" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < SurfaceView android:id = "@+id/local_view" android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> </ RelativeLayout > |
具体的demo实现
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
public class MainActivity extends Activity implements View.OnClickListener { public static final String TAG = "sssss" ; //远端的视图 private SurfaceView remote_sv; // 本地的视图 private SurfaceView local_sv; private SurfaceHolder remote_holder; private SurfaceHolder local_holder; private RelativeLayout remote_rl; private RelativeLayout local_rl; private int screenWidth; private int screenHeight; private int beforRemoteweith; private int beforLocalweith; private int beforRemoteheigth; private int beforLocalheigth; private int StateAB = 0 ; private int StateBA = 1 ; private int mSate; private int defaultLocalHeight= 200 ; private int defaultLocalwidth= 400 ; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); DisplayMetrics dm = getResources().getDisplayMetrics(); screenWidth = dm.widthPixels; screenHeight = dm.heightPixels - 500 ; remote_sv = (SurfaceView) findViewById(R.id.remote_view); remote_rl = (RelativeLayout) findViewById(R.id.remote_rl); local_rl = (RelativeLayout) findViewById(R.id.local_rl); remote_sv.setOnClickListener( this ); LayoutParams params = new LayoutParams(screenWidth, screenHeight); remote_sv.setLayoutParams(params); remote_holder = remote_sv.getHolder(); // 对 surfaceView 进行操作 remote_holder.addCallback( new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { Canvas c = remote_holder.lockCanvas(); // 2.开画 Paint p = new Paint(); p.setColor(Color.RED); Rect aa = new Rect( 0 , 0 , holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height()); c.drawRect(aa, p); // 3. 解锁画布 更新提交屏幕显示内容 remote_holder.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { /** * Log.d(TAG,"remote_holder surfaceChanged width"+ width+"height"+height); Canvas c = remote_holder.lockCanvas(); // 2.开画 Paint p = new Paint(); p.setColor(Color.RED); Rect aa = new Rect(0, 0, holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height()); c.drawRect(aa, p); // 3. 解锁画布 更新提交屏幕显示内容 remote_holder.unlockCanvasAndPost(c); */ } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); // 自动运行surfaceCreated以及surfaceChanged local_sv = (SurfaceView) findViewById(R.id.local_view); local_sv.setOnClickListener( this ); local_sv.setOnClickListener( this ); // sv.setZOrderOnTop(false); local_sv.setZOrderOnTop( true ); // 这两个方法差不多,设置了就会浮现到顶部,但是,后面的看不见,要像下面设置为透明 // local_sv.setZOrderOnTop(true); // local_sv.setZOrderMediaOverlay(true); local_holder = local_sv.getHolder(); remote_holder.setFormat(PixelFormat.TRANSPARENT); local_holder.setFormat(PixelFormat.TRANSPARENT); LayoutParams params1 = new LayoutParams(defaultLocalHeight, defaultLocalwidth); local_sv.setLayoutParams(params1); remote_holder = remote_sv.getHolder(); local_holder.addCallback( new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { Canvas c = holder.lockCanvas(); // 2.开画 Paint p = new Paint(); p.setColor(Color.YELLOW); Rect aa = new Rect( 0 , 0 , holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height()); c.drawRect(aa, p); // 3. 解锁画布 更新提交屏幕显示内容 holder.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { /** * Log.d(TAG,"local_holder surfaceChanged width"+ width+"height"+height); Canvas c = holder.lockCanvas(); // 2.开画 Paint p = new Paint(); p.setColor(Color.YELLOW); Rect aa = new Rect(0, 0, holder.getSurfaceFrame().width()-50, holder.getSurfaceFrame().height()-50); c.drawRect(aa, p); // 3. 解锁画布 更新提交屏幕显示内容 holder.unlockCanvasAndPost(c); */ } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }); zoomOpera(local_rl, local_sv, remote_sv, remote_rl, defaultLocalwidth, defaultLocalHeight, RelativeLayout.CENTER_IN_PARENT); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.local_view: Log.d(TAG, " onClick local_view" + mSate); if (mSate == StateAB) { zoomlocalViewout(beforRemoteweith, beforRemoteheigth, local_sv, remote_sv); zoomRemoteViewint(beforLocalweith, beforLocalheigth); mSate = StateBA; } break ; case R.id.remote_view: Log.d(TAG, " onClick emote_view" + mSate); if (mSate == StateBA) { zoomRemoteout(beforRemoteweith, beforRemoteheigth, local_sv, remote_sv); zoomlocalViewint(beforLocalweith, beforLocalheigth); mSate = StateAB; } break ; default : break ; } } //放大远端的视图 private void zoomRemoteout( int weith2, int heigth2, SurfaceView localView, SurfaceView remoteView) { beforLocalheigth = localView.getMeasuredHeight(); beforLocalweith = localView.getMeasuredWidth(); beforRemoteheigth = remoteView.getMeasuredHeight(); beforRemoteweith = remoteView.getMeasuredWidth(); Log.d(TAG, "zoomRemoteout beforLocalheigth" + beforLocalheigth + "beforLocalweith" + beforLocalweith + "beforRemoteheigth" + beforRemoteheigth + "beforRemoteweith" + beforLocalweith); zoomOpera(local_rl, local_sv, remote_sv, remote_rl, screenWidth, beforLocalheigth, RelativeLayout.CENTER_IN_PARENT); } //具体的视图操作 private void zoomOpera(View sourcView, SurfaceView beforeview, SurfaceView afterview, View detView, int beforLocalweith, int beforLocalHeigth, int rule) { LayoutParams params1 = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); Log.w(TAG, "beforLocalheigth = " + beforLocalheigth + "; beforLocalweith = " + beforLocalweith); params1.addRule(rule, RelativeLayout.TRUE); afterview.setLayoutParams(params1); afterview.setBackgroundResource(android.R.color.transparent); params1 = new LayoutParams(beforLocalweith, beforLocalHeigth); params1.addRule(rule, RelativeLayout.TRUE); detView.setLayoutParams(params1); } //缩小远端的视图 private void zoomRemoteViewint( int weith2, int heigth2) { RelativeLayout paretview = (RelativeLayout) local_rl.getParent(); paretview.removeView(remote_rl); paretview.removeView(local_rl); zoomOpera(local_rl, local_sv, remote_sv, remote_rl, beforLocalweith, beforLocalheigth, RelativeLayout.ALIGN_PARENT_TOP); Log.d(TAG, "paretview" + paretview.getChildCount()); paretview.addView(local_rl); paretview.addView(remote_rl); remote_sv.setZOrderOnTop( true ); } //放大本端的视图 private void zoomlocalViewout( int weith2, int heigth2, SurfaceView localView, SurfaceView remoteView) { beforLocalheigth = localView.getMeasuredHeight(); beforLocalweith = localView.getMeasuredWidth(); beforRemoteheigth = remoteView.getMeasuredHeight(); beforRemoteweith = remoteView.getMeasuredWidth(); Log.d(TAG, "zoomlocalViewout beforLocalheigth" + beforLocalheigth + "beforLocalweith" + beforLocalweith + "beforRemoteheigth" + beforRemoteheigth + "beforRemoteweith" + beforRemoteweith); zoomOpera(remote_rl, remote_sv, local_sv, local_rl, beforRemoteweith, beforRemoteheigth, RelativeLayout.CENTER_IN_PARENT); } //减小本端的视图 private void zoomlocalViewint( int weith2, int heigth2) { RelativeLayout paretview = (RelativeLayout) local_rl.getParent(); paretview.removeView(remote_rl); paretview.removeView(local_rl); zoomOpera(remote_rl, remote_sv, local_sv, local_rl, beforRemoteweith, beforRemoteheigth, RelativeLayout.ALIGN_PARENT_TOP); paretview.addView(remote_rl); paretview.addView(local_rl); local_sv.setZOrderOnTop( true ); } } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/xuedaqian123/article/details/77878781