国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android 類似UC瀏覽器的效果:向上滑動地址欄隱藏功能

2019-10-22 18:18:18
字體:
來源:轉載
供稿:網友

思路

要求

ScrollView 嵌套 地址欄 和 WebView

手指滑屏向下滾動(網頁向上),如果網頁有滾動條,首先把 地址欄 滾動到消失,然后 WebView 才開始滾動;

手指滑屏向上滾動(網頁向下),如果地址欄隱藏,那么 地址欄 首先慢慢顯示,然后 WebView 才開始滾動。

實現方案

  • 根據 View 的 onInterceptTouchEvent 和 onTouchEvent 原理。把 ScrollView 設置為 WebView 的一個變量,在 WebView的 onInterceptTouchEvent 方法里檢測到 MotionEvent.ACTION_DOWN 事件后中斷事件,在 WebView 的 onTouchEvent 事件中根據具體情況決定是把 MotionEvent.ACTION_MOVE 事件傳送給 ScrollView 還是留給自己
  • 由于MotionEvent.ACTION_MOVE 事件傳送給 ScrollView 后無法在一次 Touch 事件中再接收,所以會導致如果有地址欄,向下滑動第一次只能滑動到 ScrollView 消失
  • +
  • Hack網頁,加入JS腳本,前行讓網頁頂部空出來一段空白,空白處覆蓋地址欄
  • 優點是WebView大小不變化,容易控制
  • 缺點是比較復雜要處理各種網頁元素,各種 position 情況,實現復雜,效率低
  • 由手勢接管所有觸發操作,再由它分發給需要滾動的控件

本文方法

資源

SrollView下面包含節點地址欄,WebView控件

<?xml version="1.0" encoding="utf-8"?><RelativeLayout android:id="@+id/root" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <samples.zjc.com.testbrowserfeature.MyScrollView  android:id="@+id/scrollView"  android:scrollbars="none"  android:layout_width="match_parent"  android:layout_height="match_parent">  <LinearLayout   android:orientation="vertical"   android:layout_width="match_parent"   android:layout_height="match_parent">   <LinearLayout    android:id="@+id/toolBar"    android:background="#5ff0"    android:orientation="horizontal"    android:layout_width="match_parent"    android:layout_height="wrap_content">    <EditText     android:id="@+id/urlEdit"     android:layout_weight="1"     android:layout_width="0dp"     android:layout_height="wrap_content"/>    <Button     android:id="@+id/goButton"     android:text="Go"     android:layout_width="wrap_content"     android:layout_height="wrap_content"/>   </LinearLayout>   <samples.zjc.com.testbrowserfeature.MyWebView    android:id="@+id/webView"    android:layout_width="match_parent"    android:layout_height="100dp" />  </LinearLayout> </samples.zjc.com.testbrowserfeature.MyScrollView></RelativeLayout>

ScrollView繼承自 ScrollView

onTouchEvent 中阻止 MotionEvent.ACTION_MOVE 事件public class MyScrollView extends ScrollView { public MyScrollView(Context context) {  super(context); } public MyScrollView(Context context, AttributeSet attrs) {  super(context, attrs); } public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {  super(context, attrs, defStyleAttr, defStyleRes); } @Override public boolean onTouchEvent(MotionEvent ev) {  if(ev.getAction() == MotionEvent.ACTION_MOVE) {   return true;  }  return super.onTouchEvent(ev); }}

MyWebView繼承自 WebView

onTouchEvent 中阻止 MotionEvent.ACTION_MOVE 事件

onDrawListner

計算豎直滾動范圍

