'How to implement hiding the toolbar when scrolling WebView?
I have an Activity with WebView and my own AppBarLayout. I want to implement hiding/showing the AppBarLayout with animation when scrolling the WebView, like in the Google Chrome app.
I tried different ways.
ObservableWebView, but it doesn't work correctly, it doesn't always show AppBar, especially if the page is short.
ConstraintLayout with animations. Something similar, but still not the same as in Google Chrome.
Coordinator layout. This is the best variant, I think. But it have some bugs.
I have wrote the code of layout like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@android:color/white"
app:layout_scrollFlags="scroll|enterAlways">
<View
android:id="@+id/linkFrame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="visible" />
<HorizontalScrollView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:background="@drawable/frame_link_browser"
android:padding="8dp"
app:layout_constraintBottom_toBottomOf="@+id/linkFrame"
app:layout_constraintEnd_toStartOf="@+id/pauseButton"
app:layout_constraintStart_toEndOf="@+id/linkDivider"
app:layout_constraintTop_toTopOf="@+id/linkFrame">
<TextView
android:id="@+id/linkTextView"
style="@style/BrowserSmallSecondaryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:textColor="@color/textPrimary"
android:textIsSelectable="true"
tools:text="https://vk.com/id118573338"
tools:visibility="visible" />
</HorizontalScrollView>
<View
android:id="@+id/linkDivider"
style="@style/VerticalDivider"
android:layout_height="24dp"
android:layout_centerVertical="true"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:background="#90FFFFFF"
android:textColor="@color/textPrimary"
app:layout_constraintBottom_toBottomOf="@+id/timerTextView"
app:layout_constraintStart_toEndOf="@+id/timerTextView"
app:layout_constraintTop_toTopOf="@+id/timerTextView"
tools:visibility="visible" />
<TextView
android:id="@+id/timerTextView"
style="@style/BrowserMiddlePrimaryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:gravity="center_vertical"
app:layout_constraintBottom_toBottomOf="@+id/linkFrame"
app:layout_constraintStart_toStartOf="@+id/linkFrame"
app:layout_constraintTop_toTopOf="@+id/linkFrame"
tools:text="30" />
<TextView
android:id="@+id/noInternetTextView"
style="@style/BrowserBigPrimaryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:text="@string/no_internet_connection"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/noInternetAdditionalTextView"
style="@style/BrowserSmallSecondaryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_internet_connection_additional"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="@+id/noInternetTextView"
app:layout_constraintTop_toBottomOf="@+id/noInternetTextView" />
<ImageButton
android:id="@+id/pauseButton"
android:layout_width="44dp"
android:layout_height="44dp"
android:background="@color/transparent"
android:text="@string/pause"
app:layout_constraintBottom_toBottomOf="@+id/linkFrame"
app:layout_constraintEnd_toStartOf="@+id/settingsButton"
app:layout_constraintTop_toTopOf="@+id/linkFrame"
app:srcCompat="@drawable/ic_pause_circle_filled_white_36dp"
tools:visibility="visible" />
<ImageButton
android:id="@+id/settingsButton"
android:layout_width="44dp"
android:layout_height="44dp"
android:background="@color/transparent"
android:text="@string/settings"
app:layout_constraintBottom_toBottomOf="@+id/linkFrame"
app:layout_constraintEnd_toEndOf="@+id/linkFrame"
app:layout_constraintTop_toTopOf="@+id/linkFrame"
app:srcCompat="@drawable/ic_settings_white_36dp"
tools:visibility="visible" />
</android.support.constraint.ConstraintLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="4dp"
android:indeterminate="false"
android:max="100"
android:progress="0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<com.github.ksoichiro.android.observablescrollview.ObservableWebView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
In this case the page is not scrolling. I have tried many variants. If in the behavior I put clean webview (without swiperefresh, nestedscrolling etc) it's work correctly, but if I lock and unlock the screen - WebView swells up and on the bottom of page appears white empty place. I have been trying to solve this problem for several days now, but it doesn’t work. Please help make a stable solution to this problem. Thank you very much.
I tried this method: How to Hide ActionBar/Toolbar While Scrolling Down in Webview but if I lock and unlock the screen - WebView swells up and on the bottom of page appears white empty place
Solution 1:[1]
I created WebView with this features and it works perfect:
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.webkit.WebView;
public class NestedWebView extends WebView implements NestedScrollingChild, Scrollable {
private int mLastY;
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private int mNestedOffsetY;
private NestedScrollingChildHelper mChildHelper;
private int mScrollY;
private ScrollViewCallback callback;
private boolean firstScroll = true;
public NestedWebView(Context context) {
this(context, null);
}
public NestedWebView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.webViewStyle);
}
public NestedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
}
public void setOnScrollListener(ScrollViewCallback callback) {
this.callback = callback;
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
boolean returnValue = false;
MotionEvent event = MotionEvent.obtain(ev);
final int action = MotionEventCompat.getActionMasked(event);
if (action == MotionEvent.ACTION_DOWN) {
mNestedOffsetY = 0;
}
int eventY = (int) event.getY();
event.offsetLocation(0, mNestedOffsetY);
switch (action) {
case MotionEvent.ACTION_MOVE:
int deltaY = mLastY - eventY;
// NestedPreScroll
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
deltaY -= mScrollConsumed[1];
mLastY = eventY - mScrollOffset[1];
event.offsetLocation(0, -mScrollOffset[1]);
mNestedOffsetY += mScrollOffset[1];
}
returnValue = super.onTouchEvent(event);
// NestedScroll
if (dispatchNestedScroll(0, mScrollOffset[1], 0, deltaY, mScrollOffset)) {
event.offsetLocation(0, mScrollOffset[1]);
mNestedOffsetY += mScrollOffset[1];
mLastY -= mScrollOffset[1];
}
break;
case MotionEvent.ACTION_DOWN:
returnValue = super.onTouchEvent(event);
if (firstScroll) {
// dispatching first down scrolling properly by making sure that first deltaY will be -ve
mLastY = eventY - 5;
firstScroll = false;
} else {
mLastY = eventY;
}
// start NestedScroll
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
break;
default:
returnValue = super.onTouchEvent(event);
break;
}
return returnValue;
}
// Nested Scroll implements
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return mChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return mChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return mChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,
int[] offsetInWindow) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
mScrollY = t;
dispatchOnScrollChanged(mScrollY);
}
private void dispatchOnScrollChanged(int scrollY) {
if (callback != null) {
callback.onScrollChanged(scrollY);
}
}
// Scrollable implements
@Override
public void setScrollViewCallbacks(ObservableScrollViewCallbacks listener) {
}
@Override
public void scrollVerticallyTo(int y) {
}
@Override
public int getCurrentScrollY() {
return mScrollY;
}
@Override
public void setTouchInterceptionViewGroup(ViewGroup viewGroup) {
}
public interface ScrollViewCallback {
void onScrollChanged(int scrollY);
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |