最近公司的项目中要求用户可以在移动端编辑图文混排,以前没有弄过这方面的东东,所以一方面记录一下开发历程,一方面秉着分享的精神写出来希望对看到这篇文章的人一点帮助。
先上效果图
搜索了一下网上的解决方案我这里找到了两个:
1.采用SpannableString和ImageSpan两个类来实现这一功能。
2,.采用通过html的<img
>标签的方式插入到edittext中去。
这里我选择的是第一种,第二种方式我不知道如何从edittext对象中取出img标签对应的路径。
现在直接上代码:
private void appendImage(String imgUrl) {
// 用imgUrl获取Bitmap对象
Bitmap bitmap = ImageLoader.getInstance().loadImageSync(
"file://" + imgUrl);
// 将Bitmap对象转换成Drawable对象
Resources res = getApplicationContext().getResources();
Drawable drawable = new BitmapDrawable(res, bitmap);
// 用imgUrl初始化SpannableString对象
msp = new SpannableString(imgUrl);
// 设置图片宽高
drawable.setBounds(0, 0, 600, 800);
msp.setSpan(new ImageSpan(drawable), 0, imgUrl.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 获取Editable的对象
Editable edit = editText.getEditableText();
// 获取光标位置
int index = editText.getSelectionStart();
// 光标所在位置插入文字
edit.insert(index, msp);
Log.i("图文混排",editText.getText().toString());
}
这个代码非常简单了,可以分成两部分来看。
第一部分:因为我们移动端编辑图文,图片肯定来自本地文件,我们根据这个路径将其最终转换成Drawable对象,这里我采用的是
ImageLoader框架直接获取到Bitmap对象然后转换成Drawable对象,大家根据自己项目,换成相应的取得Bitmap对象的方法即可。
第二部分:初始化SpannableString对象。
msp = new SpannableString(imgUrl);
这里的参数很重要,为什么这么说呢,我们以开头的效果图为例,通过结尾的Log打印下:
随便写写字/storage/emulated/thumbnails/1448764326621.jpg啊啊
我们发现editText.getText().toString()打印的内容文字部分还是文字,但是图片部分就是SpannableString对象的参数,因为我们移动端编辑完图文肯定是要发布的,这时候我们就需要上传这些图片,那么因为内容中包换路径我们就能想写办法获取路径。
我就是在这个地方卡住了,一开始随便用了个“image”这样的字符串创建的对象,然后后期我发现我不知道从哪里拿到图片的原始路径。
剩下的看代码注释就可以知道我们将图片放入了光标位置。
接下来自然是与服务器的交互了,这里我们要想办法从editText.getText().toString()中取出我们所有加入的图片的路径。
还是上代码:
//从EditText中获取图片所对应的路径
private ArrayList<String> getImagePath() {
Editable edit = editText.getText();
String path = null;
ArrayList<String> pathArr = new ArrayList<String>();
ImageSpan[] spans = edit.getSpans(0, edit.length(), ImageSpan.class);
for (ImageSpan ip : spans) {
int start = edit.getSpanStart(ip);
int end = edit.getSpanEnd(ip);
path = edit.toString().substring(start, end);
path = path.substring(0, path.length());
pathArr.add(path);
}
return pathArr;
}
这个是我从“仿小米便签图文混排 EditText解决尾部插入文字bug”中提出的方法也感谢原作者。大家如果想看可以百度搜下这个内容。
就是这样一个方法我们就拿到了路径的集合,然后大家调用自己项目中的上传方法将图片上传到服务器吧!
接下来我们用上传成功后得到的网络路径替换原本editText中的本地路径
/**
* 用网络路径替换本地路径
* @param urls 上传图片后得到的网络路径集合
* @return editText 替换后的文本内容(用于最终上传)
*/
public String getEditText(ArrayList<String> urls) {
Editable edit = editText.getText();
String cont = edit.toString();
ImageSpan[] spans = edit.getSpans(0,edit.length(),
ImageSpan.class);
int size = spans.length;
for (int i = 0; i < size ; i++) {
int start = edit.getSpanStart(spans[i]);
int end = edit.getSpanEnd(spans[i]);
String path = edit.toString().substring(start, end);
cont = cont.replace(path, urls.get(i));
}
editText.setText(cont);
return cont;
}
这样我们就拿到了替换后的editText中的文本内容,这也就是最终我们需要上传的内容!