Two surfaceviews to achieve switching effect

Time:2021-4-17

Demand:In the video call interface, there are two surfaceviews, one displays the local view and the other displays the opposite view. Due to the problem of display scale, there is always the problem of one covering the other. In order to ensure the user experience, it is required that the small view covers the large view, and click the small view to cut the flower in the middle of the large view, so as to achieve the function of two view cutting flowers. Simply write a demo to complete the function test requirements. In order to reduce the length of the article, the content of the view is replaced by the receipt rectangle (in the actual development, the data collected by the local camera and the data processed by OPGL on the opposite end are displayed)

Simple layout


<?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>

Specific demo implementation

public class MainActivity extends Activity implements View.OnClickListener {
 public static final String TAG = "sssss";
 //Remote view
 private SurfaceView remote_sv;
 //Local view
 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();
 //Operate on surfaceview
 remote_holder.addCallback(new SurfaceHolder.Callback() {
  @Override
  public void surfaceCreated(SurfaceHolder holder) {
  Canvas c = remote_holder.lockCanvas();
  //2. Drawing
  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. Unlock the canvas, update and submit the content displayed on the screen
  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. Drawing
  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. Unlock the canvas, update and submit the content displayed on the screen
  remote_holder.unlockCanvasAndPost(c);
  */}

  @Override
  public void surfaceDestroyed(SurfaceHolder holder) {

  }
 }); // automatically run surfacecreated and surfacechanged

 local_sv = (SurfaceView) findViewById(R.id.local_view);
 local_sv.setOnClickListener(this);
 local_sv.setOnClickListener(this);
 // sv.setZOrderOnTop(false);
 local_sv.setZOrderOnTop(true);
 //These two methods are almost the same. Once they are set, they will appear at the top. However, if the back is invisible, they should be set as transparent as the bottom
 // 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. Drawing
  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. Unlock the canvas, update and submit the content displayed on the screen
  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. Drawing
  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. Unlock the canvas, update and submit the content displayed on the screen
  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;
 }

 }
//Zoom in on the view of the far end
 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);

 }
//Specific view operations
 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);

 }
//Zoom out the view of the far end
 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);

 }
//Zoom in on the local view
 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);

 }
//Reduce the local view
 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);

 }
}

The above is the whole content of this article, I hope to help you learn, and I hope you can support developer more.

Recommended Today

Looking for frustration 1.0

I believe you have a basic understanding of trust in yesterday’s article. Today we will give a complete introduction to trust. Why choose rust It’s a language that gives everyone the ability to build reliable and efficient software. You can’t write unsafe code here (unsafe block is not in the scope of discussion). Most of […]