实现仿简书选取内容生成分享图片效果

前几天脑子里忽然闪过简书的图片分享效果,感觉很简洁也很漂亮,想着能不能用自己方式实现一下呢,于是今天就有了这篇文章。好了,先看下效果图吧:

GeneratePicture

项目地址: https://github.com/zhangke301... 欢迎star、issues~

实现这个效果,首先要弄明白几个问题:

一、如何获取选取的网页内容
二、获取的网页内容如何加载显示

GeneratePicture

一、如何获取选取的网页内容

获取选取的网页内容,通过Java来获取选取的网页内容很困难,而实现效果又必须要得到选取的网页内容,我们可以转换下思路,既然通过Java层不容易得到那通过JavaScript是不是要容易点呢,之后的实现确定这个思路是正确的,JavaScript很容易获取选取的网页内容。

那我们的思路就是:当用户点击生成图片分享按钮后,我们调用JavaScript方法获取选取的网页内容同时回调Java的获取内容方法,将获取的网页内容回传到Java层,我们就可以拿到网页的内容了。
简单看下代码:

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 functionif (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;}@JavascriptInterfacepublic void getText(String text) {onGetDataListener.getDataListener(text);}}public interface OnGetDataListener{void getDataListener(String text);}

上面的实现思路就是当我们要获取选取的网页内容时,给WebView注入一段自己写的JavaScript脚本,这段JavaScript代码的含义就是获取当前页面选取的内容包含html标签,调用JSInterface.getText(txt)方法将内容回传给Java的getText(String text)方法,我们设置onGetDataListener.getDataListener(text)回调方法,由需要的地方调用获取内容。

二、获取的网页内容如何加载显示

我们已经获取到了网页内容,按道理其实调用TextView的setText(Html.fromHtml())这个方法就可以显示我们选取的效果,但考虑到美观性以及截图保存功能、图片的正常显示,我选取用WebView来加载获取的网页内容。

这里我是这样处理的:首先在本地assets文件夹下创建一个html页面,在页面里加载基本的显示内容并添加css标签修饰加载的内容,当获取到网页内容时,用JavaScript动态替换本地html页面指定的对应标签内容为获取的网页内容,并在本地html页面里对显示内容进行修饰。

看下代码:

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>发送 "+other+"</p>";webView.loadUrl("javascript:changeContent(\"" + strData.replace("\n", "\\n").replace("\"", "\\\"").replace("'", "\\'") + "\")");webView.setBackgroundColor(Color.WHITE);}

白色和黑色不同的显示效果实现可以在changeDay方法里改变css样式来实现,比较简单。

但这里出现了一个问题:当选取的页面内容有图片且图片是以相对路径显示的时候就加载不到图片了。

在这种情况下图片是相对路径也就是在本地对应的相对路径下找,本地肯定是找不到的,图片也就显示不出来。
为了让图片正常显示出来,在选取内容页面调用onLoadResource方法对加载的资源进行判断,将图片路径保存下来,因为既然选取页面图片可以显示处理,说明路径是http路径,可以显示图片。
看下代码:

 mWebView.setWebViewClient(new WebViewClient(){@Overridepublic 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);}

当显示选取内容页面显示时动态修改显示的图片路径,让图片显示出来:

 webView.setWebViewClient(new WebViewClient(){@Overridepublic 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;}});

