Android使用EditText做图文混排

Android使用EditText做图文混排

安卓图文混排在网络上没有搜索到的丰富的资料,也没有找到合适的demo。之前在做项目的时候有相应的需求,在此做一个总结,并说明其中碰到的坑。

一、 向EditText中添加图片

Editable text = editText.getText();
text.insert(int where, CharSequence text);

以上代码可以用来向EditText中添加实现了CharSequence接口的类的实例,最常见的就是String类,所以,它是可以用来添加文字的,并且使用此方法后,会直接改变EditText中的内容,并且,如果此EditText设置了TextWatcher,TextWatcher中的方法将会被调用。向EditText中添加图片也需要用到此方法。
添加图片还涉及到两个重要的类:SpannableString与ImageSpan。SpannableString实现了CharSequence接口,可以添加到EditText中。并且它添加的文字有多种形式。SpannableString 没有无参构造器,实例化可以使用SpannableString(CharSequence source)。在这里可以传入String字符串,并且,后面插入的图片将会使用这里传入的字符串占位,因此,这里传入的字符串很重要,后面还会用到。另一个类是ImageSpan,也没有无参构造器。这里,只介绍比较简单的一个ImageSpan(Drawable d)。其他的很简单,可以自己了解。显然这个构造器需要传入一个Drawable。Drawable得到的方式比较简单,不详讲。接下来正式插入图片。
在SpannableString中使用setSpan(Object what, int start, int end, int flags)将ImageSpan加入进去。显然第一个参数传ImageSpan,第二个参数传0,第三个传构造器中传入字符串的长度。第四个参数传入Spanned.SPAN_EXCLUSIVE_EXCLUSIVE,第四个参数也有其他选择,但此处不会用到。然后通过Editable.insert()方法加入SpannableString。图片就加入到EditText中了。相关代码如下

public void inertImage(EditText editText, String imgPath) {
        Bitmap imgInfo = BitmapCompressUtil.getBitmap(imgPath);//通过图片地址获取到Bitmap

        //配置 SpannableString
        SpannableString spannableString = new SpannableString(imgPath);
        Drawable drawable = new BitmapDrawable(editText.getContext().getResources(), imgInfo);
        drawable.setBounds(0, 0, imgInfo.getWidth(), imgInfo.getHeight());
        ImageSpan span = new ImageSpan(drawable);
        spannableString.setSpan(span, 0, imgPath.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        Editable text = editText.getText();
        int start = editText.getSelectionStart();//获取光标位置
        text.insert(start, spannableString);//添加图片
    }
至此,图片就加入到了EditText中,接下来进行信息保存。

二、保存图文信息
EditText中能保存下来并且用于上传到服务器的只是一串字符串。如果需要将此图文信息上传到服务器需做以下几件事:

    1. 将刚刚用到的图片上传到服务器,并得到每张图片的地址;
    2. 用 图片的网络地址 替换掉EditText保存下来的字符串中相对应的 图片本地地址;
    3. 将替换过的字符串上传到服务器中

通过以上几步就完成了将图文信息保存到服务器中。

三、恢复图文信息
在恢复图片信息的时候,首先得到的只有一串字符串,可以通过正则表达式将字符串中的图片地址取出,通过图片地址加载图片。在此时,图片地址有可能是本地地址,也可能是网络地址。具体代码比较复杂,在此不贴出来。

四、添加图片时遇到的坑

  • 添加大图图片出现两张
    这里的大图不一定长宽有多大,只是满足一定的条件就会出现。具体是指图片的长或宽大于EditText能占用的的最大长或者高就会出现bug。比如说:EditText长为500px,宽400px,当添加的图片长大于500px或者图片宽大于400px时显示就会出现bug。所以在插入图片时 drawable.setBounds()。其宽高不要大于EditText宽高,也要注意不要让图片拉伸变形。
  • 图在末尾时添加文字文字不输出
    这一个bug在少部分手机上出现,具体表现是在插入图片后,输入文字,当前行不能继续显示文字,只能在下一行显示,但是部分手机上不会显示输入的文字。经过调试后发现,文字输入成功,但是展示的位置不正确。比如:
    插入图片后,图片占位字符为
    {img src=”*.jpg”/}
    此时光标所在的位置在 / 与}之间。输入文字时,占位字符将会变成
    {img src=”*.jpg”/%…………&&}
    其中%…………&&为输入的字符。这种情况下,不论是上传还是恢复都会受影响,具体解决方法是在输入文字之前判断光标是否在图片占位符内部,在的话,将光标向后移动。在插入图片的时候也需要判断
    具体代码这里不方便贴出来,不过大概思路以及会碰到的坑都已经作介绍了。写出具体代码可能会花费时间但肯定是能写出来的
    五、拓展
    这里添加图片使用到了ImageSpan,其实在这里还可设置文字的其他样式,比如:下划线,删除线,斜体,加粗等效果。有时间可以试试。如果只是需要显示表情的话可以参考
    Android 官方兼容库 EmojiCompat Support Library
    如有错误,请指正
    参考资料
    http://www.jianshu.com/p/4e79e20731fe
    http://blog.csdn.net/cike110120/article/details/9106027
    http://chuansong.me/n/20867
    http://www.jianshu.com/p/2a26502db899
发布了9 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/spyunknow/article/details/73824914