如何在 Android 中为 WebView 制作滚动监听器

Posted

技术标签:

【中文标题】如何在 Android 中为 WebView 制作滚动监听器【英文标题】:How to make a Scroll Listener for WebView in Android 【发布时间】:2013-01-23 00:51:15 【问题描述】:

如何在android中实现WebView的滚动监听器

我试过这个,但它没有在滚动 web 视图时调用我的Log.i

package com.example.webview.full.width;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.webkit.WebView;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;

public class scorllableWebview extends WebView implements OnScrollListener 


Context ctx;
AttributeSet atrs;

public scorllableWebview(Context context) 
    super(context);

    ctx = context;


public scorllableWebview(Context context, AttributeSet atters)
    super(context, atters);

    ctx = context;
    atrs = atters;


@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) 

    Log.i("onScroll", "Called");


@Override
public void onScrollStateChanged(AbsListView view, int scrollState) 


    Log.i("onScrollStateChanged", "Called");



这是我的MainActivity.java

package com.example.webview.full.width;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.view.Menu;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class MainActivity extends Activity 

ProgressDialog progressDialog;
scorllableWebview wv;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    wv = (scorllableWebview) findViewById(R.id.scorllableWebview);

    wv.getSettings().setjavascriptEnabled(true);

    wv.getSettings().setBuiltInZoomControls(true);
    wv.getSettings().supportZoom();

    progressDialog = ProgressDialog.show(MainActivity.this,
            "Loading Book...!", "Please Wait");
    progressDialog.setCancelable(true);

    String htnlString = "<!DOCTYPE html><html><body style = \"text-align:center\"><script type=\"text/javascript\">for(a=1;a<=10;a++)document.write('<img style=\"border-style:dotted;border-width:10px;border-color:black;\"src=\"http://myURL.com/books_snaps/EN567/'+a+'.jpg\" alt=\"Page Not Found\"/>');</script></body></html>";
    // width=\"100%\"
    wv.setWebViewClient(new WebViewClient() 

        @Override
        public void onPageFinished(WebView view, String url) 
            progressDialog.dismiss();
            Toast.makeText(MainActivity.this, "Completed",
                    Toast.LENGTH_SHORT).show();
            wv.pageUp(true);
            super.onPageFinished(view, url);
        

    );

    wv.loadDataWithBaseURL(null, htnlString, "text/html", "UTF-8", null);


   

这是我的 XML 文件。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_ >

<com.example.webview.full.width.scorllableWebview
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/scorllableWebview"
    android:layout_
    android:layout_ />

</RelativeLayout>

【问题讨论】:

检查这个***.com/questions/6253444/android-webview-scrollable和***.com/questions/10552702/… 感谢您的评论,但对我不起作用 那你想要什么? 它在滚动 web 视图时没有调用我的 onScroll 方法。请看看我的 scorllableWebview.java 类 【参考方案1】:

类似:

public class ObservableWebView extends WebView

    private OnScrollChangedCallback mOnScrollChangedCallback;

    public ObservableWebView(final Context context)
    
        super(context);
    

    public ObservableWebView(final Context context, final AttributeSet attrs)
    
        super(context, attrs);
    

    public ObservableWebView(final Context context, final AttributeSet attrs, final int defStyle)
    
        super(context, attrs, defStyle);
    

    @Override
    protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt)
    
        super.onScrollChanged(l, t, oldl, oldt);
        if(mOnScrollChangedCallback != null) mOnScrollChangedCallback.onScroll(l, t, oldl, oldt);
    

    public OnScrollChangedCallback getOnScrollChangedCallback()
    
        return mOnScrollChangedCallback;
    

    public void setOnScrollChangedCallback(final OnScrollChangedCallback onScrollChangedCallback)
    
        mOnScrollChangedCallback = onScrollChangedCallback;
    

    /**
     * Impliment in the activity/fragment/view that you want to listen to the webview
     */
    public static interface OnScrollChangedCallback
    
        public void onScroll(int l, int t, int oldl, int oldt);
    

应该可以,这是未经测试的,但这适用于 Android 中的几乎所有其他视图。

你会像这样实现:

wv = (ObservableWebView) findViewById(R.id.scorllableWebview);
wv.setOnScrollChangedCallback(new OnScrollChangedCallback()
    public void onScroll(int l, int t, int oldl, int oldt)
        if(t> oldt)
            //Do stuff
            System.out.println("Swipe UP");
            //Do stuff
        
        else if(t< oldt)
            System.out.println("Swipe Down");
        
        Log.d(TAG,"We Scrolled etc...");
    
);

【讨论】:

@Chris.Jenkins 它没有用,它在我们使用 ClassCastException 的 findViewBid 的地方给出了错误 @AnasReza 你必须确保在你的 XML 文件中实现你的ObservableWebView。这是暗示的。 @Chris.Jenkins 是的,谢谢我在我的 XML 文件中实现,它运行良好 nt tek = (int) Math.floor(mTermsCondWV.getContentHeight() * mTermsCondWV.getScale()); if(tek - mTermsCondWV.getScrollY() == mTermsCondWV.getHeight()) mAgreeBT.setEnabled(true); mAgreeBT.setBackground(ContextCompat.getDrawable(getActivity(),R.drawable.button_bg)); 您好,它不适用于最新版本的api,您能否更新答案【参考方案2】:

从 API 23 开始,您不再需要这样做,您只需使用所有视图(包括 WebView 上的)可用的新 OnScrollChangeListener。但是由于您仍然需要支持旧版本,您仍然可以使用@Chris.Jenkins 的建议。我对提议的类进行了一些调整,使其与新的 OnScrollChangeListener 接口“更兼容”:

public class ObservableWebView extends WebView 
private OnScrollChangeListener onScrollChangeListener;

