如何在 Webview 中向下滚动时隐藏操作栏/工具栏
Posted
技术标签:
【中文标题】如何在 Webview 中向下滚动时隐藏操作栏/工具栏【英文标题】:How to Hide ActionBar/Toolbar While Scrolling Down in Webview 【发布时间】:2015-04-30 11:41:51 【问题描述】:在 Google chrome 和 Play 商店中。该应用程序可以在滚动时隐藏操作栏,并允许用户方便地浏览。请帮我这样做。
我在 webview 中使用了 onTouchListener,它不起作用。
mWebView.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
switch (event.getAction())
case MotionEvent.ACTION_DOWN:
getSupportActionBar().show();
break;
case MotionEvent.ACTION_UP:
getSupportActionBar().hide();
break;
default: break;
return false;
);
提前致谢
【问题讨论】:
隐藏操作栏的例子是here 此示例显示线性布局。如何在 webview 中实现这一点 这里有一个例子[***.com/questions/14752523/… 【参考方案1】:您可以使用设计库的CoordinatorLayout
和NestedScrollView
并在Toolbar
上设置app:layout_scrollFlags
来执行此操作,而无需任何Java 代码。这是你如何做到的。
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_>
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_
android:layout_
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_
android:layout_
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:layout_gravity="fill_vertical"
android:fillViewport="true"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<WebView
android:id="@+id/webview"
android:layout_
android:layout_/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
一旦掌握了窍门,您就可以使用不同的 layout_scrollFlags 和 fitSystemWindows 行为。
【讨论】:
这很好用,但是你通过手势松开了“缩放”。有没有办法在这个解决方案中再次获得它?谢谢 有些人可能会发现有必要将android:fillViewport="true"
添加到NestedScrollView
以使其占据其容器的全部可用高度。奇怪的是,android:layout_gravity="fill_vertical"
在所有情况下都不足以实现这一目标。
它按预期工作,出现此错误“java.lang.IllegalStateException:无法为 WebView 创建层,大小 1200x17076 超过最大大小 16384”。有什么解决办法吗?
添加新布局会降低性能。这不是正确的解决方案。至于你的问题@Sudarshan,它正在发生,因为它会创建全尺寸的网页视图(与网页相同)并尝试渲染它。因此,您将失去 webview 优化,其中仅呈现页面的一部分。我不建议使用此解决方案。
在 ScrollView 中使用 Webview 的错误做法,跳转链接不起作用。【参考方案2】:
我已经通过CustomWebView
和GestureDetector
实现了:
CustomWebView.java:
public class CustomWebView extends WebView
private GestureDetector gestureDetector;
public CustomWebView(Context context)
super(context);
public CustomWebView(Context context, AttributeSet attrs)
super(context, attrs);
public CustomWebView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt)
super.onScrollChanged(l, t, oldl, oldt);
@Override
public boolean onTouchEvent(MotionEvent ev)
return gestureDetector.onTouchEvent(ev) || super.onTouchEvent(ev);
public void setGestureDetector(GestureDetector gestureDetector)
this.gestureDetector = gestureDetector;
web_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:background="@android:color/transparent"
android:orientation="vertical">
<com.customview.CustomWebView
android:id="@+id/customWebView"
android:layout_
android:layout_
android:focusable="true" />
</LinearLayout>
CustomeGestureDetector 用于手势检测的 clss(我已在 Fragment 中添加):
private class CustomeGestureDetector extends GestureDetector.SimpleOnGestureListener
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
if(e1 == null || e2 == null) return false;
if(e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return false;
else
try
if(e1.getY() - e2.getY() > 20 )
// Hide Actionbar
getSupportActionBar().hide();
customWebView.invalidate();
return false;
else if (e2.getY() - e1.getY() > 20 )
// Show Actionbar
getSupportActionBar().show();
customWebView.invalidate();
return false;
catch (Exception e)
customWebView.invalidate();
return false;
WebFragment.java:
private CustomWebView customWebView;
customWebView= (CustomWebView) view.findViewById(R.id.customWebView);
customWebView.setGestureDetector(new GestureDetector(new CustomeGestureDetector()));
对我来说很好用,希望对你有帮助。
【讨论】:
谢谢你,这很有帮助!但是,我会将您的CustomGestureDetector
类的名称更改为 CustomGestureDetectorListener
或其他名称,因为它不是 GestureDetector。事实上,它令人困惑。【参考方案3】:
package com.keshav.hideactionbarandfooterexample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import java.util.ArrayList;
import java.util.List;
import adapters.RecyclerAdapter;
import listners.HidingScrollListener;
public class MainActivity extends AppCompatActivity
private Toolbar mToolbar;
private Toolbar toolbar_bottom;
private ImageButton mFabButton;
@Override
protected void onCreate(Bundle savedInstanceState)
setTheme(R.style.AppThemeRed);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e("keshav", "MainActivity called");
initToolbar();
mFabButton = (ImageButton) findViewById(R.id.fabButton);
initRecyclerView();
private void initToolbar()
mToolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar_bottom = (Toolbar) findViewById(R.id.toolbar_bottom);
setSupportActionBar(mToolbar);
setSupportActionBar(toolbar_bottom);
setTitle(getString(R.string.app_name));
mToolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
toolbar_bottom.setTitleTextColor(getResources().getColor(android.R.color.white));
toolbar_bottom.setVisibility(View.GONE);
private void initRecyclerView()
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerAdapter recyclerAdapter = new RecyclerAdapter(createItemList());
recyclerView.setAdapter(recyclerAdapter);
recyclerView.addOnScrollListener(new HidingScrollListener()
@Override
public void onHide()
hideViews();
@Override
public void onShow()
showViews();
);
private void hideViews()
// TODO (-mToolbar) plus means 2 view above ho jaye or not visible to user
mToolbar.animate().translationY(-mToolbar.getHeight()).setInterpolator(new AccelerateInterpolator(2));
// TODO uncomment this Hide Footer in android when Scrolling
// TODO (+mToolbar) plus means 2 view forward ho jaye or not visible to user
toolbar_bottom.animate().translationY(+toolbar_bottom.getHeight()).setInterpolator(new AccelerateInterpolator(2));
// TODO keshav Hide Also Floatng Button In Android
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mFabButton.getLayoutParams();
int fabBottomMargin = lp.bottomMargin;
mFabButton.animate().translationY(mFabButton.getHeight() + fabBottomMargin).setInterpolator(new AccelerateInterpolator(2)).start();
// TODO keshav Hide Also Floatng Button In Android
private void showViews()
mToolbar.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
// TODO uncomment this Hide Footer in android when Scrolling
toolbar_bottom.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2));
mFabButton.animate().translationY(0).setInterpolator(new DecelerateInterpolator(2)).start();
private List<String> createItemList()
List<String> itemList = new ArrayList<>();
for (int i = 0; i < 20; i++)
itemList.add("Item " + i);
return itemList;
=============================================
RecyclerAdapter
=============================================
package adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.keshav.hideactionbarandfooterexample.R;
import java.util.List;
/*
* RecyclerView Adapter that allows to add a header view.
* */
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
private static final int TYPE_HEADER = 2;
private static final int TYPE_ITEM = 1;
private List<String> mItemList;
public RecyclerAdapter(List<String> itemList)
mItemList = itemList;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
Context context = parent.getContext();
if (viewType == TYPE_ITEM)
final View view = LayoutInflater.from(context).inflate(R.layout.recycler_item, parent, false);
return RecyclerItemViewHolder.newInstance(view);
else if (viewType == TYPE_HEADER)
final View view = LayoutInflater.from(context).inflate(R.layout.recycler_header, parent, false);
return new RecyclerHeaderViewHolder(view);
throw new RuntimeException("There is no type that matches the type " + viewType + " + make sure your using types correctly");
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
if (!isPositionHeader(position))
RecyclerItemViewHolder holder = (RecyclerItemViewHolder) viewHolder;
String itemText = mItemList.get(position - 1); // header
holder.setItemText(itemText);
public int getBasicItemCount()
return mItemList == null ? 0 : mItemList.size();
@Override
public int getItemViewType(int position)
if (isPositionHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
@Override
public int getItemCount()
return getBasicItemCount() + 1; // header
private boolean isPositionHeader(int position)
return position == 0;
=====================================================
RecyclerHeaderViewHolder
=====================================================
package adapters;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class RecyclerHeaderViewHolder extends RecyclerView.ViewHolder
public RecyclerHeaderViewHolder(View itemView)
super(itemView);
=====================================================
RecyclerItemViewHolder
=====================================================
package adapters;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.keshav.hideactionbarandfooterexample.R;
public class RecyclerItemViewHolder extends RecyclerView.ViewHolder
private final TextView mItemTextView;
public RecyclerItemViewHolder(final View parent, TextView itemTextView)
super(parent);
mItemTextView = itemTextView;
public static RecyclerItemViewHolder newInstance(View parent)
TextView itemTextView = (TextView) parent.findViewById(R.id.itemTextView);
return new RecyclerItemViewHolder(parent, itemTextView);
public void setItemText(CharSequence text)
mItemTextView.setText(text);
===================================================
activity_main.xml
===================================================
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_>
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_
android:layout_/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_
android:layout_
android:background="?attr/colorPrimary"/>
<ImageButton
android:id="@+id/fabButton"
android:layout_
android:layout_
android:layout_gravity="bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp"
android:background="@drawable/fab_bcg"
android:src="@drawable/ic_favorite_outline_white_24dp"
android:contentDescription="@string/fab_description"/>
<RelativeLayout
android:layout_
android:layout_>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_bottom"
android:layout_
android:layout_alignParentBottom="true"
android:layout_
android:background="?attr/colorPrimary"/>
</RelativeLayout>
</FrameLayout>
==================================================
recycle_header.xml in layout folder
==================================================
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_/>
==================================================
recycle_item.xml in layout folder
==================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_
android:layout_
android:layout_gravity="center"
android:layout_margin="8dp"
card_view:cardCornerRadius="4dp">
<TextView
android:id="@+id/itemTextView"
android:layout_
android:layout_
android:gravity="center_vertical"
android:padding="8dp"
style="@style/Base.TextAppearance.AppCompat.Body2"/>
</android.support.v7.widget.CardView>
=================================================
styles.xml
=================================================
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
</style>
<style name="AppThemeRed" parent="AppTheme">
<item name="colorPrimary">@color/color_primary_red</item>
<item name="colorPrimaryDark">@color/color_primary_red_dark</item>
</style>
<style name="AppThemeGreen" parent="AppTheme">
<item name="colorPrimary">@color/color_primary_green</item>
<item name="colorPrimaryDark">@color/color_primary_green_dark</item>
</style>
<style name="AppThemeBlue" parent="AppTheme">
<item name="colorPrimary">@color/color_primary_blue</item>
<item name="colorPrimaryDark">@color/color_primary_blue_dark</item>
<item name="colorAccent">@color/color_accent_pink</item>
</style>
</resources>
build.gradle 依赖
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:recyclerview-v7:25.3.1'
compile 'com.android.support:cardview-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
【讨论】:
drive.google.com/open?id=0BzBKpZ4nzNzUVi0xeU1UMjZHeFE整个以上是关于如何在 Webview 中向下滚动时隐藏操作栏/工具栏的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Xamarin Forms 中滚动时折叠(隐藏或向上滑动)导航栏(标题栏)?
向下滚动时隐藏导航栏并在用户使用 jquery 向上滚动页面时显示它,不能正常工作