未验证 提交 14af0348 编写于 作者: A amirh 提交者: GitHub

Complete the AndroidView resize call only after a new frame is ready. (#5968)

This allows the framework to know that a frame with the resized view is
ready and to behave deterministically to workaround the jank issue
described in flutter/flutter/19572
上级 08b660ed
......@@ -171,7 +171,7 @@ public class PlatformViewsController implements MethodChannel.MethodCallHandler
result.success(null);
}
private void resizePlatformView(MethodCall call, MethodChannel.Result result) {
private void resizePlatformView(MethodCall call, final MethodChannel.Result result) {
Map<String, Object> args = call.arguments();
int id = (int) args.get("id");
double width = (double) args.get("width");
......@@ -188,10 +188,15 @@ public class PlatformViewsController implements MethodChannel.MethodCallHandler
}
vdController.resize(
toPhysicalPixels(width),
toPhysicalPixels(height)
);
toPhysicalPixels(height),
new Runnable() {
@Override
public void run() {
result.success(null);
}
}
);
}
private void onTouch(MethodCall call, MethodChannel.Result result) {
List<Object> args = call.arguments();
......
......@@ -12,6 +12,7 @@ import android.hardware.display.VirtualDisplay;
import android.os.Build;
import android.view.Surface;
import android.view.View;
import android.view.ViewTreeObserver;
@TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
class VirtualDisplayController {
......@@ -70,9 +71,8 @@ class VirtualDisplayController {
mPresentation.show();
}
public void resize(int width, int height) {
PlatformView view = mPresentation.detachView();
mPresentation.hide();
public void resize(final int width, final int height, final Runnable onNewSizeFrameAvailable) {
final PlatformView view = mPresentation.detachView();
// We detach the surface to prevent it being destroyed when releasing the vd.
//
// setSurface is only available starting API 20. We could support API 19 by re-creating a new
......@@ -91,6 +91,33 @@ class VirtualDisplayController {
mSurface,
0
);
final View embeddedView = getView();
// There's a bug in Android version older than O where view tree observer onDrawListeners don't get properly
// merged when attaching to window, as a workaround we register the on draw listener after the view is attached.
embeddedView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
embeddedView.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
@Override
public void onDraw() {
// We need some delay here until the frame propagates through the vd surface to to the texture,
// 128ms was picked pretty arbitrarily based on trial and error.
// As long as we invoke the runnable after a new frame is available we avoid the scaling jank
// described in: https://github.com/flutter/flutter/issues/19572
// We should ideally run onNewSizeFrameAvailable ASAP to make the embedded view more responsive
// following a resize.
embeddedView.postDelayed(onNewSizeFrameAvailable, 128);
embeddedView.getViewTreeObserver().removeOnDrawListener(this);
}
});
embeddedView.removeOnAttachStateChangeListener(this);
}
@Override
public void onViewDetachedFromWindow(View v) {}
});
mPresentation = new SingleViewPresentation(mContext, mVirtualDisplay.getDisplay(), view);
mPresentation.show();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册