SoFunction
Updated on 2025-03-11

Android similar to UC browser: Slide up the address bar to hide function

Ideas

Require

ScrollView Nested Address Bar and WebView

Slide your fingers to scroll down (web page up). If the web page has scroll bars, first scroll the address bar to disappear, and then the WebView starts scrolling;

Slide your fingers to scroll upwards (web pages down). If the address bar is hidden, then the address bar will be displayed slowly first, and then the WebView will start scrolling.

Implementation plan

  • According to the onInterceptTouchEvent and onTouchEvent principles of View. Set ScrollView as a variable of the WebView, and interrupt the MotionEvent.ACTION_DOWN event is detected in the onInterceptTouchEvent method of the WebView. In the onTouchEvent event of the WebView, decide whether to send the MotionEvent.ACTION_MOVE event to the ScrollView or leave it to yourself based on the specific situation.
  • Since the MotionEvent.ACTION_MOVE event cannot be received in a Touch event after being transmitted to the ScrollView, if there is an address bar, it will only slide down to the ScrollView for the first time.
  • +
  • Hack web page, add JS scripts, move forward and make a blank space at the top of the web page, and cover the address bar in the blank space.
  • The advantage is that the size of the WebView does not change and is easy to control.
  • The disadvantage is that it is relatively complex and requires handling various web elements and various position situations, which are complex and have low efficiency.
  • The gesture takes over all triggering operations and then distributes them to the controls that need to be scrolled

Methods of this article

resource

SrollView contains the node address bar and WebView control

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
 android:
 xmlns:andro
 xmlns:tools="/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">
 <
  android:
  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:
    android:background="#5ff0"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <EditText
     android:
     android:layout_weight="1"
     android:layout_width="0dp"
     android:layout_height="wrap_content"/>
    <Button
     android:
     android:text="Go"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"/>
   </LinearLayout>
   <
    android:
    android:layout_width="match_parent"
    android:layout_height="100dp" />
  </LinearLayout>
 </>
</RelativeLayout>

ScrollView inherits from ScrollView

onTouchEvent Block MotionEvent.ACTION_MOVE event
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(() == MotionEvent.ACTION_MOVE) {
   return true;
  }
  return (ev);
 }
}

MyWebView inherits from WebView

Block MotionEvent.ACTION_MOVE event in onTouchEvent

onDrawListner

Calculate vertical scroll range

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 (()) {
   case MotionEvent.ACTION_DOWN:
    mMoveCheckedCnt = 0;
    flingScroll(0, 0);
    break;
   case MotionEvent.ACTION_MOVE:
    mMoveCheckedCnt++;
    return false;
   case MotionEvent.ACTION_UP:
    if(mMoveCheckedCnt >= 2) {
     (MotionEvent.ACTION_CANCEL);
     mMoveCheckedCnt = 0;
    }
    break;
  }
  return (event);
 }
 @Override
 protected void onDraw(Canvas canvas) {
  (canvas);
  MyWebViewListener listener = mListener;
  if(listener != null) {
   (this);
  }
 }
 public int getVScrollRange() {
  int v = computeVerticalScrollRange() - computeVerticalScrollExtent();
  if(v < 0) {
   v = 0;
  }
  return v;
 }
}

Main window

GlobalLayoutListener Gets the address bar and scroll view height

GestureDetector Logical Distribution - Decide whether to slide the webview or change the webview height to change the ScrollView scroll range (ScrollView always scrolls to the bottom)

WebView detects the current address bar offset after repainting

