網(wǎng)上有很多圖文混編的方案,無(wú)非兩種
- webview
- SpannableString+ImageSpan
他們之間的優(yōu)勢(shì)比較什么的,網(wǎng)上很多,我也不再贅述,我這里直接選擇第二種,因?yàn)楹?jiǎn)單,需求也只是可以插入圖片.然后各種搜索如何實(shí)現(xiàn),找到一篇博文
https://blog.csdn.net/ljzdyh/article/details/82497625
我的代碼就是參考這篇文章來(lái)的,因?yàn)槲恼轮杏行┑胤绞褂玫腶pi已經(jīng)被標(biāo)記為棄用了,所以只好改一下,加點(diǎn)注釋,試圖讓它更加通俗易懂.
那么先上第一段代碼
/**
* 圖片上傳到本地磁盤(pán)成功
*
* @param path 所在本地磁盤(pán)路徑
*/
private void imgUploadSuccess(final String path) {
Glide.with(this)
.load(path)
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
image(resource, path);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
這個(gè)方法是我選擇圖片后的回調(diào), String path是圖片儲(chǔ)存的路徑,我給放sd卡了.路徑類(lèi)似于/storage/emulated/0/Android/data/com.xxx.xxx/files/imgs/strategy3121064518359412361.png
這里選擇用 Glide 加載管理圖片,以防止 OOM ,這里 Glide 的版本是 4.9.0 ,所以回調(diào)跟 glide3 的不一樣,沒(méi)了 .asBitmap 用的是 CustomTarget 回調(diào).
圖片準(zhǔn)備好以后會(huì)回調(diào) onResourceReady ,我們?cè)谶@里調(diào)用image(resource, path);
這個(gè)方法是重點(diǎn),看下一段代碼
/**
* 把圖片插入到 EditView
* @param resource 圖片資源
* @param path 圖片所在位置 可以是url 也可是本地儲(chǔ)存路徑,我這里是放在本地了
*/
private void image(Drawable resource, String path) {
String img_str = String.format("", path);// 插入markdown格式的插圖
imgReSize(resource);// 縮放圖片的寬度到EditView的寬度
int start = etContent.getSelectionStart();// 獲取當(dāng)前光標(biāo)所在位置
// 創(chuàng)建一個(gè)SpannableString對(duì)象,前后都寫(xiě)上換行,然后把 img_str 給放進(jìn)去
SpannableString ss = new SpannableString("\n\n" + img_str + "\n\n");
// 新建 ImageSpan 把圖片傳進(jìn)去
ImageSpan imageSpan = new ImageSpan(resource);
// 這一行的意思是給SpannableString對(duì)象修飾一下,用剛才創(chuàng)建的 ImageSpan 修飾,
// 第二個(gè)參數(shù)是從那個(gè)位置開(kāi)始,ss 前面有兩個(gè)換行符,換行符不要修飾,所以跳過(guò)換行符,從下標(biāo)2開(kāi)始,
// 換行符雖然寫(xiě)的\n,但是只算一個(gè)字符.第三個(gè)參數(shù)之所以要+2是因?yàn)榍懊娴诙€(gè)參數(shù)往后挪了兩位,
// 后面也要挪兩位,不要就會(huì)把 img_str 的最后兩個(gè)字符串給丟掉,導(dǎo)致圖片后面會(huì)有`g)`這種字符串,
// 一般圖片的后綴是 png jpg 所以最后的兩個(gè)字就是 g),這兩個(gè)字一定要寫(xiě) img_str.length() + 2
ss.setSpan(imageSpan, 2, img_str.length() + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 最后把 SpannableString 對(duì)象給插入到我們的EditText中,start就是當(dāng)前光標(biāo)所在位置
// 或者說(shuō)光標(biāo)最后所在位置
etContent.getEditableText().insert(start, ss);// 設(shè)置ss要添加的位置
// 最后更新一下view 請(qǐng)求一下焦點(diǎn).完事
etContent.requestLayout();
etContent.requestFocus();
}
這段代碼的注釋已經(jīng)說(shuō)得很清楚了,我也就不再多說(shuō),這里一定要設(shè)置 Drawable 的寬高,不然圖片無(wú)法顯示,我調(diào)用了 imgReSize(resource); 來(lái)設(shè)置 Drawable 對(duì)象的寬高為寬度撐滿(mǎn)EditView容器,然后寬高等比例縮放.下面看看 imgReSize 方法的定義
/**
* 縮放圖片的寬度到EditView的寬度
*
* @param resource 圖片
*/
void imgReSize(Drawable resource) {
double maxWidget = etContent.getMeasuredWidth() - etContent.getPaddingLeft() - etContent.getPaddingRight();//獲取 EditView 的寬度
double widget = resource.getIntrinsicWidth();// 獲取資源的固定寬度
double height = resource.getIntrinsicHeight();// 獲取資源的固定高度
double bl = height / widget; // 計(jì)算寬高比例,注意這里都是用的 double 類(lèi)型的變量,以防止整除,也就是3/2=1這樣.
double maxHeight = bl * maxWidget; // 通過(guò)寬高比例計(jì)算圖片高度.
resource.setBounds(0, 0, (int) maxWidget, (int) maxHeight); // 重點(diǎn)代碼 設(shè)置圖片的寬高
}
好了,這就是插入圖片的所有代碼了,刪除圖片的話(huà)就很簡(jiǎn)單,直接按軟鍵盤(pán)的刪除鍵就OK.
最后來(lái)看看按保存后打印的文本.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_img:
selectImgTool.selectImg();
break;
case R.id.menu_release:
Log.d(TAG, "onSave: " + etContent.getText().toString());
break;
}
return super.onOptionsItemSelected(item);
}
打印結(jié)果
>>> 2019-03-10 11:19:39.139 23523-23523/com.xxx.xxx D/StrategyActivity: onSave: 現(xiàn)在插入一張圖片

好了,圖片插入完成。
界面效果
