未验证 提交 1913040e 编写于 作者: M Maurice Parrish 提交者: GitHub

Creates a new RenderMode for FlutterView (#19143)

上级 a188779b
......@@ -689,6 +689,7 @@ FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/Flutt
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterEngineProvider.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterFragment.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterFragmentActivity.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterImageView.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterSplashView.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterSurfaceView.java
FILE: ../../../flutter/shell/platform/android/io/flutter/embedding/android/FlutterTextureView.java
......
......@@ -135,6 +135,7 @@ android_java_sources = [
"io/flutter/embedding/android/FlutterEngineProvider.java",
"io/flutter/embedding/android/FlutterFragment.java",
"io/flutter/embedding/android/FlutterFragmentActivity.java",
"io/flutter/embedding/android/FlutterImageView.java",
"io/flutter/embedding/android/FlutterSplashView.java",
"io/flutter/embedding/android/FlutterSurfaceView.java",
"io/flutter/embedding/android/FlutterTextureView.java",
......
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.embedding.android;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorSpace;
import android.hardware.HardwareBuffer;
import android.media.Image;
import android.media.Image.Plane;
import android.media.ImageReader;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Paints a Flutter UI provided by an {@link android.media.ImageReader} onto a {@link
* android.graphics.Canvas}.
*
* <p>A {@code FlutterImageView} is intended for situations where a developer needs to render a
* Flutter UI, but also needs to render an interactive {@link
* io.flutter.plugin.platform.PlatformView}.
*
* <p>This {@code View} takes an {@link android.media.ImageReader} that provides the Flutter UI in
* an {@link android.media.Image} and renders it to the {@link android.graphics.Canvas} in {@code
* onDraw}.
*/
@SuppressLint("ViewConstructor")
@TargetApi(19)
public class FlutterImageView extends View {
private final ImageReader imageReader;
@Nullable private Image nextImage;
@Nullable private Image currentImage;
/**
* Constructs a {@code FlutterImageView} with an {@link android.media.ImageReader} that provides
* the Flutter UI.
*/
public FlutterImageView(@NonNull Context context, @NonNull ImageReader imageReader) {
super(context, null);
this.imageReader = imageReader;
}
/** Acquires the next image to be drawn to the {@link android.graphics.Canvas}. */
@TargetApi(19)
public void acquireLatestImage() {
nextImage = imageReader.acquireLatestImage();
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (nextImage == null) {
return;
}
if (currentImage != null) {
currentImage.close();
}
currentImage = nextImage;
nextImage = null;
if (android.os.Build.VERSION.SDK_INT >= 29) {
drawImageBuffer(canvas);
return;
}
drawImagePlane(canvas);
}
@TargetApi(29)
private void drawImageBuffer(@NonNull Canvas canvas) {
final HardwareBuffer buffer = currentImage.getHardwareBuffer();
final Bitmap bitmap = Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB));
canvas.drawBitmap(bitmap, 0, 0, null);
}
private void drawImagePlane(@NonNull Canvas canvas) {
if (currentImage == null) {
return;
}
final Plane[] imagePlanes = currentImage.getPlanes();
if (imagePlanes.length != 1) {
return;
}
final Plane imagePlane = imagePlanes[0];
final int desiredWidth = imagePlane.getRowStride() / imagePlane.getPixelStride();
final int desiredHeight = currentImage.getHeight();
final Bitmap bitmap =
android.graphics.Bitmap.createBitmap(
desiredWidth, desiredHeight, android.graphics.Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(imagePlane.getBuffer());
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
......@@ -79,6 +79,7 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
// Internal view hierarchy references.
@Nullable private FlutterSurfaceView flutterSurfaceView;
@Nullable private FlutterTextureView flutterTextureView;
@Nullable private FlutterImageView flutterImageView;
@Nullable private RenderSurface renderSurface;
private final Set<FlutterUiDisplayListener> flutterUiDisplayListeners = new HashSet<>();
private boolean isFlutterUiDisplayed;
......@@ -155,7 +156,8 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
/**
* Deprecated - use {@link #FlutterView(Context, FlutterSurfaceView)} or {@link
* #FlutterView(Context, FlutterTextureView)} instead.
* #FlutterView(Context, FlutterTextureView)} or {@link #FlutterView(Context, FlutterImageView)}
* instead.
*/
@Deprecated
public FlutterView(@NonNull Context context, @NonNull RenderMode renderMode) {
......@@ -164,9 +166,12 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
if (renderMode == RenderMode.surface) {
flutterSurfaceView = new FlutterSurfaceView(context);
renderSurface = flutterSurfaceView;
} else {
} else if (renderMode == RenderMode.texture) {
flutterTextureView = new FlutterTextureView(context);
renderSurface = flutterTextureView;
} else {
throw new IllegalArgumentException(
String.format("RenderMode not supported with this constructor: ", renderMode));
}
init();
......@@ -216,6 +221,18 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
this(context, null, flutterTextureView);
}
/**
* Constructs a {@code FlutterView} programmatically, without any XML attributes, uses the given
* {@link FlutterImageView} to render the Flutter UI.
*
* <p>{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
* compatible with {@link PlatformViewsController}.
*/
@TargetApi(19)
public FlutterView(@NonNull Context context, @NonNull FlutterImageView flutterImageView) {
this(context, null, flutterImageView);
}
/**
* Constructs a {@code FlutterView} in an XML-inflation-compliant manner.
*
......@@ -243,9 +260,12 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
flutterSurfaceView =
new FlutterSurfaceView(context, transparencyMode == TransparencyMode.transparent);
renderSurface = flutterSurfaceView;
} else {
} else if (renderMode == RenderMode.texture) {
flutterTextureView = new FlutterTextureView(context);
renderSurface = flutterTextureView;
} else {
throw new IllegalArgumentException(
String.format("RenderMode not supported with this constructor: ", renderMode));
}
init();
......@@ -275,15 +295,30 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
init();
}
@TargetApi(19)
private FlutterView(
@NonNull Context context,
@Nullable AttributeSet attrs,
@NonNull FlutterImageView flutterImageView) {
super(context, attrs);
this.flutterImageView = flutterImageView;
init();
}
private void init() {
Log.v(TAG, "Initializing FlutterView");
if (flutterSurfaceView != null) {
Log.v(TAG, "Internally using a FlutterSurfaceView.");
addView(flutterSurfaceView);
} else {
} else if (flutterTextureView != null) {
Log.v(TAG, "Internally using a FlutterTextureView.");
addView(flutterTextureView);
} else {
Log.v(TAG, "Internally using a FlutterImageView.");
addView(flutterImageView);
}
// FlutterView needs to be focusable so that the InputMethodManager can interact with it.
......@@ -1018,7 +1053,16 @@ public class FlutterView extends FrameLayout implements MouseCursorPlugin.MouseC
* android.graphics.SurfaceTexture} are required, developers should strongly prefer the {@link
* RenderMode#surface} render mode.
*/
texture
texture,
/**
* {@code RenderMode}, which paints Paints a Flutter UI provided by an {@link
* android.media.ImageReader} onto a {@link android.graphics.Canvas}. This mode is not as
* performant as {@link RenderMode#surface}, but a {@code FlutterView} in this mode can handle
* full interactivity with a {@link io.flutter.plugin.platform.PlatformView}. Unless {@link
* io.flutter.plugin.platform.PlatformView}s are required developers should strongly prefer the
* {@link RenderMode#surface} render mode.
*/
image
}
/**
......
......@@ -21,5 +21,14 @@ public enum RenderMode {
* Views}. Unless the special capabilities of a {@link android.graphics.SurfaceTexture} are
* required, developers should strongly prefer the {@link #surface} render mode.
*/
texture
texture,
/**
* {@code RenderMode}, which paints Paints a Flutter UI provided by an {@link
* android.media.ImageReader} onto a {@link android.graphics.Canvas}. This mode is not as
* performant as {@link RenderMode#surface}, but a {@code FlutterView} in this mode can handle
* full interactivity with a {@link io.flutter.plugin.platform.PlatformView}. Unless {@link
* io.flutter.plugin.platform.PlatformView}s are required developers should strongly prefer the
* {@link RenderMode#surface} render mode.
*/
image
}
......@@ -12,6 +12,7 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.media.ImageReader;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
......@@ -370,6 +371,17 @@ public class FlutterViewTest {
assertEquals(100, viewportMetricsCaptor.getValue().paddingRight);
}
@Test
public void flutterImageView_acquiresImageAndInvalidates() {
final ImageReader mockReader = mock(ImageReader.class);
final FlutterImageView imageView =
spy(new FlutterImageView(RuntimeEnvironment.application, mockReader));
imageView.acquireLatestImage();
verify(mockReader, times(1)).acquireLatestImage();
verify(imageView, times(1)).invalidate();
}
/*
* A custom shadow that reports fullscreen flag for system UI visibility
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册