Android 纯原生 图文混排 心得

好久没有上号   今天写一下  纯原生图文混排心得

    最近的项目里需要展示图文混排的格式,因为一些特殊原因需要纯原生操作。众所周知,图文混排我们可以使用Html.fromHtml(source, imageGetter, tagHandler)通过自定义imageGetter来异步加载图片 最终展示在TextView上,最后完成图文混排。但是这样做的话对于图片段落之间的距离相对来说不好把控展示的样式也不精美。

    这篇文章说讲述的方法有一些局限性,但是看客可以通过简单的修改适配自己的项目(主要是和后台,ios 商量好返回的格式)。下面是文本的格式,每一段文字和图片都放在一组p标签里,图片和文字不能在同一组中出现,这个格式可以直接通过word转html生成比较简单(分段直接用回车)。

<p>1、给狗狗吃早餐时,你应该根据它的食量将食物分成两份,如果它一天要吃两顿晚餐也要同样这么处理。</p>

<p><img alt="" src="http://pic.ibreed.com.cn/admin/pic/201711/00300d5ad326a1dcff78d598002b267c.jpg" style="width: 1053px;" /></p>

<p>2、先给它一半的食物。</p>

<p><img alt="" src="http://pic.ibreed.com.cn/admin/pic/201711/97098cb9842ce61a009d3cc9a2342cf7.jpg" style="width: 1053px;" /></p>

<p>3、如果它很快地吃完了你给的那一半食物,那么将另外一半也给它。</p>

<p><img alt="" src="http://pic.ibreed.com.cn/admin/pic/201711/4d58ce033d3e546e747f39fc49ec6754.jpg" style="width: 1053px;" /></p>

<p>4、20分钟之后,将狗狗还没有吃完的食物拿走并且扔掉,在下一次喂食之前不要再给它任何食物吃,包括任何奖赏。当然,你起码应该提供充足的、清洁的水给它饮用。</p>

<p><img alt="" src="http://pic.ibreed.com.cn/admin/pic/201711/a84ec2bb94457351ad5d503a7c69bf4b.jpg" style="width: 1053px;" /></p>



这个是最后成品的样子大笑大笑大笑大笑大笑大笑大笑

首先整个区域都是由一个RecyclerView构成的分为四个区域 其中0是重点  应为推荐必定是3个  所以我下面的if直接判断了 太懒了

private static final int TYPE_ITEM = 0; //内容
private static final int TYPE_HEAD = 2;//头
private static final int TYPE_BOTTOM = 1;//尾部
private static final int TYPE_RECOMMEND = 3;//推荐

@Override public int getItemCount() {
     return 3 + feedDeletailsListBean.size(); 
}

@Override public int getItemViewType(int position) { 
    if (position == 0) {
         return TYPE_HEAD;
     } else if (position == 5) {
         return TYPE_RECOMMEND; 
    } else if (position == 4) {
         return TYPE_RECOMMEND; 
    } else if (position == 3) {
         return TYPE_RECOMMEND; 
    } else if (position == 2) {
         return TYPE_BOTTOM; 
    } else if (position == 1) {
         return TYPE_ITEM;
     } else {
         return TYPE_BOTTOM; 
    } 
}

TPYE_ITEM就是我们的图文混排区域 布局仅有一个LinearLayout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/ll_textImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="12dp"
        android:paddingRight="12dp" />
</LinearLayout>

1.替换使用的标签 ,  删除多余的标签


String s = text.replaceAll("</p>", "")
                    .replaceAll("\r", "")
                    .replaceAll("\n", "")
                    .replaceAll("<br />", "\n")
                    .replaceAll("”", "\"")
                    .replaceAll("“", "\"")
                    .replaceAll("—", "—")
                    .replaceAll("—", "—")
                    .replaceAll("…", "…")
                    .replaceAll(" ", " ")
                    .replaceAll("·", ".")
                    .replaceAll("<ul>", "")
                    .replaceAll("</li>", "")
                    .replaceAll("</ul>", "")
                    .replaceAll("<li>", "\n•  ");

2.使用<p>来进行截取生成一个由图片路径和段落组成的数组并且动态在LinearLayout中添加布局  动态添加的过程中我们可以自定义布局的排列

String[] split = s.split("<p>");
            for (int x = 0; x < split.length; x++) {
                String str = split[x];
                if (x == 0) {
                    continue;
                }
                if (str.indexOf("img") == -1) {
                    TextView textView = new TextView(mContext);
                    if (str.indexOf("strong") != -1) {
                        TextPaint tp = textView.getPaint();
                        tp.setFakeBoldText(true);
                        str = str.replaceAll("</strong>", "").replaceAll("<strong>", "");
                    }
                    textView.setText(str);
                    textView.setTextColor(mContext.getResources().getColor(R.color.item_text_color1));
                    textView.setTextSize(14);
                    textView.setLineSpacing(0, 1.5f);
                    textView.setPadding(0, DensityUtils.dip2px(mContext, 20), 0, 0);
                    item.llTextImage.addView(textView);
                } else {
                    final ImageView imageView = new ImageView(mContext);
                    item.llTextImage.addView(imageView);
                    final String finalStr = str;
                    Glide.with(mContext).load(Uri.parse(H5TextUtils.getImgStrs(str))).asBitmap().into(new SimpleTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
                            if (resource != null) {
                                int x = ScreenUtils.screen_width - DensityUtils.dip2px(mContext, 24);
                                int i = (resource.getHeight()) * x / (resource.getWidth());
                                Glide.with(mContext).load(Uri.parse(H5TextUtils.getImgStrs(finalStr))).into(imageView);
                                LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) imageView.getLayoutParams();
                                params.setMargins(0, DensityUtils.dip2px(mContext, 10), 0, 0);
                                params.width = x;
                                params.height = i;
                                imageView.setLayoutParams(params);
                            }
                        }
                    });
                }
            }

    这样的话一个Android 操作的图文混排就完成了 其中也可以不替换多余的H5标签  毕竟标签很多 替换起来也很麻烦,如果仅仅是调整图片和文本的距离的话可以不管一些标点 比如所引号,我们只需要把H5的内容通过android.text.Html.fromHtml()转化成 Spanned 的格式传递给TextView就可以实现了。但是这种方法的局限性也比较大——Android 并没有支持全部的H5标签。

    总结:    

        对于项目来说,如果没有特定的需求的话最好还是通过H5+webView来实现这种页面.必要的情况下根据自己项目的需求来分析是使用TextView加标签来实现还是纯原生替换标签来实现。
发布了64 篇原创文章 · 获赞 10 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 像素格子 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览