GVKun编程网logo

Android中的surfaceHolder.lockCanvas(null)返回为null详解

24

本文将带您了解关于Android中的surfaceHolder.lockCanvas(null)返回为null详解的新内容,另外,我们还将为您提供关于Android-Canvas在SurfaceVie

本文将带您了解关于Android中的surfaceHolder.lockCanvas(null)返回为null详解的新内容,另外,我们还将为您提供关于Android - Canvas 在 SurfaceView 中的智能手机导航栏上绘制、android surfaceview中的canvas为空、android usb hid通信,interface中的getendpoint这个方法返回null、Android ViewHolder 中的 getView 有时会返回 `null`的实用信息。

本文目录一览:

Android中的surfaceHolder.lockCanvas(null)返回为null详解

Android中的surfaceHolder.lockCanvas(null)返回为null详解

对于新手学习SurfaceView的时候获取lockCanvas的时候总是返回null的问题很是纠结

canvas = surfaceHolder.lockCanvas(new Rect(0, 0, 300,getWindowManager().getDefaultDisplay().getHeight()));

原因是surfaceView里面调用draw()的时候,获取的控件的width和height都是0,然后把它放到OnClickListener里面用,结果没有问题了,所以在获取到width和height不为0的地方调用就可以了。

Android - Canvas 在 SurfaceView 中的智能手机导航栏上绘制

Android - Canvas 在 SurfaceView 中的智能手机导航栏上绘制

如何解决Android - Canvas 在 SurfaceView 中的智能手机导航栏上绘制?

enter image description here

这里的红线越过导航栏


这是我的问题的重现:

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,paint);

                 surfaceHolder.unlockCanvasAndPost(canvas);

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

所以我需要帮助:

  • 如何防止线越过导航栏但仍然滚动 在它之下。(可能是 setZOrderOnTop(true) 的工作)
  • 我想更新 CustomSurfaceView 但调用 invalidate() 或 postInvalidate() 什么也没做,所以我做了这个无限循环解决方案。当我需要更新时,我将绘制变量更改为 true 并再次更新视图。
  • 我想在此 SurfaceView 之上绘制另一个布局,但 setZOrderOnTop(true) 不允许我这样做,或者如果我将其设置为 false,则视图完全消失。

编辑:画布在最小化和再次打开时消失。我认为首先将画布绘制为位图并将该位图设置为图像视图可能是上述所有问题的潜在解决方案。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

android surfaceview中的canvas为空

android surfaceview中的canvas为空

下面代码第一次进入的时候可以画出图像,点击返回后,再次进入mCanvas = holder.lockCanvas(null)就为空,不知道为什么,急切求解中...

