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();
        }
    
    
    }
  • 相关阅读:
    获取设备和 App 信息
    使用 UICollectionView 实现网格化视图效果
    UIImage 读取图片内存优化
    使用 stretchableImageWithLeftCapWidth 方法实现可伸缩图片
    使用 StoryBoard 实现左右按钮切换图片的浏览效果
    二维码图片生成(扩展知识:创建带圆角效果的图片)
    Objective-C语法之扩展(Extension)的使用
    Objective-C语法之字符串NSString去掉前后空格或回车符(可以是NSCharacterSet类型的其它字符)
    Objective-C语法之可变参数
    什么时候layoutSubview会被调用
  • 原文地址:https://www.cnblogs.com/819158327fan/p/10773146.html
Copyright © 2011-2022 走看看