Effect Picture
First of all, don’t talk nonsense, just go to a picture. Only when there is a picture can the truth come out, otherwise everyone will look at it for a long time. I realized that it was not the effect I wanted, so I wasted everyone’s time like this.
There are many practical application scenarios, such as the display of camera data at the back and a drawing board in front , The live video and handout display
layout
The layout is very simple, directly let the two surfaceView overlap each other
<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=< span class="hljs-value">"wrap_content" android:layout_height="wrap_content"> <SurfaceView android:id="@+id/sv_mini" < span class="hljs-attribute">android:layout_width="200dp" android:layout_height="200dp" android:clickable="false" android:focusable="false" /> RelativeLayout>RelativeLayout >
Add content to be displayed
I did not play video or use camera data for testing purposes. , But directly painted a color, but the principle is the same
sv = (SurfaceView) findViewById(R.id.sv);sfh = sv.getHolder(); //Operate surfaceView sfh.addCallback(new SurfaceHolder.C allback() {@Override public void surfaceCreated(SurfaceHolder holder) {Canvas c = sfh.lockCanvas(new Rect(0, 0, 600, 600)); //2. Open painting Paint p = new Paint( ); p.setColor(Color.RED); Rect aa = new Rect(0, 0, 600, 600); c.drawRect( aa, p); //3. Unlock the canvas and update the submission screen display content sfh.unlockCanvasAndPost(c); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} @Override public void surfaceDestroyed(SurfaceHolder holder) {} });
If this step , These two interfaces will definitely not have the effect of the above picture, but the first one will cover the second. Below is the key code
sv_mini.setZOrderOnTop(true);holder.setFormat(PixelFormat.TRANSPARENT);
Set the top surface to the top and make it transparent. If you don’t set transparency , Then only the surfaceView at the top can be seen, and the other places are black. At this point, the overlapping display of the two surfaceViews is basically solved. Let’s add the drag effect.
Use layout method
@TargetApi(Build.VERSION_CODES.HONEYCOMB)@Overridepublic span> 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 + < span class="hljs-string">", " + top + ", " + right + " , " + bottom); lastX = (int) event.getRawX(); lastY = (int< /span>) event.getRawY(); break; case MotionEvent.ACTION_UP: break;} return true;}
use margin
with add~
Complete code
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 and roid.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 span> 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 < span class="hljs-keyword">int lastX; private int lastY; private int screenWidth; private int screenHeight; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView (R.layout.activity_ma in); 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(); //Operate surfaceView sfh.addCallback(new SurfaceHolder.Callback( ) {@Override public void surfaceCreated(SurfaceHolder holder) {Canvas c = sfh.lockCanvas(new Rect(0, 0, 600, 600)); //2. Open painting Paint p = new Paint(); p.setColor(Color.RED); Rect aa = new Rect(0, < span class="hljs-number">0, 600, 600); c. drawRect(aa, p); //3. Unlock the canvas to update and submit the screen display content sfh.unlockCanvasAndPost(c);} @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} @Override public void surfaceDestroyed(SurfaceHolder holder) { } });// Automatically run surfaceCreated and surfaceChanged sv_mini = (SurfaceView) findViewById(R.id.sv_mini);/ / sv.setZOrderOnTop(false); //These two methods are similar. Once set, it will appear to the top. However, the latter is invisible, so you should set it as below Transparent 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 span>, 0, 400, 400 )); //2.Open painting Paint p = new Paint(); p.setColor(Color .BLUE); Rect aa = new Rect(0, 0, 400, 400); c.drawRect(aa, p); //3. Unlock the canvas and update the submission screen display content 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< /span> top = v.getTop() + dy; int right = v.getRight() + dx; int< /span> bottom = v.get Bottom() + 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 span>) event.getRawY(); break; case MotionEvent.ACTION_UP: break;} return true; }}
The next issue of the Demo address will analyze why the above problems exist from the perspective of the source code, so stay tuned