提示错误
Error inflating class android.webkit.WebView
办法:新建类
public class my_WebView extends WebView { public my_WebView (Context context) { super(getFixedContext(context)); } public my_WebView (Context context, AttributeSet attrs) { super(getFixedContext(context), attrs); } public my_WebView (Context context, AttributeSet attrs, int defStyleAttr) { super(getFixedContext(context), attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public my_WebView (Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(getFixedContext(context), attrs, defStyleAttr, defStyleRes); } public my_WebView (Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) { super(getFixedContext(context), attrs, defStyleAttr, privateBrowsing); } public static Context getFixedContext(Context context) { if (Build.VERSION.SDK_INT >= 21 && Build.VERSION.SDK_INT < 23) // Android Lollipop 5.0 & 5.1 return context.createConfigurationContext(new Configuration()); return context; }
在XML中将将控件webview替换为my_WebView
试了几种办法,就这个起作用。
后期又发现问题,当网页中有下拉菜单的时候,程序会崩溃
导致该问题的原因是context不是activity的context,上述方法行不通
最后找到一个最好的办法,在manifest中设置activity的属性
android:configChanges="uiMode"后直接使用WebView控件
-----------------------------------------------------------------------------------------------------------------------------------
个人感觉比较全的dialog+webview
public class my_webview {
WebSettings setting;
MainActivity activity;
Boolean isError = true;//默认会加载成功
ImageView rush_touming_webview;//加载失败画面
ImageView waitting_view;//正在加载画面
WebView webView;//加载成功后的网页
View view;//容器
public my_webview(MainActivity activity) {
this.activity = activity;
}
public WebView equ_showDialog_info(String URl) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
view = activity.getLayoutInflater().inflate(R.layout.my_webview, null);
webView = (WebView) view.findViewById(R.id.my_web);
rush_touming_webview = (ImageView) view.findViewById(R.id.rush_touming_webview);
waitting_view = (ImageView) view.findViewById(R.id.webview_loading_pic);
Glide.with(activity).load(R.drawable.waiting).into(waitting_view);
// 加载失败界面添加点击监听,加载失败刷新重新加载
rush_touming_webview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webView.reload();//重新加载网页
}
});
setting = webView.getSettings();
webset();
// WebView界面添加监听,加载开始、结束(根据成功与否对应响应)
webView.setWebViewClient(new WebViewClient() {
@Override//开始加载
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//显示提示界面
control_ui(1);
isError = true;//刷新后,初始化标记,否则一直判定加载失败
}
@Override//加载结束
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (isError) {//加载成功,隐藏提示界面
control_ui(2);
} else {//加载失败,继续显示提示界面
control_ui(3);
}
}
@Override//网页支持重定向,和setting里面setLayoutAlgorithm搭配生效
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//注意这边必须返回false
return false;
}
// 添加监听,判断页面是否加载失败
@Override//监听加载是否成功,如果失败了,会自动调用该方法(SDK>23)
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
// 失败了记录下,此时可以retryLoading()
isError = false;//该函数被调用,说明加载出错
}
@Override//监听加载是否成功,如果失败了,会自动调用该方法(SDK<=23)
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
// 失败了记录下,此时可以retryLoading()
isError = false;//该函数被调用,说明加载出错
}
});
webView.loadUrl(URl);//webview加载网页
builder.setView(view);//将显示界面添加进builder,必须在alertDialog = builder.create();之前,负责alertDialog里面没有内容
/*
通过builder生成alertDialog
其实可以直接给builder添加按钮监听,以及show(),但是builder没有setCanceledOnTouchOutside方法,只有setCancelable方法
setCancelable这个方法把点击外部和点击返回键全部都限制了,导致点返回键不能关闭窗口(要么同时可触发,要么同时不可触发)
setCanceledOnTouchOutside方法只限制点击外部区域关闭窗口,不影响点击返回键
*/
final AlertDialog alertDialog = builder.create();
// 添加监听,点击返回按钮先返回网页,不是关闭
alertDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,KeyEvent event) {
// 返回到起始网页后继续点击返回按钮关闭窗口
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;//不关闭webview
}
return false;//关闭webview
}
});
// 设置点击外部不关闭窗口,只能通过返回键来关闭
alertDialog.setCanceledOnTouchOutside(false);//就因为AlertDialog有这个属性,所以都不用builder
alertDialog.show();
// dialog获取焦点,弹出软键盘(一定要放在show之后)
// 清除flags,获取焦点
alertDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
// 弹出输入法
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
return webView;
}
private Timer timer;//计时器
private long timeout = 5000;//超时时间
// 因为涉及到UI,所以使用RXJAVA调整到主线程
@SuppressLint("CheckResult")
private void control_ui(int i){
Observable.just(1)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
rush_touming_webview.setVisibility(View.GONE);
webView.setVisibility(View.GONE);
waitting_view.setVisibility(View.GONE);
switch (i) {
case 1:
// 先尝试取消以前的计时,重新开始计时
stop_timer();
// 计时,超时了切换到失败界面,并停止计时
timer =new Timer();
TimerTask tt =new TimerTask() {
@Override
public void run() {
control_ui(3);//计时没有被取消,说明加载失败,显示失败界面
}
};
timer.schedule(tt, timeout, 1);//计时器只执行1次
// 显示加载动画
waitting_view.setVisibility(View.VISIBLE);
break;
case 2:
// 显示网页
webView.setVisibility(View.VISIBLE);
stop_timer();//显示页面成功,停止计时
break;
case 3:
// 显示加载失败界面
rush_touming_webview.setVisibility(View.VISIBLE);
stop_timer();//显示页面失败,停止计时
break;
}
}
});
}
// 停止计时
private void stop_timer(){
try{
timer.cancel();
timer.purge();
}catch (Exception e){
}
}
// 设置webview参数
private void webset() {
setting.setAllowFileAccess(true);//当设置为true,就可以 使用file://加载文件
setting.setDefaultTextEncodingName("UTF-8");
setting.setJavaScriptEnabled(true);//支持JavaScript
setting.setCacheMode(WebSettings.LOAD_DEFAULT);
setting.setDefaultZoom(WebSettings.ZoomDensity.FAR);
setting.setSupportZoom(true);
setting.setBuiltInZoomControls(true);
setting.setDisplayZoomControls(false);
setting.setAppCacheEnabled(true);
setting.setDomStorageEnabled(true);
// setting.setBlockNetworkImage(true);//true不下载图片
setting.setCacheMode(WebSettings.LOAD_DEFAULT);
setting.setSavePassword(false);
setting.setUseWideViewPort(true);//让Webivew支持<meta>标签的viewport属性(根据网页属性缩放网页)
setting.setLoadWithOverviewMode(false);//加载完全缩小的WebView
setting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);//重定向显示的界面
}
}