如何在 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.OnScrollChangeListener
like
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 studio 中为线性布局制作“波浪”边框?
如何在android中为pdf查看器制作注释,如突出显示、删除线、下划线、绘制、添加文本等?