Android WebView inside ScrollView scrolls only scrollview
Here is the solution. Found online. I have subclassed WebView and i'm using the requestDisallowInterceptTouchEvent(true);
method to allow my webview to handle the scroll event.
TouchyWebView.java
package com.mypackage.common.custom.android.widgets
public class TouchyWebView extends WebView {
public TouchyWebView(Context context) {
super(context);
}
public TouchyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TouchyWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event){
requestDisallowInterceptTouchEvent(true);
return super.onTouchEvent(event);
}
}
And in layout.xml
<com.mypackage.common.custom.android.widgets.TouchyWebView
android:id="@+id/description_web"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Webview in Scrollview
Update 2014-11-13: Since Android KitKat neither of the solutions described below are working -- you will need to look for different approaches like e.g. Manuel Peinado's FadingActionBar which provides a scrolling header for WebViews.
Update 2012-07-08: "Nobu games" kindly created a TitleBarWebView
class bringing the expected behavior back to Android Jelly Bean. When used on older platforms it will use the hidden setEmbeddedTitleBar()
method and when used on Jelly Bean or above it will mimic the same behavior. The source code is available under the Apache 2 license at google code
Update 2012-06-30: It seems as if the setEmbeddedTitleBar()
method has been removed in Android 4.1 aka Jelly Bean :-(
Original answer:
It is possible to place a WebView
into a ScrollView
and it does work. I am using this in GoodNews on Android 1.6 devices. The main drawback is that the user cannot scroll "diagonal" meaning: If the web content exceeds the width of the screen the ScrollView
is responsible for vertical scrolling at the WebView
for horizontal scrolling. As only one of them handles the touch events you can either scroll horizontally or vertically but not diagonal.
Further on there are some annoying problems as described by you (e.g. empty vertical space when loading a content smaller than the previous one). I've found workarounds for all of them in GoodNews, but cannot remember them now, because I've found a much better solution:
If you only put the WebView
into the ScrollView
to place Controls above the web content and you are OK to support only Android 2 and above, then you can use the hidden internal setEmbeddedTitleBar()
method of the WebView
. It has been introduced in API level 5 and (accidentally?) became public for exactly one release (I think it was 3.0).
This method allows you to embed a layout into the WebView
which will be placed above the web content. This layout will scroll out the screen when scrolling vertically but will be kept at the same horizontal position when the web content is scrolled horizontally.
As this method isn't exported by the API you need to use Java reflections to call it. I suggest to derive a new class as followed:
public final class WebViewWithTitle extends ExtendedWebView {
private static final String LOG_TAG = "WebViewWithTitle";
private Method setEmbeddedTitleBarMethod = null;
public WebViewWithTitle(Context context) {
super(context);
init();
}
public WebViewWithTitle(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
try {
setEmbeddedTitleBarMethod = WebView.class.getMethod("setEmbeddedTitleBar", View.class);
} catch (Exception ex) {
Log.e(LOG_TAG, "could not find setEmbeddedTitleBar", ex);
}
}
public void setTitle(View view) {
if (setEmbeddedTitleBarMethod != null) {
try {
setEmbeddedTitleBarMethod.invoke(this, view);
} catch (Exception ex) {
Log.e(LOG_TAG, "failed to call setEmbeddedTitleBar", ex);
}
}
}
public void setTitle(int resId) {
setTitle(inflate(getContext(), resId, null));
}
}
Then in your layout file you can include this using
<com.mycompany.widget.WebViewWithTitle
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
and somewhere else in your code you can call the setTitle()
method with the ID of the layout to be embedded into the WebView
.
WKWebView inside Scroll View
If you mean to get the content height of the html in WKWebView
to make it non-scrollable inside UIScrollView
, then read on.
You need to observe (via delegate) the content height of your webView. I'm giving you these steps, since you quite know what you're doing, and you're almost there.
Make an outlet out of your webView height constraint
@IBOutlet weak var constraint_WebViewHeight: NSLayoutConstraint!
Subscribe to webView's delegate
This will let you know (your controller when your webView has finished loading the contents of your site.
self.webView.navigationDelegate = self
Conform to protocol
Inside the didFinish navigation
method of WKNavigationDelegate
, you then adjust the constant of your webView height constraint. Put some animation if you want to :)
extension ViewController: WKNavigationDelegate {
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.constraint_WebViewHeight.constant = webView.scrollView.contentSize.height
}
}
}
Finally, fix your constraints.
a. Remove your imageView bottom constraint.
b. Add bottom constraint to your save button to the scrollView.
This will make your scrollView scrollable.
Voila! This yields this result.
I hope this helps!
Related Topics
How to Set My Sms App Default in Android Kitkat
How to Close All the Activities of My Application
How to Make Proguard Ignore External Libraries
Firebaseinitprovider: Firebaseapp Initialization Unsuccessful
Using Tesseract for Handwriting Recognition
Scrolling with Multiple Listviews for Android
Mkdir() Works While Inside Internal Flash Storage, But Not Sd Card
Eclipse Android Project, How to Reference Library Within Workspace
Broadcast Receiver Class and Registerreceiver Method
Admob Getting an Ad Response. Errorcode: 0 Failed to Load Ad:0
Android M Weird Shared Preferences Issue
How to Change Font Size in Preferencescreen
How to Block Virtual Keyboard While Clicking on Edittext in Android
Save Sensitive Data in React Native