背景

最近我们的产品来了个新的模块,给学生做题提高成绩的。需求如下:

支持单选、多选、填空题

支持图片文字混排

输入框有交互,排版精致美观

为了体验优化,不能使用网页实现效果

思路分析

我们的图文混排控件继承自TextView,重写了关键的测量onMeasure和绘制onDraw步骤

测量决定了混排里的元素的位置、尺寸;

绘制决定了如何去渲染这些元素(以及通知输入框位置)

1:图片文字混排

系统的TextView通过ImageGetter就可以原生实现对文本img标签的支持,从而达到图文混排的效果。

具体实现步骤请参考Github上的一个库https://github.com/zzhoujay/RichText

2:输入框混排

下面是我具体的实现步骤,请在步骤1图文混排源码基础上进行阅读。

最后的UI结构应该是这样子的,用输入框盖在透明的占位图上,达到了输入框混排的效果。

做题控件树

如果是列表里展示结果,不涉及输入框的。那就只有一个图文混排控件,把输入框转换成下划线____即可

2.0:根据题目答案数量,生成对应数量的输入框,添加到容器中,设置为不可见

2.1:题目中的输入框标记,通过正则表达式使用图片Img标签代替,src设置为:Input标签+输入框对应答案ID+该输入框对应答案文字长度

2.2:在ImageGetter中,发现当前图片包含Input标签,则使用一个透明的占位图代替,宽度为画笔的文本尺寸*答案长度

2.3:参考本步骤开始给出的代码地址,稍微加工下就可以拿来实现自己的TextView,在onDraw事件里,就能获取当前的x、y值。

2.4:在onDraw事件里,遇到当前绘制的Span是图片类型,且src包含Input标签的,获取当前的高度和左边距,通过下面代码获取图片的宽度。imgSpan.getDrawable().getBounds().width()

2.5:用步骤4取到的数据,设置MarginLeft和MarginTop,还有宽度,通过输入框对应答案ID来找到2.0对应的输入框,刷新其位置和宽度

输入框排版大体流程

最终实现的效果如如下,满足产品需求

效果图1

效果图2

FAQ

下面是一些网友的提问

1 问题:效果图里,文字垂直居中对齐,怎么做到的

回答:

原生TextView是底部对齐的,我们自己实现的图文混排是可以自由定制垂直对齐方式的,参考我给出的第二个博客地址,他里面会记录每一行的行高,然后在绘制的时候,判断当前行高是否大于标准行高(我们填空题或者选择题都会有一个初始行高。)

如果当前行高>默认行高,则说明此行有大图,文本垂直居中=当前高度+(行高-文本高度)/2;

如果当前行高==默认行高,判断图片的高度如果小于默认行高,则图片垂直居中=当前高度+(行高-图片高度)/2;

2 请问返回的数据有处理不了的标签怎么处理,还有怎么实现如果返回的图片宽度大于一屏不被截图的问题呢?

回答:

1:标签和服务端沟通好,只返回有用的标签。一些数学符号用png图片代替。

2:Html.ImageGetter,在请求返回Bitmap的时,对Bitmap的宽度进行判断(bitmap.getWidth()),如果超过最大宽度,则使用最大宽度,同时拿到缩放比率,对高度进行等比处理。

3 填空输入功能看了您的文章还是不太明白,请问您三个关于输入框排版的问题。

1、输入框怎么拿到input位置。

2、输入框怎么刷新位置。

3、输入框怎么与文字对齐居中。

回答:

第一个问题输入框怎么拿到input位置。

1:input我们实际上也是转换成一个图片标签

2:参考http://blog.csdn.net/yellowcath/article/details/27527275如何实现自定义TextView;里面ondraw的时候,判断当前是个imageSpan,并且src是input_A

3:满足2,则判定,该image标签是个输入框标签。如果你仔细看过2步骤的博客;则知道自定义TextView是逐行绘制标签的,我们在绘制的时候,是可以拿到当前的x和y的。

第二个问题输入框怎么刷新位置。

还记得一步骤的src里面的input_A吗?这是我们自定义的标签,第二个标签则是input_B。以此类推

input_A 我们对应创建一个输入框A,放进一个hashMap。

逐行绘制的时候,我们拿到x、y,则更新该输入框的x、y就好了。

第三个问题输入框怎么与文字对齐居中。

参考问题2给出的答案

补充

这个图文混排模块,我在17年的时候就已经完成上线了,最早发布在博客园https://www.cnblogs.com/kimmy/p/5027299.html

到今天3年过去,期间的迭代主要围绕着渲染性能、各种格式文本支持,标签()嵌套扩展性等迭代,主体测量、绘制流程大体上就是文中所述。

安卓原生的Html.fromHtml在处理一些标签的时候,需要额外预处理下比如

*

*