public class MainActivity extends AppCompatActivity implements  {
 MyWebView mWebView;
 GestureDetector mGesture = null;
 View mToolBar;
 int mToolBarHeight;
 MyScrollView mScrollView;
 int mScrollViewHeight;
 int mScrollOffset;
 EditText mUrlEdit;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  (savedInstanceState);
  setContentView(.activity_main);
  mWebView = (MyWebView) findViewById();
  (new WebViewClient() {
   @Override
   public boolean shouldOverrideUrlLoading(WebView view, String url) {
    return false;
   }
  });
  (this);
  ("");
  mUrlEdit = (EditText) findViewById();
  findViewById().setOnClickListener(new () {
   @Override
   public void onClick(View v) {
    String url = ().toString();
    if (!("http://") && !("https://")) {
     url = "http://" + url;
    }
    (url);
   }
  });
  mToolBar = findViewById();
  mScrollView = (MyScrollView)findViewById();
  ScrollView scrollView = (ScrollView) mScrollView;
  findViewById().getViewTreeObserver().addOnGlobalLayoutListener(new () {
   @Override
   public void onGlobalLayout() {
    mToolBarHeight = ();
    mScrollViewHeight = ();
    adjustScrollView();
   }
  });
  mGesture = new GestureDetector(this, new GestureListener());
 }
 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
  (ev);
  return (ev);
 }
 @Override
 public void afterDraw(WebView webView) {
  if (() < mScrollOffset) {
   mScrollOffset = ();
   adjustScrollView();
  }
 }
 class GestureListener extends  {
  @Override
  public boolean onDoubleTap(MotionEvent e) {
   ("Temp", "onDoubleTap");
   return (e);
  }
  @Override
  public boolean onDown(MotionEvent e) {
   ("Temp", "onDown");
   return (e);
  }
  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
        float velocityY) {
   ("Temp", "onFling:velocityX = " + velocityX + " velocityY" + velocityY);
   int effectX = (int) velocityX;
   int effectY = (int) velocityY;
   if (effectOnScrollViewByScroll((velocityY < 0 ? 1 : -1) * 8000)) {
    effectY = 0;
   }
   (-effectX, -effectY);
   return (e1, e2, velocityX, velocityY);
  }
  @Override
  public void onLongPress(MotionEvent e) {
   ("Temp", "onLongPress");
   (e);
  }
  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2,
        float distanceX, float distanceY) {
   ("Temp", "onScroll:distanceX = " + distanceX + " distanceY = " + distanceY);
   int effectX = (int) distanceX;
   int effectY = (int) distanceY;
   if (effectOnScrollViewByScroll((int) distanceY)) {
    effectY = 0;
   }
   (effectX, effectY);
   return (e1, e2, distanceX, distanceY);
  }
  @Override
  public boolean onSingleTapUp(MotionEvent e) {
   ("Temp", "onSingleTapUp");
   return (e);
  }
 }
 private boolean effectOnScrollViewByScroll(int distanceY) {
  if (distanceY > 0) {
   // scroll up, the web will scroll down
   if (mScrollOffset >= mToolBarHeight || mScrollOffset >= ()) {
    return false;
   }
   mScrollOffset += distanceY;
   if (mScrollOffset > mToolBarHeight) {
    mScrollOffset = mToolBarHeight;
   }
   if (mScrollOffset > ()) {
    mScrollOffset = ();
   }
  } else {
   if (mScrollOffset <= 0) {
    return false;
   }
   mScrollOffset += distanceY;
   if (mScrollOffset <= 0) {
    mScrollOffset = 0;
   }
  }
  adjustScrollView();
  return true;
 }
 private void adjustScrollView() {
  ("Temp", "offset is " + mScrollOffset);
   layoutParams = ();
  int newHeight = (mScrollViewHeight - mToolBarHeight) + mScrollOffset;
  ("Temp", "newHeight is " + newHeight + ", " + );
  if (newHeight != ) {
    = newHeight;
   (layoutParams);
   new Handler(()).post(new Runnable() {
    @Override
    public void run() {
     (ScrollView.FOCUS_DOWN);
    }
   });
  }
 }
}

Summarize

The above is the effect of Android similar to UC browser introduced to you by the editor: Slide up the address bar to hide the function, I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support for my website!