Android:EditText插入图片实现图文混排

2016年03月17日 Android 1条评论 阅读7345次


Android:多行EditText打造图文混排富文本编辑器


对于插入到富文本编辑框多行EditText的图片而言,什么样的尺寸都有可能出现,或者尺寸很大,或尺寸很小。对于这种情况,出于下面两点考虑,要做相应的优化。

  • 根据用户体验至上的原则,尽量不出现水平方向的滚动条,上下方向滚动条是可以接受的
  • Android设备中很大的图片会出现OOM的异常

所以我们的优化方案就出来了:

  • 如果插入图片的宽度大于EditText控件的宽度,按照EditText控件宽度的80%作为目标宽度,对原图进行压缩
  • 如果插入图片的宽度不大于EditText控件的宽度,则直接插入原图(不进行压缩)

Activity显示时,先获得插入图片的宽度,这里用EditText控件宽度的80%(考虑到两边留一些空白更更好看一些)作为插入图片的目标宽度

点击插入图片按钮时的响应时间

public void add_img(View v) {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    startActivityForResult(intent, PICK_PIC);
} 

从图库选择一张图之后的处理逻辑

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_OK) {
        if (requestCode == PICK_PIC) {
            if (data == null) {
                Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show();
            } else {
                Uri uri = data.getData();
                Bitmap bitmap = getOriginalBitmap(uri);
                SpannableString ss = getBitmapMime(bitmap, uri);
                insertIntoEditText(ss);
            }
        }
    }
} 

其他关联代码

/**
 * EditText中可以接收的图片(要转化为SpannableString)
 * 
 * @param pic
 * @param uri
 * @return SpannableString
 */
private SpannableString getBitmapMime(Bitmap pic, Uri uri) {
    int imgWidth = pic.getWidth();
    int imgHeight = pic.getHeight();
    // 只对大尺寸图片进行下面的压缩,小尺寸图片使用原图
    if (imgWidth >= mInsertedImgWidth) {
        float scale = (float) mInsertedImgWidth / imgWidth;
        Matrix mx = new Matrix();
        mx.setScale(scale, scale);
        pic = Bitmap.createBitmap(pic, 0, 0, imgWidth, imgHeight, mx, true);
    }
    String smile = uri.getPath();
    SpannableString ss = new SpannableString(smile);
    ImageSpan span = new ImageSpan(this, pic);
    ss.setSpan(span, 0, smile.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return ss;
}
private void insertIntoEditText(SpannableString ss) {
    // 先获取Edittext中原有的内容
    Editable et = et_addimage.getText();
    int start = et_addimage.getSelectionStart();
    // 设置ss要添加的位置
    et.insert(start, ss);
    // 把et添加到Edittext中
    et_addimage.setText(et);
    // 设置Edittext光标在最后显示
    et_addimage.setSelection(start + ss.length());
}
private Bitmap getOriginalBitmap(Uri photoUri) {
    if (photoUri == null) {
        return null;
    }
    Bitmap bitmap = null;
    try {
        ContentResolver conReslv = getContentResolver();
        // 得到选择图片的Bitmap对象
        bitmap = MediaStore.Images.Media.getBitmap(conReslv, photoUri);
    } catch (Exception e) {
        Log.e(TAG, "Media.getBitmap failed", e);
    }
    return bitmap;
} 

遇到的一些小问题

得到布局中EditText控件的宽度,使用ViewTreeObserver

ViewTreeObserver vto = et_addimage.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        et_addimage.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        mImgViewWidth = et_addimage.getWidth();
        mInsertedImgWidth = mImgViewWidth * 0.8f;
    }
}); 

多行EditText的默认初始光标不在左上角

因为EditText默认的android:gravity属性值为center,在布局文件中把它改为top就可以了。

android:gravity="top" 

EditText,SpannableString insert-image-to-edittext

分享本文至:

WRITTEN BY

avatar
本文标签:EditText图文混排
看了本文是不是觉得很赞,那就赶紧点击下面按钮分享给身边的朋友吧!

1 条评论

  1. avatar 乐悠游

    有兴趣玩玩,收下这个,谢谢

欢迎留言




用户登录

sitemap