两个surfaceView实现切换效果
程序员文章站
2023-11-09 16:34:58
需求:视频通话界面,两个surfaceview一个显示本端的视图,另一个显示对端的视图,由于显示比例的问题总会存在一个覆盖另一个的问题,为保证用户体验,规定小的覆盖大的视图上面,且点击...
需求:视频通话界面,两个surfaceview一个显示本端的视图,另一个显示对端的视图,由于显示比例的问题总会存在一个覆盖另一个的问题,为保证用户体验,规定小的覆盖大的视图上面,且点击小的视图可切花为大图视图居中,达到两个视图切花的功能。简单写一个demo完成功能的测试需求,为了较少文章的篇幅,视图的内容用回执矩形代替(实际开发中显示的是本地照相采集的数据和对端经过opgl处理的数据)
简单的布局
<?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实现
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); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。