仿小米便签图文混排 EditText解决尾部插入文字bug
一直想实现像小米便签那样的图文混排效果,收集网上的办法无非三种:
1、自定义布局,每张图片是一个ImageView,插入图片后插入EditText,缺点是实现复杂,不能像小米便签那样同时选中图片和文字
2、通过Html.fromHtml(source),可以将图片加载写进ImageGetter,实现后无bug,但是只能显示Html,当EditText setText后,想取出之前的HTML格式
图片得到的是一个obj的字符,查看了很多博客,包括stackoverflow也没给出办法从editable中解析出spanned对象。若谁有方法希望不吝啬告诉我。
3、通过ImageSpan和SpannableString,这是我实现的方法,而且较为理想,不但可以写入EditText,也可以从EditText中解析出图文混排排版。
1、插入图片到光标位置
/**
* 将图片路径映射到Bitmap,再通过SpannableString 和 ImageSpan显示到EditText
*/
private void setImageView() {
// 如果EditText中已经有相同资源的ImageSpan,则不再读取图片
ImageSpan imageSpan = getImageSpanFromExistence(imagePath);
if (imageSpan != null) {
insertIntoEditor(imageSpan, imagePath);
return;
} if (imagePath != null && (!imagePath.equals("null"))
&& (!"".equals(imagePath))) {
insertIntoEditor(imagePath);
/*
* 不再用缓存模式
*/
}
} /**
* 从当前的EditText获取ImageSpan,如果存在则返回否则返回Null
*
* @return
*/
private ImageSpan getImageSpanFromExistence(String source) {
Editable edit = contentText.getText();
ImageSpan[] spans = edit.getSpans(, edit.length(), ImageSpan.class);
for (ImageSpan ip : spans) {
int start = edit.getSpanStart(ip);
int end = edit.getSpanEnd(ip);
String path = edit.toString().substring(start, end);
path = path.substring(, path.length() - ); if (source.equals(path)) {
Logg.D("find existed ImageSpan");
return new ImageSpan(ip.getDrawable(), ImageSpan.ALIGN_BASELINE);
}
}
return null;
} /**
* 向光标位置插入ImageSpan,针对EditText已经有ImageSpan的情况
*
* @param ip
* ImageSpan
* @param path
* 路径
*/
private void insertIntoEditor(ImageSpan span, String path) {
if(("<img " + path + " img>").length()+contentText.getText().length() > MAX_CONTENT){
Toast.makeText(getApplicationContext(), R.string.toast_reached_max_text, ).show();
return;
}
SpannableString ss = new SpannableString("<img " + path + " img>");
if (span == null)
throw new NullPointerException("span cant be null");
ss.setSpan(span, , ("<img " + path + " img>").length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Editable et = contentText.getText();// 先获取Edittext中的内容
int start = contentText.getSelectionStart();
et.insert(start, ss);// 设置ss要添加的位置
contentText.setSelection(start + ss.length());// 设置Edittext中光标在最后面显示
Logg.D("insertIntoEditor by using existed ImageSpan");
} /**
* 向光标位置插入ImageSpan,针对EditText没有图片的情况
*
* @param path
* 图片路径
*/
private void insertIntoEditor(String path) {
if(("<img " + path + " img>").length()+contentText.getText().length() > MAX_CONTENT){
Toast.makeText(getApplicationContext(), R.string.toast_reached_max_text, ).show();
return;
}
SpannableString ss = new SpannableString("<img " + path + " img>");
// 不再用缓存模式
// Bitmap bm = mEditorHelper.getImage(path);
Bitmap bm = PictureHelper.getImageFromPath(imagePath,
screenWidth * 0.7F, screenWidth * 0.7F, false, ,
Editor.this, imgPadding, false);
if (bm == null) {
throw new NullPointerException("bm cant be null");
} ImageSpan span = new ImageSpan(this, bm, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, , ("<img " + path + " img>").length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
Editable et = contentText.getText();// 先获取Edittext中的内容
int start = contentText.getSelectionStart();
et.insert(start, ss);// 插入图片到光标处
// contentText.setSelection(start + ss.length());// 设置Edittext中光标在最后面显示
Logg.D("insertIntoEditor by loading new");
}
以上插入图片前会查找edittext有没有相同地址的ImageSpan,如果有则不再读取新的Bitmap,直接复用drawable
2、解决尾部插入Bug\
Bug来源:http://www.baidufe.com/item/65fd7eba51123bbe80bc.html
一直没能理解作者说的半角站位
我实现了一个方法,当光标到达图片末尾,直接跳转至正确位置
实现:http://mxw3755.iteye.com/admin/blogs/2164905
当光标嵌入spannableString的字符从末尾前一位,我们可以将光标位置+1,这样光标会在两张图之间
3、如何保存解析图文混排的EditText
可以将ImageSpan的位置保存到Arraylist中,怎么保存至数据库请参考 http://mxw3755.iteye.com/admin/blogs/2165147
android 图文结合,使用SpannableString和ImageSpan类
Drawable drawable = getResources().getDrawable(id);
drawable.setBounds(, , drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
//需要处理的文本,[smile]是需要被替代的文本
SpannableString spannable = new SpannableString(getText().toString()+"[smile]");
//要让图片替代指定的文字就要用ImageSpan
ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
//开始替换,注意第2和第3个参数表示从哪里开始替换到哪里替换结束(start和end)
//最后一个参数类似数学中的集合,[5,12)表示从5到12,包括5但不包括12
spannable.setSpan(span, getText().length(),getText().length()+"[smile]".length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
setText(spannable);
仿小米便签图文混排 EditText解决尾部插入文字bug的更多相关文章
- 使用android SpannableStringBuilder实现图文混排
项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的 ...
- CoreText实现图文混排
CoreText的介绍 Core Text 是基于 iOS 3.2+ 和 OSX 10.5+ 的一种能够对文本格式和文本布局进行精细控制的文本引擎.它良好的结合了 UIKit 和 Core Graph ...
- EditText图文混排
下面就具体说一下我遇到的问题,首先是EditText里面的图文混排问题,这个问题的难点就是三点: 1.怎么插图片 2.怎么保存插入的图片和文字 3.怎么解析回图片和文字 解决: 一.怎么插入图片 在这 ...
- 仿QQ聊天图文混排流程图【适用于XMPP】
图文混排流程图.graffle4.8 KB 下面附上图片素材: 表情.zip692.5 KB 下面是字符串与图片的详细对应关系: "[呲牙]& ...
- Android图文混排-实现EditText图文混合插入上传
前段时间做了一个Android会议管理系统,项目需求涉及到EditText的图文混排,如图: 在上图的"会议详情"中.须要支持文本和图片的混合插入,下图演示输入的演示样例: 当会议 ...
- 用NSAttributedString实现简单的图文混排
iOS7以后,因为TextKit的强大,可以用NSAttributedString很方便的实现图文混排(主要是利用了NSTextAttachment). 关于Textkit的牛逼之处,可以参考objc ...
- DIV+CSS 图文混排的图片居中办法
不少人为了让 Div 图文混排的图片可以居中,给 IMG 套各式各样的 SPAN.DIV.LI 等等,以便于使用 text-align来进行居中. <div>图文混排 <br> ...
- CoreText 实现图文混排
CoreText 实现图文混排 相关博文推荐 IOS CoreText.framework - 基本用法 IOS CoreText.framework - 段落样子CTParagraphStyle h ...
- 简单的Coretext 图文混排
在很多新闻类或有文字展示的应用中现在都会出现图文混排的界面例如网易新闻等,乍一看去相似一个网页,其实这样效果并非由UIWebView 加载网页实现.现在分享一种比较简单的实现方式 iOS sdk中为我 ...
随机推荐
- .NET中的async和await关键字使用及Task异步调用实例
其实早在.NET 4.5的时候M$就在.NET中引入了async和await关键字(VB为Async和Await)来简化异步调用的编程模式.我也早就体验过了,现在写一篇日志来记录一下顺便凑日志数量(以 ...
- 没事用html5 canvas画一个仪表盘自用,自适应的哦
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Java程序员的面试经历和题库
最近打算换城市了,受不了北京的雾霾了,所以准备逃离啦.所以一直在面试中,整理了下最近遇到的一些面试题,供大家参考.其中会包含一些面试的小经验,如果您是面霸,希望能给予指导.自己不是大牛,如果您是大牛, ...
- Hibernate核心开发接口_SessionFactory详解
SessionFactory: a) 用来产生和管理Session b)通常情况下每个应用只需要一个SessionFactory c)除非要访问多个数据库的情况 d) 关注两个方法即: openS ...
- mp3转speex的一些研究(貌似不能播放,暂存着)
思路是,先从mp3中提取pcm(raw原始数据),再将原始数据转成speex. 貌似不能播放,可能还存在其他问题,需要继续研究. 使用了两个类库NSpeex和NAudio using (var wav ...
- fgets()函数读取键盘,去掉换行符或丢弃多余的字符
在上一遍随笔中,我们知道可以用fgets()函数来代替不安全的gets()函数.fgets函数中的第二个参数限制了读取的个数. 上篇文章也提到,fgets是会读取回车换行符的.有时候我们并不希望在字符 ...
- Android Studio 和 gradle 修改缓存文件夹路径
Android Studio的缓存文件主要有四个文件夹,分别是 .android 这个文件夹是Android SDK生成的AVD(Android Virtual Device Manager)即模拟器 ...
- ibatis插入正确但查询不出数据的问题
现在,使用打印的sql在oracle数据库客户端能查询出结果,但执行ibatis查询语句不行,ibatis插入可以. 解决问题的历程: 1. 去掉sql中的where语句,仍然查找不到,确定不是sql ...
- 【LeetCode题解】7_反转整数
目录 [LeetCode题解]7_反转整数 描述 方法一 思路 Java 实现 类似的 Java 实现 Python 实现 方法二:转化为求字符串的倒序 Java 实现 Python 实现 [Leet ...
- (三)JNI常用示例
针对我之前文章的练习:JNI方法总结 1. 字符串 JAVA层: test.testString("HELLOWORLD"); JNI层: JNIEXPORT jstring JN ...