* 将不是html标签的< 替换成< 不然{@link android.text.Html#fromHtml(String)}会丢失,比如下面数据只有a, "a

* 把不是引号里的空格 替换成 不然{@link android.text.Html#fromHtml(String)}会将多个空格合并成一个

* 把不是引号里的\n 替换成
;不然{@link android.text.Html#fromHtml(String)}处理后,课后堂堂清渲染引擎识别不了换行符号

*

* 输入:c( ) \n

* 输出:<b>c<d (   )

android多媒体图文混排,android图文混排相关推荐

  1. Android多媒体学习一:Android中Image的简单实例。

    在多媒体应用中,Image是最基础的功能模块,接下来我们将看看在Android中是如何获取和存储Image的.Android内嵌的Image获取和存储功能,可以让我们对于整个媒体框架有个比较全面的了解 ...

  2. android多媒体编程题库,android 仿猿题库答题UI

    需要做类似猿题库答题板效果,网上没有找到Android的,就自己写一个,浮层上滑底层UI跟着改变的UI public class DragLinearLayoutextends LinearLayou ...

  3. Android多媒体扫描过程(Android Media Scanner Prosess)

    原作者:Steve Gou 转载请注明! 下面是系统图       MediaScannerReceiver会在任何的ACTION_BOOT_COMPLETED, ACTION_MEDIA_MOUNT ...

  4. android多媒体框架学习 详解

    原址 一:多媒体框架概述 jellybean 的多媒体跟以前的版本,通过对比没啥变化,最大的变化是google终于舍得给multimedia建个独立的git了(framework/av),等你好久了! ...

  5. android多媒体框架学习 详解 最新版本

    一:多媒体框架概述 jellybean 的多媒体跟以前的版本,通过对比没啥变化,最大的变化是google终于舍得给multimedia建个独立的git了(framework/av),等你好久了!也体现 ...

  6. Android 多媒体综述

    Android 多媒体综述 多媒体系统是Android中最为庞大的系统,涉及了硬件抽象层.编解码.OpenCore多媒体框架.Android多媒体框架.Java层接口多方面的内容. 一.引言 本系列内 ...

  7. Android多媒体开发

    Android多媒体开发系列文章 Android多媒体开发:录音机 Android多媒体开发:照相机 TextureView+MediaPlayer实现在线短视频播放 Android多媒体开发:第三方 ...

  8. android 点击图片事件,android图文混排点击事件

    图文混排顾名思义就是把文字和图片混合排列在一起,比较简单的需求我们也可以通过TextView和ImageView配合使用来达到目的,但是遇到稍微复杂一些的情况这种方法就不适用了. 做这样一个按钮: 对 ...

  9. css控制图文混排、图文自适应容器显示的效果

    闲来无聊,写了一个css控制图文混排.图文自适应容器显示的效果. 下面js,是鼠标拖动div缩放大小的代码, 跟样式无关,目的是展示自适应效果. 留存参考: <!DOCTYPE html /&g ...

  10. Android 开发之Windows环境下Android Studio安装和使用教程(图文详细步骤)

    鉴于谷歌最新推出的Android Studio备受开发者的推崇,所以也跟着体验一下. 一.介绍Android Studio  Android Studio 是一个Android开发环境,基于Intel ...

最新文章

  1. Resin install document
  2. Java 基础【12】 日期类型
  3. Java高级工程师学习路径
  4. double小数点后最多几位_花了这么多冤枉钱后,我最喜欢这4款医美氨基酸洗面奶...
  5. centos service 无法用
  6. (45)FPGA面试技能提升篇(Hyperlink接口)
  7. C++11 多线程线程共享数据
  8. android RecyclerView实战
  9. 小脚丫 LCMXO2 4000HC FPGA入门——点个灯
  10. tenda无线网卡Linux驱动,腾达Tenda W311MA无线网卡Linux下驱动安装
  11. Android仿微信朋友圈发动态功能(相册图片多选)
  12. office软件不显示图标
  13. 神经网络的三种训练方法,神经网络训练过程详解
  14. 直播美颜SDK代码浅析:直播平台接入美颜SDK是怎样实现美颜的?
  15. 灰度共生矩阵原理+Matlab中实现
  16. 流媒体传输 - HLS 协议
  17. Windows.h和windows.h的区别
  18. Android控件之TextView全解析
  19. 影响人生的五大定律,值得一读
  20. 手写一个基于NIO的迷你版Tomcat

热门文章

  1. 力扣76,最小覆盖字串(JavaScript)
  2. 人生苦短我用python梗_为什么说人生苦短,我用Python?
  3. Linux NGINX 主备,使用keepalived实现主备(以nginx为例)
  4. linux socket编程web服务器实现报文解析,[Socket][网络编程]程序范例:Linux下连接WEB服务器...
  5. mysql 报错1005_MysqlERROR 1005错误处理
  6. c# oldb连接_(转)C#连接OleDBConnection数据库的操作
  7. thunderx 循环获得_湖北专业生产CY310热循环风机厂商
  8. java堆内存_java堆内存详解
  9. C语言运算符优先级和结合性
  10. java基础应用_Java基础(应用篇)