前幾天腦子里忽然閃過簡書的圖片分享效果昂验,感覺很簡潔也很漂亮,想著能不能用自己方式實現(xiàn)一下呢蟹演,于是今天就有了這篇文章抄瑟。好了凡泣,先看下效果圖吧:
項目地址:** https://github.com/zhangke3016/GeneratePicture **歡迎star、issues~
實現(xiàn)這個效果皮假,首先要弄明白幾個問題:
一、如何獲取選取的網(wǎng)頁內(nèi)容
二骂维、獲取的網(wǎng)頁內(nèi)容如何加載顯示
一惹资、如何獲取選取的網(wǎng)頁內(nèi)容
獲取選取的網(wǎng)頁內(nèi)容,通過Java來獲取選取的網(wǎng)頁內(nèi)容很困難航闺,而實現(xiàn)效果又必須要得到選取的網(wǎng)頁內(nèi)容褪测,我們可以轉(zhuǎn)換下思路,既然通過Java層不容易得到那通過JavaScript是不是要容易點呢潦刃,之后的實現(xiàn)確定這個思路是正確的侮措,JavaScript很容易獲取選取的網(wǎng)頁內(nèi)容。
那我們的思路就是:當用戶點擊生成圖片分享按鈕后乖杠,我們調(diào)用JavaScript方法獲取選取的網(wǎng)頁內(nèi)容同時回調(diào)Java的獲取內(nèi)容方法分扎,將獲取的網(wǎng)頁內(nèi)容回傳到Java層,我們就可以拿到網(wǎng)頁的內(nèi)容了胧洒。
簡單看下代碼:
mWebView.addJavascriptInterface(new WebAppInterface(onGetDataListener), "JSInterface");
public void getSelectedData(WebView webView) {
String js = "(function getSelectedText() {" +
"var txt;" +
"if (window.getSelection) {" +
"var range=window.getSelection().getRangeAt(0);" +
"var container = window.document.createElement('div');" +
"container.appendChild(range.cloneContents());" +
"txt = container.innerHTML;" +
"} else if (window.document.getSelection) {" +
"var range=window.getSelection().getRangeAt(0);" +
"var container = window.document.createElement('div');" +
"container.appendChild(range.cloneContents());" +
"txt = container.innerHTML;" +
"} else if (window.document.selection) {" +
"txt = window.document.selection.createRange().htmlText;" +
"}" +
"JSInterface.getText(txt);" +
"})()";
// calling the js function
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("javascript:" + js, null);
} else {
webView.loadUrl("javascript:" + js);
}
webView.clearFocus();
}
static class WebAppInterface {
WebViewHelper.OnGetDataListener onGetDataListener;
WebAppInterface(WebViewHelper.OnGetDataListener onGetDataListener) {
this.onGetDataListener = onGetDataListener;
}
@JavascriptInterface
public void getText(String text) {
onGetDataListener.getDataListener(text);
}
}
public interface OnGetDataListener{
void getDataListener(String text);
}
上面的實現(xiàn)思路就是當我們要獲取選取的網(wǎng)頁內(nèi)容時畏吓,給WebView注入一段自己寫的JavaScript腳本,這段JavaScript代碼的含義就是獲取當前頁面選取的內(nèi)容包含html標簽卫漫,調(diào)用JSInterface.getText(txt)
方法將內(nèi)容回傳給Java的getText(String text)
方法菲饼,我們設(shè)置onGetDataListener.getDataListener(text)
回調(diào)方法,由需要的地方調(diào)用獲取內(nèi)容列赎。
二宏悦、獲取的網(wǎng)頁內(nèi)容如何加載顯示
我們已經(jīng)獲取到了網(wǎng)頁內(nèi)容,按道理其實調(diào)用TextView的setText(Html.fromHtml())
這個方法就可以顯示我們選取的效果,但考慮到美觀性以及截圖保存功能饼煞、圖片的正常顯示源葫,我選取用WebView來加載獲取的網(wǎng)頁內(nèi)容。
這里我是這樣處理的:首先在本地assets
文件夾下創(chuàng)建一個html頁面派哲,在頁面里加載基本的顯示內(nèi)容并添加css標簽修飾加載的內(nèi)容臼氨,當獲取到網(wǎng)頁內(nèi)容時,用JavaScript動態(tài)替換本地html頁面指定的對應(yīng)標簽內(nèi)容為獲取的網(wǎng)頁內(nèi)容芭届,并在本地html頁面里對顯示內(nèi)容進行修飾储矩。
看下代碼:
webView.loadUrl("file:///android_asset/generate_pic.html");
public void changeDay(String strData,String userInfo,String userName,String other) {
if(userInfo == null)
userInfo ="";
if(strData == null)
strData ="";
if(userName == null)
userName ="";
if(other == null)
other ="";
strData+="<br /><br />\n" +
"\t\t<span style=\"font-size: small;color: gray;line-height:150%;\">"+userInfo+"</span>\n" +
"\t\t<br /><br />\n" +
"\t\t<hr style=\"margin: auto;border:0;background-color:gray;height:1px;\"/>\n" +
"\t\t<br />\n" +
"\t\t<p style=\"color: orangered;font-size: x-small;text-align: center;letter-spacing: 0.5px;\">由<strong>"+userName+"</strong>發(fā)送 "+other+"</p>";
webView.loadUrl("javascript:changeContent(\"" + strData.replace("\n", "\\n").replace("\"", "\\\"").replace("'", "\\'") + "\")");
webView.setBackgroundColor(Color.WHITE);
}
白色和黑色不同的顯示效果實現(xiàn)可以在changeDay
方法里改變css樣式來實現(xiàn),比較簡單褂乍。
但這里出現(xiàn)了一個問題:當選取的頁面內(nèi)容有圖片且圖片是以相對路徑顯示的時候就加載不到圖片了持隧。
在這種情況下圖片是相對路徑也就是在本地對應(yīng)的相對路徑下找,本地肯定是找不到的逃片,圖片也就顯示不出來屡拨。
為了讓圖片正常顯示出來,在選取內(nèi)容頁面調(diào)用onLoadResource
方法對加載的資源進行判斷褥实,將圖片路徑保存下來呀狼,因為既然選取頁面圖片可以顯示處理,說明路徑是http路徑损离,可以顯示圖片哥艇。
看下代碼:
mWebView.setWebViewClient(new WebViewClient(){
@Override
public void onLoadResource(WebView view, String url) {
//Log.e("TAG","url :"+url);
if(url.toLowerCase().contains(".jpg")
||url.toLowerCase().contains(".png")
||url.toLowerCase().contains(".gif")){
mlistPath.add(url);
}
super.onLoadResource(view, url);
}
當顯示選取內(nèi)容頁面顯示時動態(tài)修改顯示的圖片路徑,讓圖片顯示出來:
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//view.loadUrl(url);
return true;
}
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
WebResourceResponse response = null;
for (String path:WebViewHelper.getInstance().getAllListPath()){
if (path.toLowerCase().contains(url.replace("file://","").toLowerCase())){
try {
response = new WebResourceResponse("image/png", "UTF-8", new URL(path).openStream());
} catch (IOException e) {
e.printStackTrace();
}
}
}
return response;
}
});
這樣僻澎,我們的圖片就可以顯示出來啦貌踏!
最后,實現(xiàn)我們的截圖保存功能窟勃,看下代碼:
/**
* 截屏
*
* @return
*/
public Bitmap getScreen() {
Bitmap bmp = Bitmap.createBitmap(webView.getWidth(), 1, Bitmap.Config.ARGB_8888);
int rowBytes = bmp.getRowBytes();
bmp = null;
if (rowBytes*webView.getHeight()>=getAvailMemory()){
return null;
}
bmp = Bitmap.createBitmap(webView.getWidth(), webView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
webView.draw(canvas);
return bmp;
}
private long getAvailMemory() {
return Runtime.getRuntime().maxMemory();
}
這里需要對保存的圖片大小做下判斷祖乳,防止創(chuàng)建圖片過大OOM。
到這里秉氧,基本功能就已經(jīng)實現(xiàn)了眷昆。把圖片分享給好友吧~
項目地址:** https://github.com/zhangke3016/GeneratePicture **歡迎star、issues~