public RecordWaveformView(Context context, AttributeSet attrs) {
        super(context, attrs);
        MyLogger.i(TAG, "RecordWaveformView");
        mHolder = this.getHolder();
        mHolder.addCallback(this);
        setFocusable(true);
    }

    public void startDraw(byte[] pcmData) {
        MyLogger.i(TAG, "startDraw");
        // initData(pcmData);
        Message msg = Message.obtain();
        msg.what = 0;
        msg.obj = pcmData;
        mDrawThread.mHandler.sendMessage(msg);
    }

    class DrawThread extends Thread {
        private Handler mHandler;
        public ArrayList<Short> inBuf = new ArrayList<Short>();
        private ByteArrayInputStream byteArrayInputStream;
        private SurfaceHolder holder;
        public boolean isRunning;
        private Canvas mCanvas;

        private byte[] buffer = new byte[1764];

        public DrawThread(SurfaceHolder holder) {
            this.holder = holder;
        }

        public void run() {

            MyLogger.i(TAG, "handleMessage=" + isRunning);
            while (isRunning) {
                MyLogger.i(TAG, "run");
                Looper.prepare();

                mHandler = new Handler() {
                    public void handleMessage(Message msg) {
                        if (msg.what == 0) {

                            byte[] obj = (byte[]) msg.obj;

                            initData(obj);
                            draw();

                        }
                    }
                };

                Looper.loop();
            }

        }

        private void initData(byte[] pcmData) {
            MyLogger.i(TAG, "initData" + pcmData.length);
            byteArrayInputStream = new ByteArrayInputStream(pcmData);
            MyLogger.i(TAG, "byteArrayInputStream");
            int readsize = byteArrayInputStream.read(buffer, 0, 1764);
            int len = readsize / rateX;
            for (int i = 0; i < len; i++) {
                inBuf.add((short) ((0x0000 | buffer[i + 1]) << 8 | buffer[i]));
            }

        }

        private void draw() {
            MyLogger.i(TAG, "draw" + inBuf.size());

            if (rateY == 0) {
                rateY = 50000 / getHeight();
                baseLine = getHeight() / 2;
            }

            synchronized (holder) {
                try {
                    mCanvas = holder.lockCanvas(null);
                    // 获得canvas
                    MyLogger.i(TAG, "holder" + mCanvas + holder);
                    if (mCanvas != null) {
                        Paint paint = new Paint();
                        paint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
                        mCanvas.drawPaint(paint);
                        paint.setXfermode(new PorterDuffXfermode(Mode.SRC));

                        MyLogger.i(TAG, "drawColor");
                        int start = getWidth() - inBuf.size() * divider;
                        MyLogger.i(TAG, "start=" + start);
                        int py = baseLine;
                        if (inBuf.size() > 0) {
                            py += inBuf.get(0) / rateY;
                        }
                        int y;
                        mCanvas.drawLine(0, baseLine, start - divider,
                                baseLine, mWaveformPaint);
                        for (int i = 0; i < inBuf.size(); i++) {
                            y = inBuf.get(i) / rateY + baseLine;// 调节缩小比例,调节基准线
                            MyLogger.i(TAG, "y=" + y);
                            mCanvas.drawLine(start + (i - 1) * divider, py,
                                    start + i * divider, y, mWaveformPaint);
                            py = y;
                        }

                    }
                } catch (Exception e) {
                } finally {
                    if (mCanvas != null) {
                        holder.unlockCanvasAndPost(mCanvas);
                    }
                }
            }

        }
    }




android usb hid通信,interface中的getendpoint这个方法返回null

android usb hid通信,interface中的getendpoint这个方法返回null

Android ViewHolder 中的 getView 有时会返回 `null`

Android ViewHolder 中的 getView 有时会返回 `null`

如何解决Android ViewHolder 中的 getView 有时会返回 `null`?

在 RecyclerView 中的某些列表项上间歇性地显示更多文本。如果 description 文本扩展了 5 行,则应显示更多显示。这似乎不是单个项目的问题。

enter image description here

description 是在 ViewHolder 中找到的 TextView。在进行了一些调试后,我发现 description.layout (getLayout) 有时会返回 null,因此它无法执行其余的逻辑。

我试图找出为什么 layout 有时会返回 null,所以添加了一个 addOnLayoutchangelistener 来查找大小是否发生变化,结果是 null,{{ 1}} 为 addOnLayoutchangelistenerbottom

返回一些新值

下面是我的 Task 的 ViewHolder 中的 snipper,其中显示/隐藏 right show more 文本的逻辑。

show less

    Handler(Looper.getMainLooper()).post {
        description.layout?.let { l ->
            val lines = l.lineCount
            if (expanded || lines > 0 && l.getEllipsisCount(lines - 1) > 0) {
                showMoreLess.visibility = View.VISIBLE
                showMoreLess.setonClickListener { showMoreLesstapped() }
            } else {
                showMoreLess.visibility = View.GONE
                showMoreLess.setonClickListener {  }
            }
        }
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

关于Android中的surfaceHolder.lockCanvas(null)返回为null详解的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Android - Canvas 在 SurfaceView 中的智能手机导航栏上绘制、android surfaceview中的canvas为空、android usb hid通信,interface中的getendpoint这个方法返回null、Android ViewHolder 中的 getView 有时会返回 `null`的相关知识,请在本站寻找。

本文标签:

上一篇linux ftok()函数 -- 多进程 IPC 之共享内存(linux进程间共享内存)

下一篇RuntimeError: Compression requires the (missing) zlib module