Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
875 views
in Technique[技术] by (71.8m points)

view - Android - Canvas draws over Smartphone's Navigation Bar in SurfaceView

enter image description here

Here the red line crosses over Navigation Bar


Here is the recreation of my problem:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.Example.surfaceviewtest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.SurfaceViewTest">
        <activity android:name=".MainActivity" android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

acitivity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <com.Example.surfaceviewtest.ExampleSurfaceView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"/>
    </HorizontalScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java

package com.Example.surfaceviewtest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

ExampleSurfaceView.xml

package com.Example.surfaceviewtest;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import androidx.annotation.NonNull;

public class ExampleSurfaceView extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder surfaceHolder;
    private HandlerThread handlerThread = new HandlerThread("ExampleHandlerThread");
    private Handler handler;
    private Paint paint;
    public volatile boolean draw = true;

    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            drawView();
        }
    };

    public ExampleSurfaceView(Context context) {
        super(context);init();
    }

    public ExampleSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);init();
    }
    private void init(){
        if(surfaceHolder == null) {
            // Get surfaceHolder object.
            surfaceHolder = getHolder();
            // Add this as surfaceHolder callback object.
            surfaceHolder.addCallback(this);
        }

        this.setZOrderOnTop(true);
        this.setAlpha(0);
        this.getHolder().setFormat(PixelFormat.TRANSPARENT);
        paint  = new Paint(Paint.ANTI_ALIAS_FLAG);

        handlerThread.start();
        handler = new Handler(handlerThread.getLooper());
    }
    @Override
    public void surfaceCreated(@NonNull SurfaceHolder holder) {
        handler.post(runnable);
    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int height = 500;
        int width = 10000;
        setMeasuredDimension(width, height);
    }
    @Override
    public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(@NonNull SurfaceHolder holder) {

    }

    private void drawView(){
        Canvas canvas;
        while(true){
            if(draw){
                canvas = surfaceHolder.lockCanvas();
                canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY);



                paint.setStrokeWidth(10);
                paint.setColor(Color.RED);

                canvas.drawLine(100,100,5000,100,paint);

                 surfaceHolder.unlockCanvasAndPost(canvas);

                 draw = false;
            }
            SystemClock.sleep(50);//for no particular reason
        }
    }
}

So I need help with these:

  • How to prevent line crossing over the Navigation Bar but still scroll under it.(probably work of setZOrderOnTop(true))
  • I want to update the CustomSurfaceView but calling invalidate() or postInvalidate() did nothing so I did this infinite loop solution. When I need to update I change draw variable to true and it updates the view again.
  • I want to draw another layout over top of this SurfaceView but setZOrderOnTop(true) won't let me do it or if I set it false the view completely disappears.

EDIT: Canvas disappears on minimizing and opening again. I think first drawing canvas to a bitmap and setting that bitmap to a image view can be a potential solution for all above problems.

question from:https://stackoverflow.com/questions/65617650/android-canvas-draws-over-smartphones-navigation-bar-in-surfaceview

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...