无法在WebView中滚动图像

时间:2019-07-19 11:51:03

标签: android webview

我为Android和iOS开发了一个Webview应用。我注意到我无法在android应用中的特定html元素上滚动,尽管它可以在iOS上运行。

这是website

这是我正在谈论的示例图像,基本上是网站上的任何产品图像,但仅在产品详细信息页面上,您可以在其中购买产品并将其放入购物车...

enter image description here

HTML

package de.blizz_z.onlineshop;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Bitmap;
import android.webkit.URLUtil;
import android.net.Uri;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Build;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.WebChromeClient;
import android.widget.Button;
import android.util.Log;
import android.webkit.HttpAuthHandler;
import android.webkit.ValueCallback;

/**
 * An example full-screen activity that shows and hides the system UI (i.e.
 * status bar and navigation/system bar) with user interaction.
 */
public class FullscreenActivity extends AppCompatActivity
{
    private WebView blizzView;
    private Button backButton;
    private String website;

    /**
     * Whether or not the system UI should be auto-hidden after
     * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
     */
    private static final boolean AUTO_HIDE = true;

    /**
     * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
     * user interaction before hiding the system UI.
     */
    private static final int AUTO_HIDE_DELAY_MILLIS = 3000;

    /**
     * Some older devices needs a small delay between UI widget updates
     * and a change of the status and navigation bar.
     */
    private static final int UI_ANIMATION_DELAY = 300;
    private final Handler mHideHandler = new Handler();
    private final Runnable mHidePart2Runnable = new Runnable()
    {
        @SuppressLint("InlinedApi")
        @Override
        public void run() {

        }
    };

    private final Runnable mShowPart2Runnable = new Runnable()
    {
        @Override
        public void run() {
            // Delayed display of UI elements
            ActionBar actionBar = getSupportActionBar();
            if (actionBar != null) {
                actionBar.show();
            }
        }
    };
    private boolean mVisible;
    private final Runnable mHideRunnable = new Runnable() {
        @Override
        public void run() {
            hide();
        }
    };

