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();
    }


}

猜你喜欢

转载自www.cnblogs.com/819158327fan/p/10773146.html