public class MyWebView extends WebView { public interface MyWebViewListener {  void afterDraw(WebView webView); } private MyWebViewListener mListener; private int mMoveCheckedCnt; public MyWebView(Context context) {  super(context); } public MyWebView(Context context, AttributeSet attrs) {  super(context, attrs); } public MyWebView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public MyWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {  super(context, attrs, defStyleAttr, defStyleRes); } public MyWebView(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {  super(context, attrs, defStyleAttr, privateBrowsing); } public void setListener(MyWebViewListener listener) {  mListener = listener; } @Override public boolean onTouchEvent(MotionEvent event) {  switch (event.getAction()) {   case MotionEvent.ACTION_DOWN:    mMoveCheckedCnt = 0;    flingScroll(0, 0);    break;   case MotionEvent.ACTION_MOVE:    mMoveCheckedCnt++;    return false;   case MotionEvent.ACTION_UP:    if(mMoveCheckedCnt >= 2) {     event.setAction(MotionEvent.ACTION_CANCEL);     mMoveCheckedCnt = 0;    }    break;  }  return super.onTouchEvent(event); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  MyWebViewListener listener = mListener;  if(listener != null) {   listener.afterDraw(this);  } } public int getVScrollRange() {  int v = computeVerticalScrollRange() - computeVerticalScrollExtent();  if(v < 0) {   v = 0;  }  return v; }}

主窗口

GlobalLayoutListener 獲取地址欄和滾動視圖高度

GestureDetector 邏輯分發 - 決定是滑動webview還是改變webview高度從而改變ScrollView滾動范圍(ScrollView總是滾動到最底)

WebView 重畫之后檢測當前地址欄偏移

public class MainActivity extends AppCompatActivity implements MyWebView.MyWebViewListener { MyWebView mWebView; GestureDetector mGesture = null; View mToolBar; int mToolBarHeight; MyScrollView mScrollView; int mScrollViewHeight; int mScrollOffset; EditText mUrlEdit; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  mWebView = (MyWebView) findViewById(R.id.webView);  mWebView.setWebViewClient(new WebViewClient() {   @Override   public boolean shouldOverrideUrlLoading(WebView view, String url) {    return false;   }  });  mWebView.setListener(this);  mWebView.loadUrl("http://www.sohu.com");  mUrlEdit = (EditText) findViewById(R.id.urlEdit);  findViewById(R.id.goButton).setOnClickListener(new View.OnClickListener() {   @Override   public void onClick(View v) {    String url = mUrlEdit.getText().toString();    if (!url.startsWith("http://") && !url.startsWith("https://")) {     url = "http://" + url;    }    mWebView.loadUrl(url);   }  });  mToolBar = findViewById(R.id.toolBar);  mScrollView = (MyScrollView)findViewById(R.id.scrollView);  ScrollView scrollView = (ScrollView) mScrollView;  findViewById(R.id.root).getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {   @Override   public void onGlobalLayout() {    mToolBarHeight = mToolBar.getHeight();    mScrollViewHeight = mScrollView.getHeight();    adjustScrollView();   }  });  mGesture = new GestureDetector(this, new GestureListener()); } @Override public boolean dispatchTouchEvent(MotionEvent ev) {  mGesture.onTouchEvent(ev);  return super.dispatchTouchEvent(ev); } @Override public void afterDraw(WebView webView) {  if (mWebView.getVScrollRange() < mScrollOffset) {   mScrollOffset = mWebView.getVScrollRange();   adjustScrollView();  } } class GestureListener extends GestureDetector.SimpleOnGestureListener {  @Override  public boolean onDoubleTap(MotionEvent e) {   Log.e("Temp", "onDoubleTap");   return super.onDoubleTap(e);  }  @Override  public boolean onDown(MotionEvent e) {   Log.e("Temp", "onDown");   return super.onDown(e);  }  @Override  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,        float velocityY) {   Log.e("Temp", "onFling:velocityX = " + velocityX + " velocityY" + velocityY);   int effectX = (int) velocityX;   int effectY = (int) velocityY;   if (effectOnScrollViewByScroll((velocityY < 0 ? 1 : -1) * 8000)) {    effectY = 0;   }   mWebView.flingScroll(-effectX, -effectY);   return super.onFling(e1, e2, velocityX, velocityY);  }  @Override  public void onLongPress(MotionEvent e) {   Log.e("Temp", "onLongPress");   super.onLongPress(e);  }  @Override  public boolean onScroll(MotionEvent e1, MotionEvent e2,        float distanceX, float distanceY) {   Log.e("Temp", "onScroll:distanceX = " + distanceX + " distanceY = " + distanceY);   int effectX = (int) distanceX;   int effectY = (int) distanceY;   if (effectOnScrollViewByScroll((int) distanceY)) {    effectY = 0;   }   mWebView.scrollBy(effectX, effectY);   return super.onScroll(e1, e2, distanceX, distanceY);  }  @Override  public boolean onSingleTapUp(MotionEvent e) {   Log.e("Temp", "onSingleTapUp");   return super.onSingleTapUp(e);  } } private boolean effectOnScrollViewByScroll(int distanceY) {  if (distanceY > 0) {   // scroll up, the web will scroll down   if (mScrollOffset >= mToolBarHeight || mScrollOffset >= mWebView.getVScrollRange()) {    return false;   }   mScrollOffset += distanceY;   if (mScrollOffset > mToolBarHeight) {    mScrollOffset = mToolBarHeight;   }   if (mScrollOffset > mWebView.getVScrollRange()) {    mScrollOffset = mWebView.getVScrollRange();   }  } else {   if (mScrollOffset <= 0) {    return false;   }   mScrollOffset += distanceY;   if (mScrollOffset <= 0) {    mScrollOffset = 0;   }  }  adjustScrollView();  return true; } private void adjustScrollView() {  Log.e("Temp", "offset is " + mScrollOffset);  ViewGroup.LayoutParams layoutParams = mWebView.getLayoutParams();  int newHeight = (mScrollViewHeight - mToolBarHeight) + mScrollOffset;  Log.e("Temp", "newHeight is " + newHeight + ", layoutParams.height" + layoutParams.height);  if (newHeight != layoutParams.height) {   layoutParams.height = newHeight;   mWebView.setLayoutParams(layoutParams);   new Handler(Looper.getMainLooper()).post(new Runnable() {    @Override    public void run() {     mScrollView.fullScroll(ScrollView.FOCUS_DOWN);    }   });  } }}

總結

以上所述是小編給大家介紹的Android 類似UC瀏覽器的效果:向上滑動地址欄隱藏功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VEVB武林網網站的支持!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 方城县| 久治县| 玉树县| 亚东县| 富顺县| 宁强县| 通榆县| 泰兴市| 集贤县| 通州区| 翼城县| 三门县| 汤阴县| 公主岭市| 容城县| 正安县| 土默特右旗| 郎溪县| 海宁市| 阜阳市| 岱山县| 通许县| 湟中县| 肥乡县| 广灵县| 贵定县| 大姚县| 定陶县| 明星| 卓尼县| 永寿县| 儋州市| 南平市| 东兰县| 清徐县| 翁牛特旗| 泰和县| 和林格尔县| 芜湖县| 鄂伦春自治旗| 平果县|