    /**
     * Touch listener to use for in-layout UI controls to delay hiding the
     * system UI. This is to prevent the jarring behavior of controls going away
     * while interacting with activity UI.
     */
    private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener()
    {
        @Override
        public boolean onTouch(View view, MotionEvent event)
        {

            Log.i("debug_log", "touch");

            if (AUTO_HIDE) {
                delayedHide(AUTO_HIDE_DELAY_MILLIS);
            }

            int x = (int) event.getX();
            int y = (int) event.getY();

            Log.i("debug_log", "moving: (" + x + ", " + y + ")");

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    Log.i("debug_log", "touched down");
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.i("debug_log", "moving: (" + x + ", " + y + ")");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.i("debug_log", "touched up");
                    break;
            }

            return true;
        }

    };

    @SuppressLint("ClickableViewAccessibility")
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fullscreen);

        mVisible = true;
        website = "https://www.blizz-z.de";
        blizzView = findViewById(R.id.blizzView);

        WebSettings settings = blizzView.getSettings();
        settings.setJavaScriptEnabled(true);

        // https://developer.android.com/reference/android/webkit/WebViewClient
        blizzView.setWebViewClient(new WebViewClient() {

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                super.onReceivedHttpError(view, request, errorResponse);

                Log.i("debug_log", errorResponse.getReasonPhrase());
            }

            @Override
            public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
            {
                super.onReceivedHttpAuthRequest(view, handler, host, realm);

                view.setHttpAuthUsernamePassword(host, realm, "macs", "20macs14");
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon)
            {
                // check here the url
                if (url.endsWith(".pdf")) {
                    Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    startActivity(browserIntent);
                } else {
                    super.onPageStarted(view, url, favicon);
                }
            }

            @Override
            // Notify the host application that a page has finished loading.
            public void onPageFinished(WebView view, String url)
            {
                super.onPageFinished(view, url);

                 // Hide/Show back button
                backButton = findViewById(R.id.backButton);
                backButton.setEnabled(blizzView.canGoBack());

                if (blizzView.canGoBack()) {
                    backButton.setVisibility(View.VISIBLE);
                } else {
                    backButton.setVisibility(View.INVISIBLE);
                }

                js(blizzView, "jQuery(document).ready(function() {"

                                        + "setInterval(function() {"
                                            + "jQuery('#myInput').css('background', '#'+(Math.random()*0xFFFFFF<<0).toString(16));"

                                            + "jQuery('a').each(function() {"
                                                + "jQuery(this).removeAttr('download');"
                                            + "});"
                                        + "}, 1000);"
                                    + "});");

            }

            // Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url)
            {
                Log.i("debug_log", "shouldOverrideUrlLoading");

                //view.loadDataWithBaseURL("https://www.blizz-z.de", );

            // Allow download of .pdf files
                if (url.endsWith(".pdf")) {
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
                    // if want to download pdf manually create AsyncTask here
                    // and download file
                    return true;
                }

            // Also allow urls not starting with http or https (e.g. tel, mailto, ...)
                if( URLUtil.isNetworkUrl(url) ) {
                    return false;
                } else {
                    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
                }

                return true;
            }

        });

        blizzView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                int x = (int) event.getX();
                int y = (int) event.getY();

                //WebView.HitTestResult hr = blizzView.getHitTestResult();
                //Log.i("debug_log", "getExtra = "+ hr.getExtra() + " Type= " + hr.getType());

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.i("debug_log", "touched down");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.i("debug_log", "moving: (" + x + ", " + y + ")");
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.i("debug_log", "touched up");
                        break;
                }

                return false;
            }

        });

        // URL laden:
        blizzView.loadUrl(website);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState)
    {
        Log.i("debug_log", "onPostCreate");
        super.onPostCreate(savedInstanceState);

        // Trigger the initial hide() shortly after the activity has been
        // created, to briefly hint to the user that UI controls
        // are available.
        delayedHide(100);
    }

    private void toggle()
    {
        if (mVisible) {
            hide();
        } else {
            show();
        }
    }

    private void hide()
    {
        // Hide UI first
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.hide();
        }
        mVisible = false;

        // Schedule a runnable to remove the status and navigation bar after a delay
        mHideHandler.removeCallbacks(mShowPart2Runnable);
        mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
    }

    @SuppressLint("InlinedApi")

    private void show()
    {
        // Show the system bar
        mVisible = true;

        // Schedule a runnable to display UI elements after a delay
        mHideHandler.removeCallbacks(mHidePart2Runnable);
        mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
    }

    /**
     * Schedules a call to hide() in delay milliseconds, canceling any
     * previously scheduled calls.
     */
    private void delayedHide(int delayMillis)
    {
        mHideHandler.removeCallbacks(mHideRunnable);
        mHideHandler.postDelayed(mHideRunnable, delayMillis);
    }

    public void js(WebView view, String code)
    {
        String javascriptCode = "javascript:" + code;
        if (Build.VERSION.SDK_INT >= 19) {
            view.evaluateJavascript(javascriptCode, new ValueCallback<String>() {

                @Override
                public void onReceiveValue(String response) {
                    Log.i("debug_log", response);
                }
            });
        } else {
            view.loadUrl(javascriptCode);
        }
    }

    // Event Listener ------------------------------------------------------------------------------

            public void goBack(android.view.View view)
            {
                blizzView.goBack();
            }

        // If back button of smartphone is pressed, then go back in browser history
            @Override
            public boolean onKeyDown(int keyCode, KeyEvent event)
            {
                Log.i("debug_log", "KeyDown");
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    switch (keyCode) {
                        case KeyEvent.KEYCODE_BACK:
                            if (blizzView.canGoBack())
                                blizzView.goBack();
                            else
                                finish();
                            return true;
                    }
                }

                return super.onKeyDown(keyCode, event);
            }

}

