Android 使用圆形边框视图覆盖纹理视图

Android 使用圆形边框视图覆盖纹理视图,android,textureview,Android,Textureview,这里是Android新手,但我正试图在设备摄像头的TextureView流上覆盖一个透明的圆形视图,但是无论我做什么,我都无法使覆盖视图显示在TextureView的顶部。我已将TextureView实现为: package org.tensorflow.demo; import android.content.Context; import android.util.AttributeSet; import android.view.TextureView; /** * A {@link

这里是Android新手,但我正试图在设备摄像头的TextureView流上覆盖一个透明的圆形视图,但是无论我做什么,我都无法使覆盖视图显示在TextureView的顶部。我已将TextureView实现为:

package org.tensorflow.demo;

import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;

/**
 * A {@link TextureView} that can be adjusted to a specified aspect ratio.
 */
public class AutoFitTextureView extends TextureView {
    private int ratioWidth = 0;
    private int ratioHeight = 0;

    public AutoFitTextureView(final Context context) {
    this(context, null);
  }

    public AutoFitTextureView(final Context context, final AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AutoFitTextureView(final Context context, final AttributeSet attrs, final int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
     *
     * @param width  Relative horizontal size
     * @param height Relative vertical size
     */
    public void setAspectRatio(final int width, final int height) {
        if (width < 0 || height < 0) {
            throw new IllegalArgumentException("Size cannot be negative.");
        }
        ratioWidth = width;
        ratioHeight = height;
        requestLayout();
    }

    @Override
    protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int height = MeasureSpec.getSize(heightMeasureSpec);
        if (0 == ratioWidth || 0 == ratioHeight) {
            setMeasuredDimension(width, height);
        } else {
            if (width < height * ratioWidth / ratioHeight) {
                setMeasuredDimension(width, width * ratioHeight / ratioWidth);
            } else {
                setMeasuredDimension(height * ratioWidth / ratioHeight, height);
            }
        }
    }
}
最后,我的布局xml如下所示:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <org.tensorflow.demo.AutoFitTextureView
        android:id="@+id/texture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <org.tensorflow.demo.OverlayView
        android:id="@+id/overlay"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <org.tensorflow.demo.RecognitionScoreView
        android:id="@+id/results"
        android:layout_width="match_parent"
        android:layout_height="112dp" />

</FrameLayout>

最后使用PorterDuff.Mode.SRC_OUT从全屏矩形中剪切出一个圆来解决此问题:

protected void createWindowFrame() {

    int w = getWidth();
    int h = getHeight();

    windowFrame = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas osCanvas = new Canvas(windowFrame);

    RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight());

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.parseColor("#4885ed"));
    osCanvas.drawRect(outerRectangle, paint);

    paint.setColor(Color.TRANSPARENT);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));

    int pl = getPaddingLeft();
    int pr = getPaddingRight();
    int pt = getPaddingTop();
    int pb = getPaddingBottom();

    int usableWidth = w - (pl + pr);
    int usableHeight = h - (pt + pb);

    int radius = Math.min(usableWidth, usableHeight) / 2;        
    int cx = pl + (usableWidth / 2);
    int cy = pt + (usableHeight / 2);

    osCanvas.drawCircle(cx, cy, radius, paint);
}
protected void createWindowFrame() {

    int w = getWidth();
    int h = getHeight();

    windowFrame = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas osCanvas = new Canvas(windowFrame);

    RectF outerRectangle = new RectF(0, 0, getWidth(), getHeight());

    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setColor(Color.parseColor("#4885ed"));
    osCanvas.drawRect(outerRectangle, paint);

    paint.setColor(Color.TRANSPARENT);
    paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OUT));

    int pl = getPaddingLeft();
    int pr = getPaddingRight();
    int pt = getPaddingTop();
    int pb = getPaddingBottom();

    int usableWidth = w - (pl + pr);
    int usableHeight = h - (pt + pb);

    int radius = Math.min(usableWidth, usableHeight) / 2;        
    int cx = pl + (usableWidth / 2);
    int cy = pt + (usableHeight / 2);

    osCanvas.drawCircle(cx, cy, radius, paint);
}