Android-textview图文混排(网络图片)

工作太忙,不做过多的解释了,核心是用到了 SpannableStringBuilder  Glide  和 Rxjava

直接上代码了,就两个类。

public class ImageSpanAsyncLoad {

    public ImageSpanAsyncLoad() {

    }

    @SuppressLint("StaticFieldLeak")
public void displayTextAndImage(List<SkuDeliveryBean> skuDelivery, final String title, final TextView textView) { if (TextUtils.isEmpty(title)) {
return;
} final StringBuilder stringBuilder;
if (skuDelivery != null && skuDelivery.size() > 0) {
stringBuilder = new StringBuilder(" " + title);
} else {
stringBuilder = new StringBuilder(title);
}
textView.setText(stringBuilder); // List<String> tagPathList = getProductDelivery(skuDelivery);
if (skuDelivery == null || skuDelivery.size() <= 0) {
return;
} // 创建下载任务
List<Observable<ResultTask>> tempTaskList = new ArrayList<>();
for (int i = 0; i < skuDelivery.size(); i++) {
DownloadTask task = new DownloadTask(i, skuDelivery.get(i).getSkuDeliveryUrl());
task.width = skuDelivery.get(i).getWidth();
task.height = skuDelivery.get(i).getHeight();
tempTaskList.add(createDownaloadTask(task));
stringBuilder.insert(0, " ");
} // 合并任务
Observable.mergeDelayError(tempTaskList)
.subscribeOn(Schedulers.newThread())
.unsubscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResultTask>() { Disposable mD;
List<ResultTask> temp = new ArrayList<>(); @Override
public void onSubscribe(Disposable d) {
mD = d;
} @Override
public void onNext(ResultTask resultTask) {
temp.add(resultTask);
} @Override
public void onError(Throwable e) { } @Override
public void onComplete() {
if (mD != null) {
mD.dispose();
} // 排序
Collections.sort(temp, new Comparator<ResultTask>() {
@Override
public int compare(ResultTask o1, ResultTask o2) {
return o1.position - o2.position;
}
}); // 开始绘制
SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append(stringBuilder.toString());
for (int i = 0; i < temp.size(); i++) {
ResultTask task = temp.get(i);
float radio = (float) SizeUtils.dp2px(task.height) / task.drawable.getIntrinsicHeight();
task.drawable.setBounds(0, 0, (int) (task.drawable.getIntrinsicWidth() * radio), SizeUtils.dp2px(task.height));
CenterAlignImageSpan imageSpan = new CenterAlignImageSpan(task.drawable);
sb.setSpan(imageSpan, i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
textView.setText(sb);
}
}); } // 创建下载任务
private Observable<ResultTask> createDownaloadTask(DownloadTask downloadTask) { Observable<ResultTask> temp; temp = Observable.just(downloadTask)
.observeOn(Schedulers.newThread())
.flatMap(new Function<DownloadTask, ObservableSource<ResultTask>>() {
@Override
public ObservableSource<ResultTask> apply(DownloadTask downloadTask) throws Exception { ResultTask resultTask = new ResultTask();
resultTask.position = downloadTask.position;
resultTask.width = downloadTask.width;
resultTask.height = downloadTask.height; // 下图片
if (downloadTask.drawable != null) {
resultTask.drawable = downloadTask.drawable;
} else {
resultTask.drawable = GlideApp.with(BaseApplication.getInstance())
.asDrawable()
.load(downloadTask.imgUrl)
.submit()
.get();
} return Observable.just(resultTask);
}
}); return temp; } /**
* 设置标签
*
* @param skuDelivery 全球购 次日达 等网络图片
* @param title 标题
* @param textView view
* @param tag 自营非自营等
*/
@SuppressLint("StaticFieldLeak")
public void displayTextAndImage(List<SkuDeliveryBean> skuDelivery, final String title, final TextView textView, final String tag) { if (TextUtils.isEmpty(title)) {
return;
} final StringBuilder stringBuilder;
if (skuDelivery != null && skuDelivery.size() > 0) {
stringBuilder = new StringBuilder(" " + title);
} else {
stringBuilder = new StringBuilder(title);
}
textView.setText(stringBuilder);
// 创建下载任务
List<Observable<ResultTask>> tempTaskList = new ArrayList<>();
int j = 0;
//有标签手动设置drawable
if (!TextUtils.isEmpty(tag)) {
//R.layout.tag是每个标签的布局
View view = LayoutInflater.from(textView.getContext()).inflate(R.layout.tag, null);
TextView tv_tag = view.findViewById(R.id.tv_tag);
tv_tag.setText(tag);
view.setDrawingCacheEnabled(true);
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap bitmap = ConvertUtils.view2Bitmap(view);
Drawable drawable = ConvertUtils.bitmap2Drawable(bitmap);
tempTaskList.add(createDownaloadTask(new DownloadTask(0, drawable)));
stringBuilder.insert(j, " ");
j = j + 1;
view.destroyDrawingCache();
} List<String> tagPathList = getProductDelivery(skuDelivery);
if (tagPathList != null && tagPathList.size() > 0) {
for (int i = 0; i < tagPathList.size(); i++) {
if (TextUtils.isEmpty(tagPathList.get(i))) {
continue;
}
tempTaskList.add(createDownaloadTask(new DownloadTask(i + 1, tagPathList.get(i))));
stringBuilder.insert(j, " ");
}
} if (tempTaskList.size() <= 0) {
return;
}
// 合并任务
Observable.mergeDelayError(tempTaskList)
.subscribeOn(Schedulers.newThread())
.unsubscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResultTask>() { Disposable mD;
List<ResultTask> temp = new ArrayList<>(); @Override
public void onSubscribe(Disposable d) {
mD = d;
} @Override
public void onNext(ResultTask resultTask) {
temp.add(resultTask);
} @Override
public void onError(Throwable e) { } @Override
public void onComplete() {
if (mD != null) {
mD.dispose();
} // 排序
Collections.sort(temp, new Comparator<ResultTask>() {
@Override
public int compare(ResultTask o1, ResultTask o2) {
return o1.position - o2.position;
}
}); // 开始绘制
SpannableStringBuilder sb = new SpannableStringBuilder();
sb.append(stringBuilder.toString());
for (int i = 0; i < temp.size(); i++) {
ResultTask task = temp.get(i);
float dpValue = 24;
if (!TextUtils.isEmpty(tag) && i == 0) {
dpValue = 16;
}
float radio = (float) SizeUtils.dp2px(dpValue) / task.drawable.getIntrinsicHeight();
task.drawable.setBounds(0, 0, (int) (task.drawable.getIntrinsicWidth() * radio), SizeUtils.dp2px(dpValue));
CenterAlignImageSpan imageSpan = new CenterAlignImageSpan(task.drawable);
sb.setSpan(imageSpan, i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
textView.setText(sb);
}
}); } // 下载任务类
private static class DownloadTask {
private int position;
private String imgUrl;
private int width;
private int height;
private Drawable drawable; public DownloadTask(int position, String imgUrl) {
this.position = position;
this.imgUrl = imgUrl;
} public DownloadTask(int position, Drawable drawable) {
this.position = position;
this.drawable = drawable;
}
} // 承载任务的类
private static class ResultTask {
private int position;
private Drawable drawable;
private int width;
private int height;
} /**
* 转化标签
*/
private List<String> getProductDelivery(List<SkuDeliveryBean> skuDelivery) {
List<String> temp = new ArrayList<>();
if (skuDelivery != null) {
for (SkuDeliveryBean bean : skuDelivery) {
if (bean == null) {
continue;
}
temp.add(bean.getSkuDeliveryUrl());
}
}
return temp;
}
}

ImageSpan

public class CenterAlignImageSpan extends ImageSpan {

    public CenterAlignImageSpan(Drawable drawable) {
super(drawable);
} @Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
Drawable d = getDrawable();
Rect rect = d.getBounds();
if (fm != null) {
Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
int fontHeight = fmPaint.bottom - fmPaint.top;
int drHeight = rect.bottom - rect.top; int top = drHeight / 2 - fontHeight / 4;
int bottom = drHeight / 2 + fontHeight / 4; fm.ascent = -bottom;
fm.top = -bottom;
fm.bottom = top;
fm.descent = top;
}
return rect.right;
} @Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
Drawable b = getDrawable();
canvas.save();
int transY = 0;
transY = ((bottom - top) - b.getBounds().bottom) / 2 + top;
canvas.translate(x, transY);
b.draw(canvas);
canvas.restore();
} }
上一篇:acmer之ubuntu下安装Eclipse


下一篇:【Robot Framework 介绍】总纲