如果我通过智能手机的chrome浏览器访问该网站,那么它可以正常工作,那么它一定是webview中的错误吗?

enter image description here

图像是一个滑块,我可以左右滑动,但是如果在图像上滚动,则无法向下滚动页面。

FullscreenActivity.java:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/relativeLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="visible"
    tools:context="de.blizz_z.onlineshop.FullscreenActivity">

    <WebView
        android:id="@+id/blizzView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:keepScreenOn="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </WebView>

    <Button
        android:id="@+id/backButton"
        android:layout_width="90dp"
        android:layout_height="39dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginBottom="16dp"
        android:background="#F5EA01"
        android:enabled="false"
        android:onClick="goBack"
        android:text="Zurück"
        android:visibility="invisible"
        app:layout_constraintBottom_toBottomOf="@+id/blizzView"
        app:layout_constraintStart_toStartOf="@+id/blizzView" />

</android.support.constraint.ConstraintLayout>

activity_fullscreen.xml

df = pd.DataFrame({'reviews':['He writer in me great great me',
                        'great ambience the coffee was great',
                        'great coffee'],
                   'year':[2002,2004,2004]})
print (df)

                               reviews  year
0       He writer in me great great me  2002
1  great ambience the coffee was great  2004
2                         great coffee  2004

#change for 100 for top100 in real data
N = 3
df1 =  (df.set_index('year')['reviews']
          .str.lower()
          .str.split(expand=True)
          .stack()
          .groupby(level=0)
          .value_counts()
          .groupby(level=0)
          .head(N)
          .rename_axis(('year','words'))
          .reset_index(name='count'))

print (df1)
   year     words  count
0  2002     great      2
1  2002        me      2
2  2002        he      1
3  2004     great      3
4  2004    coffee      2
5  2004  ambience      1

4 个答案:

答案 0 :(得分:1)

您有两个选择

选项一

通过在Webview上为“触摸事件”创建自定义侦听器。 我已经修改了post上@fernandohur的答案中的代码段,以匹配您的情况。

创建一个新类(OnSwipeListener.java)

import android.view.GestureDetector;
import android.view.MotionEvent;

public class OnSwipeListener extends GestureDetector.SimpleOnGestureListener {

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

    // Grab two events located on the plane at e1=(x1, y1) and e2=(x2, y2)
    // Let e1 be the initial event
    // e2 can be located at 4 different positions, consider the following diagram
    // (Assume that lines are separated by 90 degrees.)
    //
    //
    //         \ A  /
    //          \  /
    //       D   e1   B
    //          /  \
    //         / C  \
    //
    // So if (x2,y2) falls in region:
    //  A => it's an UP swipe
    //  B => it's a RIGHT swipe
    //  C => it's a DOWN swipe
    //  D => it's a LEFT swipe
    //

    float x1 = e1.getX();
    float y1 = e1.getY();

    float x2 = e2.getX();
    float y2 = e2.getY();

    Direction direction = getDirection(x1,y1,x2,y2);
    return onSwipe(direction, velocityX, velocityY);
}

/** Override this method. The Direction enum will tell you how the user swiped. */
public boolean onSwipe(Direction direction, float velocityX, float velocityY){
    return false;
}

/**
 * Given two points in the plane p1=(x1, x2) and p2=(y1, y1), this method
 * returns the direction that an arrow pointing from p1 to p2 would have.
 * @param x1 the x position of the first point
 * @param y1 the y position of the first point
 * @param x2 the x position of the second point
 * @param y2 the y position of the second point
 * @return the direction
 */
public Direction getDirection(float x1, float y1, float x2, float y2){
    double angle = getAngle(x1, y1, x2, y2);
    return Direction.fromAngle(angle);
}

/**
 *
 * Finds the angle between two points in the plane (x1,y1) and (x2, y2)
 * The angle is measured with 0/360 being the X-axis to the right, angles
 * increase counter clockwise.
 *
 * @param x1 the x position of the first point
 * @param y1 the y position of the first point
 * @param x2 the x position of the second point
 * @param y2 the y position of the second point
 * @return the angle between two points
 */
public double getAngle(float x1, float y1, float x2, float y2) {

    double rad = Math.atan2(y1-y2,x2-x1) + Math.PI;
    return (rad*180/Math.PI + 180)%360;
}


public enum Direction{
    up,
    down,
    left,
    right;

    /**
     * Returns a direction given an angle.
     * Directions are defined as follows:
     *
     * Up: [45, 135]
     * Right: [0,45] and [315, 360]
     * Down: [225, 315]
     * Left: [135, 225]
     *
     * @param angle an angle from 0 to 360 - e
     * @return the direction of an angle
     */
    public static Direction fromAngle(double angle){
        if(inRange(angle, 45, 135)){
            return Direction.up;
        }
        else if(inRange(angle, 0,45) || inRange(angle, 315, 360)){
            return Direction.right;
        }
        else if(inRange(angle, 225, 315)){
            return Direction.down;
        }
        else{
            return Direction.left;
        }

    }

    /**
     * @param angle an angle
     * @param init the initial bound
     * @param end the final bound
     * @return returns true if the given angle is in the interval [init, end).
     */
    private static boolean inRange(double angle, float init, float end){
        return (angle >= init) && (angle < end);
    }
}
}

然后在您的活动中使用...

public class FullscreenActivity extends AppCompatActivity implements View.OnTouchListener {

private WebView blizzView;
private Button backButton;
private String website;
private GestureDetector gestureDetector;

/**
 * Whether or not the system UI should be auto-hidden after
 * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
 */
private static final boolean AUTO_HIDE = true;

/**
 * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after
 * user interaction before hiding the system UI.
 */
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;

/**
 * Some older devices needs a small delay between UI widget updates
 * and a change of the status and navigation bar.
 */
private static final int UI_ANIMATION_DELAY = 300;
private final Handler mHideHandler = new Handler();
private final Runnable mHidePart2Runnable = new Runnable()
{
    @SuppressLint("InlinedApi")
    @Override
    public void run() {

    }
};

private final Runnable mShowPart2Runnable = new Runnable()
{
    @Override
    public void run() {
        // Delayed display of UI elements
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.show();
        }
    }
};
private boolean mVisible;
private final Runnable mHideRunnable = new Runnable() {
    @Override
    public void run() {
        hide();
    }
};