public ObservableWebView(Context context) 
    super(context);


public ObservableWebView(Context context, AttributeSet attrs) 
    super(context, attrs);


public ObservableWebView(Context context, AttributeSet attrs, int defStyleAttr) 
    super(context, attrs, defStyleAttr);


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


public void setOnScrollChangeListener(OnScrollChangeListener onScrollChangeListener) 
    this.onScrollChangeListener = onScrollChangeListener;


public OnScrollChangeListener getOnScrollChangeListener() 
    return onScrollChangeListener;


public interface OnScrollChangeListener 
    /**
     * Called when the scroll position of a view changes.
     *
     * @param v          The view whose scroll position has changed.
     * @param scrollX    Current horizontal scroll origin.
     * @param scrollY    Current vertical scroll origin.
     * @param oldScrollX Previous horizontal scroll origin.
     * @param oldScrollY Previous vertical scroll origin.
     */
    void onScrollChange(WebView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);


【讨论】:

@LucasS.Müller : 你必须支持向后版本,所以你不能简单地忽略它 嗨,Alecio,它不适用于最新版本的 apis【参考方案3】:

无需扩展 WebView。 怎么样:

webView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() 
    @Override
    public void onScrollChanged() 
        Log.v(TAG, "+++ scrollchanged "+webView.getScrollY());
    
);

【讨论】:

【参考方案4】:

这里是接受答案的更优雅的 Kotlin 版本


class ObservableWebView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0
) : WebView(context, attrs, defStyleAttr) 
    var scrollListener: WebViewScrollListener? = null

    override fun onScrollChanged(scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int) 
        super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY)
        when 
            scrollY > oldScrollY -> scrollListener?.onScrollDown()
            scrollY < oldScrollY -> scrollListener?.onScrollUp()
        
        scrollListener?.onScroll(scrollX, scrollY, oldScrollX, oldScrollY)
    


interface WebViewScrollListener
    fun onScroll(scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int)

    fun onScrollDown()

    fun onScrollUp()


【讨论】:

【参考方案5】:

你可以试试这个:

它适用于 API >= 23 Android Marshmallow

web.setOnScrollChangeListener(new View.OnScrollChangeListener() 

            @Override
            public void onScrollChange(View p1, int p2, int p3, int p4, int p5)
            
                Toast.makeText(getApplicationContext, "Scrolled", Toast.LENGTH_SHORT).show();
            
        );

【讨论】:

这对我来说非常有效。谢谢!【参考方案6】:

API 23(Android - 6.0),可以实现WebView.OnScrollChangeListenerlike

    public class MainActivity extends AppCompatActivity implements WebView.OnScrollChangeListener
    
         @Override
         public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) 
         
             if(oldScrollY < scrollY) 
             
                 //Scrolling Upwards
             
             else if(oldScrollY > scrollY)
             
                 //Scrolling Downwards
             
         
    

【讨论】:

【参考方案7】:

试试这个(所有查看你想要的): 创建一个 GestureDetector 然后创建一个 TouchListener 并设置为滚动的视图

OnCreate
         private GestureDetector gestureDetector;
         gestureDetector = new GestureDetector(this, new 
         GestureDetector.SimpleOnGestureListener() 
                @Override
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float 
           velocityY) 

                    if (velocityY < 0) 
                        collapse(frToolBar);

                     else if (velocityY > 0) 
                        if (frToolBar.getVisibility()==View.GONE)
                        expand(frToolBar);
                    
                    return super.onFling(e1, e2, velocityX, velocityY);
                

                @Override
                public boolean onDown(MotionEvent e) 
                    return super.onDown(e);
                
            );

          webView.setOnTouchListener((view, motionEvent) -> 
          gestureDetector.onTouchEvent(motionEvent));


    Two method - 

           public static void expand(final View v) 
            v.measure(WindowManager.LayoutParams.MATCH_PARENT,  
          indowManager.LayoutParams.WRAP_CONTENT);
             // final int targetHeight = v.getMeasuredHeight();
            final int targetHeight = v.getHeight();
            v.getLayoutParams().height = 1;
            v.setVisibility(View.VISIBLE);
            Animation a = new Animation() 
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) 
           
                    v.getLayoutParams().height = interpolatedTime == 1
                            ? WindowManager.LayoutParams.WRAP_CONTENT
                            : (int) (targetHeight * interpolatedTime);
                    v.requestLayout();
                

                @Override
                public boolean willChangeBounds() 
                    return true;
                
            ;
            a.setDuration(300);
            v.startAnimation(a);

        


        public static void collapse(final View v) 
            final int initialHeight = v.getMeasuredHeight();
            Animation a = new Animation() 
                @Override
                protected void applyTransformation(float interpolatedTime, Transformation t) 
           
                    if (interpolatedTime == 1) 
                        v.setVisibility(View.GONE);
                     else 
                        v.getLayoutParams().height = initialHeight - (int) (initialHeight * 
              interpolatedTime);
                        v.requestLayout();
                    
                

                @Override
                public boolean willChangeBounds() 
                    return true;
                
            ;
            a.setDuration(300);
            v.startAnimation(a);

        

【讨论】:

请解释你的答案 С创建一个手势然后触摸列表并设置为滚动视图

以上是关于如何在 Android 中为 WebView 制作滚动监听器的主要内容,如果未能解决你的问题,请参考以下文章

如何在 phonegap 中为社交分享 facebook、twitter 等创建自定义 webview?

如何在Android drawable中为环形制作圆角

如何在 android studio 中为线性布局制作“波浪”边框?

如何在android中为pdf查看器制作注释,如突出显示、删除线、下划线、绘制、添加文本等?

我该如何使用此Webview Bar? - Android Studio

如何将android webview保持在后台(使用位置)