Webview in Scrollview

后端 未结 6 874
南旧
南旧 2020-11-29 02:40

I have to place WebView into ScrollView. But I have to put some views into the same scrollview before webview. So it looks like this:



        
6条回答
  •  挽巷
    挽巷 (楼主)
    2020-11-29 03:33

    Here is implementation of WebView containing another "Title bar" view at top of it.

    How it looks:

    Red bar + 3 buttons is a "Title bar", below is web view, all is scrolled and clipped together in one rectangle.

    It's clean, short, works all way from API 8 to 16 and up (with small effort it can work also on API<8). It doesn't use any hidden functions such as WebView.setEmbeddedTitleBar.

    public class TitleWebView extends WebView{
    
       public TitleWebView(Context context, AttributeSet attrs){
          super(context, attrs);
       }
    
       private int titleHeight;
    
       @Override
       protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
          super.onMeasure(widthMeasureSpec, heightMeasureSpec);
          // determine height of title bar
          View title = getChildAt(0);
          titleHeight = title==null ? 0 : title.getMeasuredHeight();
       }
    
       @Override
       public boolean onInterceptTouchEvent(MotionEvent ev){
          return true;   // don't pass our touch events to children (title bar), we send these in dispatchTouchEvent
       }
    
       private boolean touchInTitleBar;
       @Override
       public boolean dispatchTouchEvent(MotionEvent me){
    
          boolean wasInTitle = false;
          switch(me.getActionMasked()){
          case MotionEvent.ACTION_DOWN:
             touchInTitleBar = (me.getY() <= visibleTitleHeight());
             break;
    
          case MotionEvent.ACTION_UP:
          case MotionEvent.ACTION_CANCEL:
             wasInTitle = touchInTitleBar;
             touchInTitleBar = false;
             break;
          }
          if(touchInTitleBar || wasInTitle) {
             View title = getChildAt(0);
             if(title!=null) {
                // this touch belongs to title bar, dispatch it here
                me.offsetLocation(0, getScrollY());
                return title.dispatchTouchEvent(me);
             }
          }
          // this is our touch, offset and process
          me.offsetLocation(0, -titleHeight);
          return super.dispatchTouchEvent(me);
       }
    
       /**
        * @return visible height of title (may return negative values)
        */
       private int visibleTitleHeight(){
          return titleHeight-getScrollY();
       }       
    
       @Override
       protected void onScrollChanged(int l, int t, int oldl, int oldt){
          super.onScrollChanged(l, t, oldl, oldt);
          View title = getChildAt(0);
          if(title!=null)   // undo horizontal scroll, so that title scrolls only vertically
             title.offsetLeftAndRight(l - title.getLeft());
       }
    
       @Override
       protected void onDraw(Canvas c){
    
          c.save();
          int tH = visibleTitleHeight();
          if(tH>0) {
             // clip so that it doesn't clear background under title bar
             int sx = getScrollX(), sy = getScrollY();
             c.clipRect(sx, sy+tH, sx+getWidth(), sy+getHeight());
          }
          c.translate(0, titleHeight);
          super.onDraw(c);
          c.restore();
       }
    }
    

    Usage: put your title bar view hierarchy inside of element in layout xml. WebView inherits ViewGroup, so it can contain children, despite of ADT plugin complaining that it can't. Example:

    
    
       
    
          

    Note usage of layerType="software", WebView in hardware on API 11+ isn't properly animated and drawn when it has hw layer.

    Scrolling works perfectly, as well as clicks on title bar, clicks on web, selecting text in web, etc.

提交回复
热议问题