@Override
public boolean onTouch(View v, MotionEvent event) {
    Log.d("SWIPER", "onTouch: ");
    gestureDetector.onTouchEvent(event);
    return false;
}
public void scrollUpwards(int scroll_speed) {
    try{
        ObjectAnimator anim = ObjectAnimator.ofInt(blizzView, "scrollY", blizzView.getScrollY(), blizzView.getScrollY() - scroll_speed);
        anim.setDuration(800).start();
    }catch (Exception ex){}
}
public void scrollDownwards(int scroll_speed) {
    try{
       // float maxScrollY = blizzView.getContentHeight() * blizzView.getScale() - blizzView.getMeasuredHeight();
       if(blizzView.getScrollY() <= 100){
           //due to the scroll animation the web page slows down at the top
           //hence we add some extra speed when user is at the top of page to prevent from
           //experiencing delay when scrolling back down
           scroll_speed += 1300;
       }
        ObjectAnimator anim = ObjectAnimator.ofInt(blizzView, "scrollY", blizzView.getScrollY(), blizzView.getScrollY() + scroll_speed);
        anim.setDuration(800).start();
    }catch (Exception ex){}
}
@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    gestureDetector=new GestureDetector(this,new OnSwipeListener(){

        @Override
        public boolean onSwipe(Direction direction, float velocityX, float velocityY) {
          //  int scroll_jump_percentage = 60 / 100; //percent of velocity: increase(60) for faster scroll jump
            int scroll_speed =  ((int) Math.abs(velocityY)) * 60 / 100; //percent of velocity: increase(60) for faster scroll jump;
            if (direction==Direction.up){
                //do your stuff
             //   Log.d("SWIPER", "onSwipe: up");
                scrollDownwards(scroll_speed);
                Toast.makeText(getApplicationContext(),"You swiped UP ("+scroll_speed+")",Toast.LENGTH_SHORT).show();

                //we made it!
                return true;
            }
            else if (direction==Direction.down){
                //do your stuff
              //  Log.d("SWIPER", "onSwipe: down");
                scrollUpwards(scroll_speed);
                Toast.makeText(getApplicationContext(),"You swiped DOWN ("+scroll_speed+")",Toast.LENGTH_SHORT).show();

                //we made it!
                return true;
            }

            //nothing to handle here... Mr. WebView can do the rest
            return false;
        }
    });
    mVisible = true;
    website = "https://www.blizz-z.de";
    blizzView = findViewById(R.id.blizzView);
    blizzView.setOnTouchListener(this);
    WebSettings settings = blizzView.getSettings();
    settings.setJavaScriptEnabled(true);
    settings.setBuiltInZoomControls(false);

    // https://developer.android.com/reference/android/webkit/WebViewClient
    blizzView.setWebViewClient(new WebViewClient() {

        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            super.onReceivedHttpError(view, request, errorResponse);

           // Log.i("debug_log", errorResponse.getReasonPhrase());
        }

        @Override
        public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
        {
            super.onReceivedHttpAuthRequest(view, handler, host, realm);

            view.setHttpAuthUsernamePassword(host, realm, "macs", "20macs14");
        }

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon)
        {
            // check here the url
            if (url.endsWith(".pdf")) {
                Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                startActivity(browserIntent);
            } else {
                super.onPageStarted(view, url, favicon);
            }
        }

        @Override
        // Notify the host application that a page has finished loading.
        public void onPageFinished(WebView view, String url)
        {
            super.onPageFinished(view, url);

            // Hide/Show back button
            backButton = findViewById(R.id.backButton);
            backButton.setEnabled(blizzView.canGoBack());

            if (blizzView.canGoBack()) {
                backButton.setVisibility(View.VISIBLE);
            } else {
                backButton.setVisibility(View.INVISIBLE);
            }

            js(blizzView, "jQuery(document).ready(function() {"

                    + "setInterval(function() {"
                    + "jQuery('#myInput').css('background', '#'+(Math.random()*0xFFFFFF<<0).toString(16));"

                    + "jQuery('a').each(function() {"
                    + "jQuery(this).removeAttr('download');"
                    + "});"
                    + "}, 1000);"
                    + "});");

            //inject script (this script would remove all event listener from product image
            // that was placed by your MagicZoom Js Library
            //TEMP FIX
           /* blizzView.loadUrl(
                    "javascript:(function() { " +
                            "var slides = document.getElementsByClassName(\"MagicZoom\");\n" +
                            "for(var i = 0; i < slides.length; i++)\n" +
                            "{\n" +
                            "var old_element = slides.item(i);\n" +
                            "old_element.href = '#';\n" +
                            "                var new_element = old_element.cloneNode(true);\n" +
                            "\t\t\t\told_element.parentNode.replaceChild(new_element, old_element);\n" +
                            "       \n" +
                            "   }" +
                            "})()");*/

        }

        // Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            Log.i("debug_log", "shouldOverrideUrlLoading");

            //view.loadDataWithBaseURL("https://www.blizz-z.de", );

            // Allow download of .pdf files
            if (url.endsWith(".pdf")) {
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
                // if want to download pdf manually create AsyncTask here
                // and download file
                return true;
            }

            // Also allow urls not starting with http or https (e.g. tel, mailto, ...)
            if( URLUtil.isNetworkUrl(url) ) {
                return false;
            } else {
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
            }

            return true;
        }

    });
    // URL laden:
    blizzView.loadUrl(website);
}

