Commit 3ff59f65 authored by Bo Liu's avatar Bo Liu Committed by Commit Bot

Fix input offset under browser control

Copies ContentView from components and EventOffsetHandler from chrome.
These together will call EventForwarder.setCurrentTouchEventOffsets at
the right times to correctly offset user input under browser controls

Change-Id: I29a418457c4daf2306e7ce13e8311a489b1ca958
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1796046Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Bo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695823}
parent a8bef4d0
......@@ -115,6 +115,11 @@ int BrowserControllerImpl::GetTopControlsHeight() {
#endif
}
bool BrowserControllerImpl::DoBrowserControlsShrinkRendererSize(
const content::WebContents* web_contents) {
return true;
}
void BrowserControllerImpl::DidFirstVisuallyNonEmptyPaint() {
for (auto& observer : observers_)
observer.FirstContentfulPaint();
......
......@@ -62,6 +62,8 @@ class BrowserControllerImpl : public BrowserController,
void DidNavigateMainFramePostCommit(
content::WebContents* web_contents) override;
int GetTopControlsHeight() override;
bool DoBrowserControlsShrinkRendererSize(
const content::WebContents* web_contents) override;
// content::WebContentsObserver implementation:
void DidFirstVisuallyNonEmptyPaint() override;
......
......@@ -9,7 +9,9 @@ android_library("java") {
java_files = [
"org/chromium/weblayer_private/BrowserControllerImpl.java",
"org/chromium/weblayer_private/BrowserObserverProxy.java",
"org/chromium/weblayer_private/ContentView.java",
"org/chromium/weblayer_private/ContentViewRenderView.java",
"org/chromium/weblayer_private/EventOffsetHandler.java",
"org/chromium/weblayer_private/NavigationControllerImpl.java",
"org/chromium/weblayer_private/NavigationImpl.java",
"org/chromium/weblayer_private/ProfileImpl.java",
......@@ -20,7 +22,6 @@ android_library("java") {
deps = [
":client_java",
"//base:base_java",
"//components/embedder_support/android:content_view_java",
"//content/public/android:content_java",
"//ui/android:ui_java",
]
......
......@@ -13,7 +13,6 @@ import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.components.embedder_support.view.ContentView;
import org.chromium.content_public.browser.ViewEventSink;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.ActivityWindowAndroid;
......@@ -72,8 +71,11 @@ public final class BrowserControllerImpl extends IBrowserController.Stub {
mNativeBrowserController = nativeCreateBrowserController(profile.getNativeProfile());
mWebContents = nativeGetWebContents(mNativeBrowserController);
mContentView = ContentView.createContentView(context, mWebContents);
ViewAndroidDelegate viewAndroidDelegate = new ViewAndroidDelegate(mContentViewRenderView) {
mTopControlsContainerView =
new TopControlsContainerView(context, mWebContents, mContentViewRenderView);
mContentView = ContentView.createContentView(
context, mWebContents, mTopControlsContainerView.getEventOffsetHandler());
ViewAndroidDelegate viewAndroidDelegate = new ViewAndroidDelegate(mContentView) {
@Override
public void onTopControlsChanged(int topControlsOffsetY, int topContentOffsetY) {
mTopControlsContainerView.onTopControlsChanged(
......@@ -89,8 +91,6 @@ public final class BrowserControllerImpl extends IBrowserController.Stub {
new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY));
mTopControlsContainerView =
new TopControlsContainerView(context, mWebContents, mContentViewRenderView);
nativeSetTopControlsContainerView(
mNativeBrowserController, mTopControlsContainerView.getNativeHandle());
mContentView.addView(mTopControlsContainerView,
......
// Copyright 2012 The Chromium 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 org.chromium.weblayer_private;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.DragEvent;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnSystemUiVisibilityChangeListener;
import android.view.ViewGroup.OnHierarchyChangeListener;
import android.view.ViewStructure;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.widget.FrameLayout;
import org.chromium.base.ObserverList;
import org.chromium.base.TraceEvent;
import org.chromium.base.compat.ApiHelperForO;
import org.chromium.content_public.browser.ImeAdapter;
import org.chromium.content_public.browser.RenderCoordinates;
import org.chromium.content_public.browser.SmartClipProvider;
import org.chromium.content_public.browser.ViewEventSink;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.WebContentsAccessibility;
import org.chromium.ui.base.EventForwarder;
/**
* The containing view for {@link WebContents} that exists in the Android UI hierarchy and exposes
* the various {@link View} functionality to it.
*/
public class ContentView extends FrameLayout
implements ViewEventSink.InternalAccessDelegate, SmartClipProvider,
OnHierarchyChangeListener, OnSystemUiVisibilityChangeListener {
private static final String TAG = "cr.ContentView";
// Default value to signal that the ContentView's size need not be overridden.
public static final int DEFAULT_MEASURE_SPEC =
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
private final WebContents mWebContents;
private final ObserverList<OnHierarchyChangeListener> mHierarchyChangeListeners =
new ObserverList<>();
private final ObserverList<OnSystemUiVisibilityChangeListener> mSystemUiChangeListeners =
new ObserverList<>();
private ViewEventSink mViewEventSink;
private EventForwarder mEventForwarder;
/**
* The desired size of this view in {@link MeasureSpec}. Set by the host
* when it should be different from that of the parent.
*/
private int mDesiredWidthMeasureSpec = DEFAULT_MEASURE_SPEC;
private int mDesiredHeightMeasureSpec = DEFAULT_MEASURE_SPEC;
private EventOffsetHandler mEventOffsetHandler;
/**
* Constructs a new ContentView for the appropriate Android version.
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param webContents The WebContents managing this content view.
* @return an instance of a ContentView.
*/
public static ContentView createContentView(
Context context, WebContents webContents, EventOffsetHandler eventOffsetHandler) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return new ContentViewApi23(context, webContents, eventOffsetHandler);
}
return new ContentView(context, webContents, eventOffsetHandler);
}
/**
* Creates an instance of a ContentView.
* @param context The Context the view is running in, through which it can
* access the current theme, resources, etc.
* @param webContents A pointer to the WebContents managing this content view.
*/
ContentView(Context context, WebContents webContents, EventOffsetHandler eventOffsetHandler) {
super(context, null, android.R.attr.webViewStyle);
if (getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) {
setHorizontalScrollBarEnabled(false);
setVerticalScrollBarEnabled(false);
}
mWebContents = webContents;
mEventOffsetHandler = eventOffsetHandler;
setFocusable(true);
setFocusableInTouchMode(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ApiHelperForO.setDefaultFocusHighlightEnabled(this, false);
}
setOnHierarchyChangeListener(this);
setOnSystemUiVisibilityChangeListener(this);
}
protected WebContentsAccessibility getWebContentsAccessibility() {
return !mWebContents.isDestroyed() ? WebContentsAccessibility.fromWebContents(mWebContents)
: null;
}
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
WebContentsAccessibility wcax = getWebContentsAccessibility();
return wcax != null && wcax.supportsAction(action)
? wcax.performAction(action, arguments)
: super.performAccessibilityAction(action, arguments);
}
/**
* Set the desired size of the view. The values are in {@link MeasureSpec}.
* @param width The width of the content view.
* @param height The height of the content view.
*/
public void setDesiredMeasureSpec(int width, int height) {
mDesiredWidthMeasureSpec = width;
mDesiredHeightMeasureSpec = height;
}
@Override
public void setOnHierarchyChangeListener(OnHierarchyChangeListener listener) {
assert listener == this : "Use add/removeOnHierarchyChangeListener instead.";
super.setOnHierarchyChangeListener(listener);
}
/**
* Registers the given listener to receive state changes for the content view hierarchy.
* @param listener Listener to receive view hierarchy state changes.
*/
public void addOnHierarchyChangeListener(OnHierarchyChangeListener listener) {
mHierarchyChangeListeners.addObserver(listener);
}
/**
* Unregisters the given listener from receiving state changes for the content view hierarchy.
* @param listener Listener that doesn't want to receive view hierarchy state changes.
*/
public void removeOnHierarchyChangeListener(OnHierarchyChangeListener listener) {
mHierarchyChangeListeners.removeObserver(listener);
}
@Override
public void setOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener listener) {
assert listener == this : "Use add/removeOnSystemUiVisibilityChangeListener instead.";
super.setOnSystemUiVisibilityChangeListener(listener);
}
/**
* Registers the given listener to receive system UI visibility state changes.
* @param listener Listener to receive system UI visibility state changes.
*/
public void addOnSystemUiVisibilityChangeListener(OnSystemUiVisibilityChangeListener listener) {
mSystemUiChangeListeners.addObserver(listener);
}
/**
* Unregisters the given listener from receiving system UI visibility state changes.
* @param listener Listener that doesn't want to receive state changes.
*/
public void removeOnSystemUiVisibilityChangeListener(
OnSystemUiVisibilityChangeListener listener) {
mSystemUiChangeListeners.removeObserver(listener);
}
// View.OnHierarchyChangeListener implementation
@Override
public void onChildViewRemoved(View parent, View child) {
for (OnHierarchyChangeListener listener : mHierarchyChangeListeners) {
listener.onChildViewRemoved(parent, child);
}
}
@Override
public void onChildViewAdded(View parent, View child) {
for (OnHierarchyChangeListener listener : mHierarchyChangeListeners) {
listener.onChildViewAdded(parent, child);
}
}
// View.OnHierarchyChangeListener implementation
@Override
public void onSystemUiVisibilityChange(int visibility) {
for (OnSystemUiVisibilityChangeListener listener : mSystemUiChangeListeners) {
listener.onSystemUiVisibilityChange(visibility);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mDesiredWidthMeasureSpec != DEFAULT_MEASURE_SPEC) {
widthMeasureSpec = mDesiredWidthMeasureSpec;
}
if (mDesiredHeightMeasureSpec != DEFAULT_MEASURE_SPEC) {
heightMeasureSpec = mDesiredHeightMeasureSpec;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
WebContentsAccessibility wcax = getWebContentsAccessibility();
AccessibilityNodeProvider provider =
(wcax != null) ? wcax.getAccessibilityNodeProvider() : null;
return (provider != null) ? provider : super.getAccessibilityNodeProvider();
}
// Needed by ViewEventSink.InternalAccessDelegate
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
// Calls may come while/after WebContents is destroyed. See https://crbug.com/821750#c8.
if (mWebContents.isDestroyed()) return null;
return ImeAdapter.fromWebContents(mWebContents).onCreateInputConnection(outAttrs);
}
@Override
public boolean onCheckIsTextEditor() {
if (mWebContents.isDestroyed()) return false;
return ImeAdapter.fromWebContents(mWebContents).onCheckIsTextEditor();
}
@Override
protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
try {
TraceEvent.begin("ContentView.onFocusChanged");
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
getViewEventSink().setHideKeyboardOnBlur(true);
getViewEventSink().onViewFocusChanged(gainFocus);
} finally {
TraceEvent.end("ContentView.onFocusChanged");
}
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
getViewEventSink().onWindowFocusChanged(hasWindowFocus);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return getEventForwarder().onKeyUp(keyCode, event);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return isFocused() ? getEventForwarder().dispatchKeyEvent(event)
: super.dispatchKeyEvent(event);
}
@Override
public boolean onDragEvent(DragEvent event) {
return getEventForwarder().onDragEvent(event, this);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
boolean ret = super.onInterceptTouchEvent(e);
mEventOffsetHandler.onInterceptTouchEvent(e);
return ret;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean ret = getEventForwarder().onTouchEvent(event);
mEventOffsetHandler.onTouchEvent(event);
return ret;
}
@Override
public boolean onInterceptHoverEvent(MotionEvent e) {
mEventOffsetHandler.onInterceptHoverEvent(e);
return super.onInterceptHoverEvent(e);
}
@Override
public boolean dispatchDragEvent(DragEvent e) {
mEventOffsetHandler.onPreDispatchDragEvent(e.getAction());
boolean ret = super.dispatchDragEvent(e);
mEventOffsetHandler.onPostDispatchDragEvent(e.getAction());
return ret;
}
/**
* Mouse move events are sent on hover enter, hover move and hover exit.
* They are sent on hover exit because sometimes it acts as both a hover
* move and hover exit.
*/
@Override
public boolean onHoverEvent(MotionEvent event) {
boolean consumed = getEventForwarder().onHoverEvent(event);
WebContentsAccessibility wcax = getWebContentsAccessibility();
if (wcax != null && !wcax.isTouchExplorationEnabled()) super.onHoverEvent(event);
return consumed;
}
@Override
public boolean onGenericMotionEvent(MotionEvent event) {
return getEventForwarder().onGenericMotionEvent(event);
}
private EventForwarder getEventForwarder() {
if (mEventForwarder == null) {
mEventForwarder = mWebContents.getEventForwarder();
}
return mEventForwarder;
}
private ViewEventSink getViewEventSink() {
if (mViewEventSink == null) mViewEventSink = ViewEventSink.from(mWebContents);
return mViewEventSink;
}
@Override
public boolean performLongClick() {
return false;
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
getViewEventSink().onConfigurationChanged(newConfig);
super.onConfigurationChanged(newConfig);
}
/**
* Currently the ContentView scrolling happens in the native side. In
* the Java view system, it is always pinned at (0, 0). scrollBy() and scrollTo()
* are overridden, so that View's mScrollX and mScrollY will be unchanged at
* (0, 0). This is critical for drawing ContentView correctly.
*/
@Override
public void scrollBy(int x, int y) {
getEventForwarder().scrollBy(x, y);
}
@Override
public void scrollTo(int x, int y) {
getEventForwarder().scrollTo(x, y);
}
@Override
protected int computeHorizontalScrollExtent() {
RenderCoordinates rc = RenderCoordinates.fromWebContents(mWebContents);
return rc != null ? rc.getLastFrameViewportWidthPixInt() : 0;
}
@Override
protected int computeHorizontalScrollOffset() {
RenderCoordinates rc = RenderCoordinates.fromWebContents(mWebContents);
return rc != null ? rc.getScrollXPixInt() : 0;
}
@Override
protected int computeHorizontalScrollRange() {
RenderCoordinates rc = RenderCoordinates.fromWebContents(mWebContents);
return rc != null ? rc.getContentWidthPixInt() : 0;
}
@Override
protected int computeVerticalScrollExtent() {
RenderCoordinates rc = RenderCoordinates.fromWebContents(mWebContents);
return rc != null ? rc.getLastFrameViewportHeightPixInt() : 0;
}
@Override
protected int computeVerticalScrollOffset() {
RenderCoordinates rc = RenderCoordinates.fromWebContents(mWebContents);
return rc != null ? rc.getScrollYPixInt() : 0;
}
@Override
protected int computeVerticalScrollRange() {
RenderCoordinates rc = RenderCoordinates.fromWebContents(mWebContents);
return rc != null ? rc.getContentHeightPixInt() : 0;
}
// End FrameLayout overrides.
@Override
public boolean awakenScrollBars(int startDelay, boolean invalidate) {
// For the default implementation of ContentView which draws the scrollBars on the native
// side, calling this function may get us into a bad state where we keep drawing the
// scrollBars, so disable it by always returning false.
if (getScrollBarStyle() == View.SCROLLBARS_INSIDE_OVERLAY) return false;
return super.awakenScrollBars(startDelay, invalidate);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
getViewEventSink().onAttachedToWindow();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
getViewEventSink().onDetachedFromWindow();
}
// Implements SmartClipProvider
@Override
public void extractSmartClipData(int x, int y, int width, int height) {
mWebContents.requestSmartClipExtract(x, y, width, height);
}
// Implements SmartClipProvider
@Override
public void setSmartClipResultHandler(final Handler resultHandler) {
mWebContents.setSmartClipResultHandler(resultHandler);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// Start Implementation of ViewEventSink.InternalAccessDelegate //
///////////////////////////////////////////////////////////////////////////////////////////////
@Override
public boolean super_onKeyUp(int keyCode, KeyEvent event) {
return super.onKeyUp(keyCode, event);
}
@Override
public boolean super_dispatchKeyEvent(KeyEvent event) {
return super.dispatchKeyEvent(event);
}
@Override
public boolean super_onGenericMotionEvent(MotionEvent event) {
return super.onGenericMotionEvent(event);
}
///////////////////////////////////////////////////////////////////////////////////////////////
// End Implementation of ViewEventSink.InternalAccessDelegate //
///////////////////////////////////////////////////////////////////////////////////////////////
private static class ContentViewApi23 extends ContentView {
public ContentViewApi23(
Context context, WebContents webContents, EventOffsetHandler eventOffsetHandler) {
super(context, webContents, eventOffsetHandler);
}
@Override
public void onProvideVirtualStructure(final ViewStructure structure) {
WebContentsAccessibility wcax = getWebContentsAccessibility();
if (wcax != null) wcax.onProvideVirtualStructure(structure, false);
}
}
}
// Copyright 2018 The Chromium 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 org.chromium.weblayer_private;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.ui.base.SPenSupport;
/**
* A class to update motion event offset while dragging. This is needed to compensate the change
* caused by top control.
* TODO: Note this class is copied from src/chrome and should be shared.
*/
public class EventOffsetHandler {
/**
* A delegate for EventOffsetHandler.
*/
interface EventOffsetHandlerDelegate {
float getTop();
void setCurrentTouchEventOffsets(float top);
}
private final EventOffsetHandlerDelegate mDelegate;
public EventOffsetHandler(EventOffsetHandlerDelegate delegate) {
mDelegate = delegate;
}
/**
* Call this before handling onDispatchDragEvent.
* @param action Drag event action.
*/
public void onPreDispatchDragEvent(int action) {
setTouchEventOffsets(-mDelegate.getTop());
}
/**
* Call this after handling onDispatchDragEvent.
* @param action Drag event action.
*/
public void onPostDispatchDragEvent(int action) {
if (action == DragEvent.ACTION_DRAG_EXITED || action == DragEvent.ACTION_DRAG_ENDED
|| action == DragEvent.ACTION_DROP) {
setTouchEventOffsets(0.f);
}
}
/** See {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}. */
public void onInterceptTouchEvent(MotionEvent e) {
setContentViewMotionEventOffsets(e, false);
}
/** See {@link View#onTouchEvent(MotionEvent)}. */
public void onTouchEvent(MotionEvent e) {
setContentViewMotionEventOffsets(e, true);
}
/** See {@link ViewGroup#onInterceptHoverEvent(MotionEvent)}. */
public void onInterceptHoverEvent(MotionEvent e) {
setContentViewMotionEventOffsets(e, true);
}
private void setContentViewMotionEventOffsets(MotionEvent e, boolean canClear) {
int actionMasked = SPenSupport.convertSPenEventAction(e.getActionMasked());
if (actionMasked == MotionEvent.ACTION_DOWN
|| actionMasked == MotionEvent.ACTION_HOVER_ENTER
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
setTouchEventOffsets(-mDelegate.getTop());
} else if (canClear
&& (actionMasked == MotionEvent.ACTION_UP
|| actionMasked == MotionEvent.ACTION_CANCEL
|| actionMasked == MotionEvent.ACTION_HOVER_EXIT)) {
setTouchEventOffsets(0.f);
}
}
private void setTouchEventOffsets(float y) {
mDelegate.setCurrentTouchEventOffsets(y);
}
}
......@@ -41,6 +41,9 @@ class TopControlsContainerView extends FrameLayout {
private View mView;
private ContentViewRenderView mContentViewRenderView;
private WebContents mWebContents;
private EventOffsetHandler mEventOffsetHandler;
private int mTopContentOffset;
// True if scrolling.
private boolean mInTopControlsScroll;
......@@ -54,6 +57,19 @@ class TopControlsContainerView extends FrameLayout {
Context context, WebContents webContents, ContentViewRenderView contentViewRenderView) {
super(context);
mContentViewRenderView = contentViewRenderView;
mWebContents = webContents;
mEventOffsetHandler =
new EventOffsetHandler(new EventOffsetHandler.EventOffsetHandlerDelegate() {
@Override
public float getTop() {
return mTopContentOffset;
}
@Override
public void setCurrentTouchEventOffsets(float top) {
mWebContents.getEventForwarder().setCurrentTouchEventOffsets(0, top);
}
});
mNativeTopControlsContainerView = nativeCreateTopControlsContainerView(
webContents, contentViewRenderView.getNativeHandle());
}
......@@ -67,6 +83,10 @@ class TopControlsContainerView extends FrameLayout {
return mNativeTopControlsContainerView;
}
public EventOffsetHandler getEventOffsetHandler() {
return mEventOffsetHandler;
}
/**
* Sets the view from the client.
*/
......@@ -105,8 +125,7 @@ class TopControlsContainerView extends FrameLayout {
return;
}
if (!mInTopControlsScroll) prepareForTopControlsScroll();
nativeSetTopControlsOffset(
mNativeTopControlsContainerView, topControlsOffsetY, topContentOffsetY);
setTopControlsOffset(topControlsOffsetY, topContentOffsetY);
}
@SuppressLint("NewApi") // Used on O+, invalidateChildInParent used for previous versions.
......@@ -172,10 +191,16 @@ class TopControlsContainerView extends FrameLayout {
private void finishTopControlsScroll(int topContentOffsetY) {
mInTopControlsScroll = false;
nativeSetTopControlsOffset(mNativeTopControlsContainerView, 0, topContentOffsetY);
setTopControlsOffset(0, topContentOffsetY);
mContentViewRenderView.postOnAnimation(() -> showTopControls());
}
private void setTopControlsOffset(int topControlsOffsetY, int topContentOffsetY) {
mTopContentOffset = topContentOffsetY;
nativeSetTopControlsOffset(
mNativeTopControlsContainerView, topControlsOffsetY, topContentOffsetY);
}
private void prepareForTopControlsScroll() {
mInTopControlsScroll = true;
mContentViewRenderView.postOnAnimation(() -> hideTopControls());
......
......@@ -24,7 +24,7 @@
android:launchMode="singleTask"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="stateUnspecified">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment