Search code examples
javaandroidandroid-layoutandroid-webviewandroid-scrollview

How to stack WebViews on top and load url into it without pushing views down


in our app, I'm loading an initial webview. Then in order to allow users to see chat history, I want to add new webviews on top on that initial one. The way I do that now is to have a linear layout wrapping the initial webview; this LinearLayout is called webview_wrapper and is in a ScrollView. Then, using a ScrollViewListener interface, when the user scrolls up past a set coordinate I create a new webview, call it newWebView, and call webview_wrapper.addView(newWebView, 0), the problem I'm having is that I want to do the loading and adding of the webview off the screen, then the user can continue to scroll up. This adding and scrolling happens inside of an onAnimationEnd method of an AnimationListener(while I make the post request for webview).

I feel like I've tried every way like calling scrollTo or scrollBy after adding the view but it's only scrolling partially. What is the best way to do this?


Solution

  • This problem was eventually solved by using a OnGlobalLayoutListener on the containing ScrollView, inside of which I call scrollTo(0, webViewHeight) and removeOnGlobalLayoutListener(this). Right before that, I make the WebView visible, set its height via setLayoutParams(view must be visible first).

    Please correct me if I'm wrong but this probably works as seamlessly as it does because of the OnGlobalLayoutListener. When the view is made visible and the height set, and right after we set an OnGlobalLayoutListener which fires the scrollTo() to the exact height of the new view when the scrollView is being laid out, the net result becomes the appearance of the view inflating off screen.

        final int newHeight    = (int) ((height / 380.0) * webView.getWidth());
    
        // Must set visible before setting layout params
        currentOldView.setVisibility(View.VISIBLE);
    
        // Without this line, view will bounce around as it attempts to self set the height based on HTML content
        currentOldView.setLayoutParams(new LinearLayout.LayoutParams(webView.getWidth(), newHeight));
    
        // Use viewTreeObserver to wait until scrollView completely laid out before attempting to scroll
        ViewTreeObserver observer = scrollView.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                scrollView.scrollTo(0, newHeight);  // Because spinner_wrapper still on view, will scroll to an overlap point.
                canAddOldChat = true;
                currentOldView.startAnimation(fadeInAnim);
    
                if (isLastOldChat) spinner_wrapper.setAlpha(0.0f);
    
                scrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
        });