概述
需求:管理端有个富文本可以添加一个阅读须知,通过接口将富文本生成的Html返回给Android端,要求展示正确展示富文本内容,并且如果内容较多时,用户需要看完所有内容(滑动到底部)才能确认进入下一步。
简单来说需要实现加载Html片段,并且根据内容多少判断是否需要滑动到底部和是否滑动到底部了。下面封装一个自定义的WebView,实现此需求:
package com.zhn.learn_android;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
/**
* @author : zhn
* @date : 2022/11/1 14:04
* description :滑动监听WebView
*/
public class ScrollListenerWebView extends WebView {
//webView的高度,dp
public int viewHeight = 0;
//web内容高度,dp
public int contentHeight = 0;
public ScrollListenerWebView(Context context) {
super(getFixedContext(context));
}
public ScrollListenerWebView(Context context, AttributeSet attrs) {
super(getFixedContext(context), attrs);
}
public ScrollListenerWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(getFixedContext(context), attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ScrollListenerWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(getFixedContext(context), attrs, defStyleAttr, defStyleRes);
}
/**
* 解决Android 5.0~5.1 WebView兼容问题
* @param context ctx
* @return ctx
*/
private static Context getFixedContext(Context context) {
// Android Lollipop 5.0 & 5.1
if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23) {
return context.createConfigurationContext(new Configuration());
}
return context;
}
/**
* 添加获取
*
* @param activity activity
*/
public void addWebHeightSupport(Activity activity, ScrollWebListener listener) {
this.mListener = listener;
addWebHeightSupport(activity, this, "app");
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewHeight = px2dip(getContext(), getMeasuredHeight());
Log.e("onMeasure"," viewHeight= "+viewHeight);
}
@JavascriptInterface
public void contentHeight(int webContentHeight) {
contentHeight = webContentHeight;
if (mListener == null || contentHeight <= 0) {
return;
}
Log.e("","contentHeight="+contentHeight);
//如果html高度小于控件高度,那么说明一屏可以展示下
if (contentHeight < viewHeight) {
mListener.noScroll();
} else {
mListener.needScroll();
}
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mListener == null) {
return;
}
// 当前webview的高度
float webNow = viewHeight + px2dip(getContext(),getScrollY());
//判断是否抵达底部
if (webNow >= contentHeight - 10) {
mListener.scrollBottom();
}
}
/**
* 添加内容高度支持
*
* @param activity activity
* @param jsInterface js接口
* @param jsInterfaceName js接口名称
*/
@SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface", "JavascriptInterface"})
private void addWebHeightSupport(Activity activity, Object jsInterface, String jsInterfaceName) {
//js支持
getSettings().setJavaScriptEnabled(true);
//添加JS交互方法
this.addJavascriptInterface(jsInterface, jsInterfaceName);
//监听加载进度
setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
addWebHeightSupport(newProgress);
}
});
}
/**
* 添加内容高度预览支持
*
* @param newProgress 加载进度
*/
private void addWebHeightSupport(int newProgress) {
if (newProgress == 100) {
Observable.timer(200L, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.safeSubscribe(new Observer<Long>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(Long aLong) {
loadUrl("javascript:(function(){" +
"var result = document.body.offsetHeight; " +
"window.app.contentHeight(result);" +
"})()");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
}
private ScrollWebListener mListener;
public interface ScrollWebListener {
void noScroll();
void needScroll();
void scrollBottom();
}
/**
* 获取Html前缀
*
* @return
*/
public String getHtmlPrefixStr() {
return "<!DOCTYPE html><html><head><meta name='viewport' content='width=device-width,initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no'>" +
"<style>" +
"*{margin:0 !important;}" +
"img{width:100% !important; height:auto !important; margin-top:10px !important;margin-bottom:10px !important; border-radius:4px;}" +
"div{font-size:14px !important; color: #3A3D4B !important; font-family: PingFangSC;}" +
"body{padding: 20px 16px 20px 20px;}" +
"</style>" +
"</head><body><div>";
}
/**
* 获取Html后缀
*
* @return
*/
public String getHtmlSuffixStr() {
return "</div></body></html>";
}
/**
* 加载Html片段
*
* @param htmlPart html片段
*/
public void loadHtmlPart(String htmlPart) {
loadDataWithBaseURL(null, getHtmlPrefixStr() + htmlPart + getHtmlSuffixStr(),
"text/html", "utf-8", null
);
}
public int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
}
使用:
package com.zhn.learn_android
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
class TestActivity : AppCompatActivity() {
private var mWebView:ScrollListenerWebView?=null
private var btnConfirm:Button?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_test)
mWebView=findViewById(R.id.web_view)
btnConfirm=findViewById(R.id.btn_confirm)
mWebView!!.addWebHeightSupport(this,object : ScrollListenerWebView.ScrollWebListener{
override fun noScroll() {
Log.e("-TestActivity--","不需要滑动")
btnConfirm!!.isEnabled=true
}
override fun needScroll() {
Log.e("-TestActivity--","需要滑动")
btnConfirm!!.isEnabled=false
}
override fun scrollBottom() {
Log.e("-TestActivity--","滑动到底部了")
btnConfirm!!.isEnabled=true
}
})
}
fun loadWithHtmlPart(view:View){
var htmlPart="<p>阿神经asx酰胺北ahsx京</p>" +
"<img src="https://img2.baidu.com/it/u=1245013499,1883492144&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500">" +
"<p>市西安ajsbhx不熟悉asbx啊</p>" +
"<img src="https://img2.baidu.com/it/u=1245013499,1883492144&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500">"
mWebView!!.loadHtmlPart(htmlPart)
}
}
效果:
device-2022-11-06-144942
总结:
1、给Html片段添加Html头和尾
2、重写onMeasure方法获取WebView控件的高度
3、通过Js交互获取html中body的高度,与WebView高度对比判断是否需要滑动
4、监听WebView的onScrollChanged方法,判断是否滑动到底部了
最后
以上就是长情小蝴蝶为你收集整理的WebView加载Html片段监听滑动到底部的全部内容,希望文章能够帮你解决WebView加载Html片段监听滑动到底部所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复