zoukankan      html  css  js  c++  java
  • 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();
        }
    
    
    }
  • 相关阅读:
    ZOJ 3818 Pretty Poem
    HDU 4597 Play Game
    HDU 4497 GCD and LCM
    CSU 1335 高桥和低桥
    UVA 10791 Minimum Sum LCM
    CSU 1119 Collecting Coins
    CSU 1120 病毒
    UVA 12169 Disgruntled Judge
    HDU 1301 Jungle Roads
    POJ 1258 Agri-Net
  • 原文地址:https://www.cnblogs.com/819158327fan/p/10773146.html
Copyright © 2011-2022 走看看