欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

两个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);

 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。