@Override
protected void onPostCreate(Bundle savedInstanceState)
{
    Log.i("debug_log", "onPostCreate");
    super.onPostCreate(savedInstanceState);

    // Trigger the initial hide() shortly after the activity has been
    // created, to briefly hint to the user that UI controls
    // are available.
    delayedHide(100);
}

private void toggle()
{
    if (mVisible) {
        hide();
    } else {
        show();
    }
}

private void hide()
{
    // Hide UI first
    ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.hide();
    }
    mVisible = false;

    // Schedule a runnable to remove the status and navigation bar after a delay
    mHideHandler.removeCallbacks(mShowPart2Runnable);
    mHideHandler.postDelayed(mHidePart2Runnable, UI_ANIMATION_DELAY);
}

@SuppressLint("InlinedApi")

private void show()
{
    // Show the system bar
    mVisible = true;

    // Schedule a runnable to display UI elements after a delay
    mHideHandler.removeCallbacks(mHidePart2Runnable);
    mHideHandler.postDelayed(mShowPart2Runnable, UI_ANIMATION_DELAY);
}

/**
 * Schedules a call to hide() in delay milliseconds, canceling any
 * previously scheduled calls.
 */
private void delayedHide(int delayMillis)
{
    mHideHandler.removeCallbacks(mHideRunnable);
    mHideHandler.postDelayed(mHideRunnable, delayMillis);
}

public void js(WebView view, String code)
{
    String javascriptCode = "javascript:" + code;
    if (Build.VERSION.SDK_INT >= 19) {
        view.evaluateJavascript(javascriptCode, new ValueCallback<String>() {

            @Override
            public void onReceiveValue(String response) {
                Log.i("debug_log", response);
            }
        });
    } else {
        view.loadUrl(javascriptCode);
    }
}

// Event Listener ------------------------------------------------------------------------------

public void goBack(android.view.View view)
{
    blizzView.goBack();
}

// If back button of smartphone is pressed, then go back in browser history
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
    Log.i("debug_log", "KeyDown");
    if (event.getAction() == KeyEvent.ACTION_DOWN) {
        switch (keyCode) {
            case KeyEvent.KEYCODE_BACK:
                if (blizzView.canGoBack())
                    blizzView.goBack();
                else
                    finish();
                return true;
        }
    }

    return super.onKeyDown(keyCode, event);
}

}

选项二

将以下代码段添加到WebviewClient的 onPageFinished 方法中

//This will remove all javascript event listener from affected images. (offending script: MagicZoomPlus.js)
//Setback of this is that images would no longer zoom in when clicked. 

            blizzView.loadUrl(
                    "javascript:(function() { " +
                            "var slides = document.getElementsByClassName(\"MagicZoom\");\n" +
                            "for(var i = 0; i < slides.length; i++)\n" +
                            "{\n" +
                            "var old_element = slides.item(i);\n" +
                            "old_element.href = '#';\n" +
                            "                var new_element = old_element.cloneNode(true);\n" +
                            "\t\t\t\told_element.parentNode.replaceChild(new_element, old_element);\n" +
                            "       \n" +
                            "   }" +
                            "})()");

答案 1 :(得分:0)

您是否尝试过将其设置为webView?

 webview.setVerticalScrollBarEnabled(true);
 webview.setHorizontalScrollBarEnabled(true);

答案 2 :(得分:0)

首先删除整个部分,

