網上有很多圖文混編的方案,無非兩種
- webview
- SpannableString+ImageSpan
他們之間的優勢比較什麼的,網上很多,我也不再贅述,我這裡直接選擇第二種,因為簡單,需求也只是可以插入圖片.然後各種搜尋如何實現,找到一篇博文
我的程式碼就是參考這篇文章來的,因為文章中有些地方使用的api已經被標記為棄用了,所以只好改一下,加點註釋,試圖讓它更加通俗易懂.
那麼先上第一段程式碼
/**
* 圖片上傳到本地磁碟成功
*
* @param path 所在本地磁碟路徑
*/
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) {
}
});
}
複製程式碼
這個方法是我選擇圖片後的回撥, String path
是圖片儲存的路徑,我給放sd卡了.路徑類似於/storage/emulated/0/Android/data/com.xxx.xxx/files/imgs/strategy3121064518359412361.png
這裡選擇用 Glide 載入管理圖片,以防止 OOM ,這裡 Glide 的版本是 4.9.0 ,所以回撥跟 glide3 的不一樣,沒了 .asBitmap 用的是 CustomTarget 回撥.
圖片準備好以後會回撥 onResourceReady ,我們在這裡呼叫image(resource, path);
這個方法是重點,看下一段程式碼
/**
* 把圖片插入到 EditView
* @param resource 圖片資源
* @param path 圖片所在位置 可以是url 也可是本地儲存路徑,我這裡是放在本地了
*/
private void image(Drawable resource, String path) {
String img_str = String.format("![插圖](%s)", path);// 插入markdown格式的插圖
imgReSize(resource);// 縮放圖片的寬度到EditView的寬度
int start = etContent.getSelectionStart();// 獲取當前游標所在位置
// 建立一個SpannableString物件,前後都寫上換行,然後把 img_str 給放進去
SpannableString ss = new SpannableString("\n\n" + img_str + "\n\n");
// 新建 ImageSpan 把圖片傳進去
ImageSpan imageSpan = new ImageSpan(resource);
// 這一行的意思是給SpannableString物件修飾一下,用剛才建立的 ImageSpan 修飾,
// 第二個引數是從那個位置開始,ss 前面有兩個換行符,換行符不要修飾,所以跳過換行符,從下標2開始,
// 換行符雖然寫的\n,但是隻算一個字元.第三個引數之所以要+2是因為前面第二個引數往後挪了兩位,
// 後面也要挪兩位,不要就會把 img_str 的最後兩個字串給丟掉,導致圖片後面會有`g)`這種字串,
// 一般圖片的字尾是 png jpg 所以最後的兩個字就是 g),這兩個字一定要寫 img_str.length() + 2
ss.setSpan(imageSpan, 2, img_str.length() + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// 最後把 SpannableString 物件給插入到我們的EditText中,start就是當前游標所在位置
// 或者說游標最後所在位置
etContent.getEditableText().insert(start, ss);// 設定ss要新增的位置
// 最後更新一下view 請求一下焦點.完事
etContent.requestLayout();
etContent.requestFocus();
}
複製程式碼
這段程式碼的註釋已經說得很清楚了,我也就不再多說,這裡一定要設定 Drawable 的寬高,不然圖片無法顯示,我呼叫了 imgReSize(resource);
來設定 Drawable 物件的寬高為寬度撐滿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; // 計算寬高比例,注意這裡都是用的 double 型別的變數,以防止整除,也就是3/2=1這樣.
double maxHeight = bl * maxWidget; // 通過寬高比例計算圖片高度.
resource.setBounds(0, 0, (int) maxWidget, (int) maxHeight); // 重點程式碼 設定圖片的寬高
}
複製程式碼
好了,這就是插入圖片的所有程式碼了,刪除圖片的話就很簡單,直接按軟鍵盤的刪除鍵就OK.
最後來看看按儲存後列印的文字.
@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);
}
複製程式碼
列印結果
>>> 2019-03-10 11:19:39.139 23523-23523/com.xxx.xxx D/StrategyActivity: onSave: 現在插入一張圖片
![插圖](/storage/emulated/0/Android/data/com.xxx.xxx/files/imgs/strategy150272438965405431.png)
好了,圖片插入完成。
複製程式碼
介面效果