如何在 Android WebView 重动态加载页面和注入 CSS 和 JavaScript ?
我们在开发过程中可能有这样的需求, 用一个 WebView 去加载网页的时候, 原来的网页里面的样式用安卓的WebView控件打开, 想改变原网页的样式为另外的一种样式, 这时候就可以采用这样的方法:
主要使用了 Android WebView 这个类里面的一个函数:
loadDataWithBaseURL(url, page, null, mDefaultEncoding, null);
下面是完整的 CSS注入 代码:
public class StyledWebView extends WebView {
private static final String TAG = "AsSamsung";
public static String mDefaultEncoding = "UTF-8";
private Context mContext;
private String mCss, mUrl;
public StyledWebView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
this.setHorizontalScrollBarEnabled(true);
this.getSettings().setJavaScriptEnabled(true);
this.getSettings().setBuiltInZoomControls(true);
// Read custom attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StyledWebView);
mCss = a.getString(R.styleable.StyledWebView_css);
mUrl = a.getString(R.styleable.StyledWebView_url);
a.recycle();
loadUrl(mUrl);
}
/**
* Complete delete everything in the webview.
* Is needed to repaint
*/
public void clean() {
super.loadUrl("javascript:document.getElementsByTagName('body')[0].innerHTML='';");
}
/**
* Download url content, store it as a file and concat styles
*/
@Override
public void loadUrl(String url) {
String page = WGet(url);
String css = buildCss();
page = injectCss(page, css);
super.loadDataWithBaseURL(url, page, null, mDefaultEncoding, null);
}
/**
* Concatenates CSS rules to given page content
* @return Concatenation result
*/
private String injectCss(String page, String css) {
int headEnd = page.indexOf("</head>");
String res = "";
if (headEnd > 0) {
res = page.substring(0, headEnd) + css + page.substring(headEnd, page.length());
} else {
res = "<head>" + css + "</head>" + page;
}
return res;
}
/**
* Fetches url content and returns it as string
*/
private String WGet(String webUrl) {
StringBuilder total = new StringBuilder();
try {
URL url = new URL(webUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream is = connection.getInputStream();
String encoding = connection.getContentEncoding();
if (encoding == null) {
encoding = mDefaultEncoding;
}
BufferedReader r = new BufferedReader(new InputStreamReader(is, encoding));
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return total.toString();
}
/**
* Read CSS file from assets
* @return String with the format '<style> xxxx </style>'
*/
private String buildCss() {
StringBuilder contents = new StringBuilder();
InputStreamReader reader;
try {
reader = new InputStreamReader(mContext.getAssets().open(mCss), mDefaultEncoding);
BufferedReader br = new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null) {
contents.append(line);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "<style>" + contents.toString().trim().replace("\n", "") + "</style>";
}
public void setDefaultEncoding(String encoding) {
mDefaultEncoding = encoding;
}
}
assets目录下的两个文件:
文件1: customStyle.css
a {
color: #A4C639 !important;
font-weight: bold;
}
文件2: resultados.css
h1, h2 {
color: red;
}
ul.tabmain a{
color: green;
}
同理 JavaScript 也是类似的思路. 有兴趣小伙伴可以去试一下.