@Override
        public void onPageFinished(WebView view, String url)
        {
            super.onPageFinished(view, url);

            //blizzView.Settings.setSupportZoom(true);

            blizzView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);

            blizzView.getSettings().setSupportZoom(true);
            blizzView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);

            blizzView.loadUrl(
                    "javascript:(function() {"


                            //+ "jQuery('.logo').remove();" //Einige Funktionen wie z.B. alert() sind scheinbar aus Sicherheits-/Missbrauchsgründen nicht verfügbar; jQuery kann man natürlich nur nutzen wenn es eingebunden ist. Möglicherweise kann man es auch selbst einbinden.
                    + "})()"
            );

            // Hide/Show back button
            backButton = findViewById(R.id.backButton);
            backButton.setEnabled(blizzView.canGoBack());

            if (blizzView.canGoBack()) {
                backButton.setVisibility(View.VISIBLE);
            } else {
                backButton.setVisibility(View.INVISIBLE);
            }

            blizzView.setVerticalScrollBarEnabled(true);
            blizzView.setHorizontalScrollBarEnabled(true);

        }

因为您不能依靠onPageFinished,而是应该实现shouldOverrideUrlLoading。我将在此处发布完整的代码。

public class TempWebActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_temp_web);

    WebView webView = findViewById(R.id.wv_scroller);
    webView.getSettings().setJavaScriptEnabled(true);

    webView.loadUrl("https://www.blizz-z.de");

    webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    });
    }
}

这是活动布局

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TempWebActivity">

<WebView 
android:id="@+id/wv_scroller"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</ScrollView>

实现此目的的关键是,如果某些ScrollView可以拦截某些触摸事件,则将WebView包装器与Javascript一起使用。 另外,请确保将WebView的高度保持为wrap_content。 祝您编码愉快! :)

答案 3 :(得分:-1)

尝试在此示例中添加Webview。

  <NestedScrollViewHome
            android:id="@+id/scroll_nested_journey"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/toolbar">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:descendantFocusability="blocksDescendants"
                android:orientation="vertical">

    //  add Webview here

     </LinearLayout>

        </NestedScrollViewHome>

NestedScrollViewHome.java

public class NestedScrollViewHome  extends NestedScrollView {
    @SuppressWarnings("unused")
    private int slop;
    @SuppressWarnings("unused")
    private float mInitialMotionX;
    @SuppressWarnings("unused")
    private float mInitialMotionY;
    public NestedScrollViewHome(Context context) {
        super(context);
        init(context);
    }

    private boolean enableScrolling = true;

    public boolean isEnableScrolling() {
        return enableScrolling;
    }

    public void setEnableScrolling(boolean enableScrolling) {
        this.enableScrolling = enableScrolling;
    }


    private void init(Context context) {
        ViewConfiguration config = ViewConfiguration.get(context);
        slop = config.getScaledEdgeSlop();
    }
    public NestedScrollViewHome(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
    public NestedScrollViewHome(Context context, AttributeSet attrs,
                              int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
    private float xDistance, yDistance, lastX, lastY;
    @SuppressWarnings("unused")
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
      if (isEnableScrolling())
      {
          final float x = ev.getX();
          final float y = ev.getY();
          switch (ev.getAction()) {
              case MotionEvent.ACTION_DOWN:
                  xDistance = yDistance = 0f;
                  lastX = ev.getX();
                  lastY = ev.getY();
                  // This is very important line that fixes
                  computeScroll();
                  break;
              case MotionEvent.ACTION_MOVE:
                  final float curX = ev.getX();
                  final float curY = ev.getY();
                  xDistance += Math.abs(curX - lastX);
                  yDistance += Math.abs(curY - lastY);
                  lastX = curX;
                  lastY = curY;
                  if (xDistance > yDistance) {
                      return false;
                  }
          }
          return super.onInterceptTouchEvent(ev);
      }else
          return false;
    }
    public interface OnScrollChangedListener {
        void onScrollChanged(NestedScrollView who, int l, int t, int oldl,
                             int oldt);
    }
    private OnScrollChangedListener mOnScrollChangedListener;
    public void setOnScrollChangedListener(OnScrollChangedListener listener) {
        mOnScrollChangedListener = listener;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isEnableScrolling()) {
            return super.onTouchEvent(ev);
        } else {
            return false;
        }
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);
        if (mOnScrollChangedListener != null) {
            mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);
        }
    }
}