这样,我们的图片就可以显示出来啦!
最后,实现我们的截图保存功能,看下代码:

 /*** 截屏** @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();}

这里需要对保存的图片大小做下判断,防止创建图片过大OOM。

到这里,基本功能就已经实现了。把图片分享给好友吧~

项目地址: https://github.com/zhangke301... 欢迎star、issues~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

千万级可观测数据采集器--iLogtail代码完整开源

2022年6月29日&#xff0c;阿里云iLogtail开源后迎来首次重大更新&#xff0c;正式发布完整功能的iLogtail社区版。本次更新开源全部C核心代码&#xff0c;该版本在内核能力上首次对齐企业版&#xff0c;开发者可以构建出与企业版性能相当的iLogtail云原生可观测性数据采集器。…

Java8新特性--CompletableFuture

并发与并行 Java 5并发库主要关注于异步任务的处理&#xff0c;它采用了这样一种模式&#xff0c;producer线程创建任务并且利用阻塞队列将其传递给任务的consumer。这种模型在Java 7和8中进一步发展&#xff0c;并且开始支持另外一种风格的任务执行&#xff0c;那就是将任务的…

用 MAUI 在Windows 和 Linux 绘制 PPT 图表

我在做一个图表工具软件&#xff0c;这个软件使用 MAUI 开发。我的需求是图表的内容需要和 PPT 的图表对接&#xff0c;需要用到 OpenXML 解析 PPT 内容&#xff0c;读取到 PPT 图表元素的内容&#xff0c;接着使用 MAUI 渲染层绘制图表元素。图表工具软件需要在 Windows 平台和…

聊聊接口性能优化的11个小技巧

前言 接口性能优化对于从事后端开发的同学来说&#xff0c;肯定再熟悉不过了&#xff0c;因为它是一个跟开发语言无关的公共问题。 该问题说简单也简单&#xff0c;说复杂也复杂。 有时候&#xff0c;只需加个索引就能解决问题。 有时候&#xff0c;需要做代码重构。 有时…

Java中ArrayList,LinkedList,Vector三者的异同点及其使用场景和ArrayList的一些常用方法

相同点&#xff1a;三者存储的都是有序&#xff0c;可重复的数据。 异&#xff1a; ①&#xff1a;ArrayList底层存储类型是Object数组&#xff0c;而LinkedList底层是双向链表 ②&#xff1a;ArrayList和Vector调用创建空参构造器创建对象时&#xff0c;默认的size是10&…

第二百四十六节,Bootstrap弹出框和警告框插件

Bootstrap弹出框和警告框插件 学习要点&#xff1a; 1.弹出框 2.警告框 本节课我们主要学习一下 Bootstrap 中的弹出框和警告框插件。 一&#xff0e;弹出框 弹出框即点击一个元素弹出一个包含标题和内容的容器。 基本用法 注意&#xff1a;必须在js结合popover()方法使用 da…

Intellij IDEA2017 的控制台里不识别maven命令问题处理

2019独角兽企业重金招聘Python工程师标准>>> cmd里运行 mvn -v可以显示出maven的版本信息&#xff0c;可是在IDEA的控制台里却提示不识别maven命令&#xff0c;此情况以管理员的身份运行IDEA即可。 转载于:https://my.oschina.net/u/2364025/blog/1788797

使用IDEA 提交代码到svn

2019独角兽企业重金招聘Python工程师标准>>> 新手第一次使用教程&#xff1a; 一、安装svn TortoiseSVN是个客户端&#xff0c;需要安装VisualSVN服务端。 二、IDEA配置&#xff08;Ctrl alt S&#xff09; 需要配置服务端svn.exe文件。 三、上传代码 svn路径&…

如何在 BackgroundService 获取 ASP.NET Core 启动地址

前言上次&#xff0c;我们介绍了《如何获取 ASP.NET Core 启动地址》。但是&#xff0c;如果要在 BackgroundService 中获取启动地址可不那么容易&#xff0c;因为 BackgroundService 在 app 启动前就开始执行了:var builder WebApplication.CreateBuilder(args); builder.Ser…

016-Spring Boot JDBC

一、数据源装配 通过查看代码可知&#xff0c;默认已装配了数据源和JdbcTemplate System.out.println(context.getBean(DataSource.class)); System.out.println(context.getBean(JdbcTemplate.class)); 1.1、环境搭建 主要是pom引用&#xff1a;spring-boot-starter-jdbc、增加…

分库分表和 NewSQL 到底怎么选?

文章来源&#xff1a;【公众号&#xff1a;CoderW】 目录 背景 分表 分库 分库分表的成本 NewSQL NewSQL 平滑接入方案 NewSQL 真的有那么好吗&#xff1f; NewSQL 的应用 分库分表和 NewSQL 到底怎么选&#xff1f; 背景 曾几何时&#xff0c;“并发高就分库&#xff…

jQuery/javascript实现简单网页计算器

1 <html>2 <head>3 <meta charset"utf-8">4 <title>jQuery实现</title>5 <script src"jquery.js"></script>6 7 <style type"text/css">8 table{background-color:pink;width:300px;height…

雷军招人反被3句话问懵:当我在面试牛人的时候,牛人也在面试我

来 源&#xff5c;环球人力资源智库&#xff08;GHRlib&#xff09; 作 者&#xff5c;Black “你做过手机吗&#xff1f;” “没做过。” “你认识中移动老总王建宙吗&#xff1f;” “不认识。” “你认识富士康老板郭台铭吗&#xff1f;” “我认识他&#xff0c;他不认识我…

C# 11 中的 required members

C# 11 中的 required membersIntro在 C# 11 中引入了一个新的特性 —— Required Members&#xff0c;引入了一个新的 required 关键词&#xff0c;可以用来表示字段或者属性在类型初始化的时候必须要进行初始化&#xff0c;这一特性也进一步的改进了可空引用类型的用法。Sampl…

互联网大佬简史:马云/雷军/罗永浩/刘强东...

燃财经&#xff08;ID:rancaijing&#xff09;原创 作者 | 杜枫 编辑 | 魏佳中国互联网的发展&#xff0c;是一部由大佬撑起的奋斗史&#xff0c;也是一部由大佬主演的打脸史。和传统行业不同&#xff0c;互联网行业日新月异&#xff0c;从业者趋于年轻。马云唱起了摇滚&#x…

Windows 11 新版 22621.575 和 22622.575 推送:照片、URL、文件资源管理器

面向 Beta 频道的 Windows 预览体验成员&#xff0c;微软推送了 Windows 11 预览版 Build 22621.575 和 22622.575。 目前 Beta 频道 Windows 11 预览版分为两组进行测试&#xff0c;通过两组 Windows 预览体验成员的使用数据和反馈&#xff0c;以更好的测试新功能的可靠性。Wi…

linux mysql5.6 安装

2019独角兽企业重金招聘Python工程师标准>>> 1、gcc yum install gcc gcc-c ncurses-devel perl 2、cmake安装 wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz tar -xzvf cmake-2.8.10.2.tar.gz cd cmake-2.8.10.2 ./bootstrap ; make ; make insta…

Python常用的12个GUI框架

Graphical User Interface&#xff0c;简称 GUI&#xff0c;又称图形化用户接口&#xff0c;所谓的GUI编程&#xff0c;指的是用户不需要输入代码指令&#xff0c;只通过图形界面的交互就可以操作软件功能。 1.Tkinter 一个轻量级的跨平台图形用户界面&#xff08;GUI&#xff…

PHP下操作Linux消息队列完成进程间通信的方法

2019独角兽企业重金招聘Python工程师标准>>> 来源:http://www.jb51.net/article/24353.htm 关于Linux系统进程通信的概念及实现可查看&#xff1a;http://www.ibm.com/developerworks/cn/linux/l-ipc/   关于Linux系统消息队列的概念及实现可查看&#xff1a;htt…

.NET 7 发布的最后一个预览版Preview 7, 下个月发布RC

微软在2022年8月9日 发布了.NET 7 Preview 7[1]&#xff0c;这是它在11月10日 RTM 之前进入发布候选阶段之前的最后预览版。预览版 7 已在 Visual Studio 17.4 预览版 1 中进行了测试&#xff0c;该预览版也于也与 VS 2022 v17.3 版本一起发布。对于预览版7&#xff0c;开发团队…