美文网首页
Android中的富文本

Android中的富文本

作者: townof1997 | 来源:发表于2019-07-17 16:00 被阅读0次

    Android开发在与后台对接的时候,有时会返回HTML5格式的数据,需要解析<p><p/><image></image>标签,比如如下返回数据:

            <p style="margin: 0pt;"></p>
            <p style="margin: 0pt;"></p>
            <p style="margin: 0pt;">
                <span style='color: rgb(0, 0, 0); font-family: 宋体; font-size: 12pt; mso-spacerun: "yes"; mso-font-kerning: 1.0000pt;'><font face="宋体">领导者的综合影响力主要来源于()<span style='font-family: 宋体; font-size: 12pt; font-weight: normal; mso-spacerun: "yes"; mso-font-kerning: 1.0000pt;'><font face="宋体">。</font></span></font></span>
            </p>
            <p>
                <br>
            </p>
    

    还有带网络图片的图片的,如:


    Android_image_influter.png

    我们就需要用到富文本来解析了,具体使用如下:
    将html代码转换为text,然后显示在textview中呢,有一个简单直接的方法:

    textView.setText(Html.fromHtml(content));
    

    用的时候却发现html里面的图片没法被被解析出来,对于图片Html还有一个方法:

    public static Spanned fromHtml(String source, ImageGetter imageGetter,TagHandler tagHandler)
    

    这里面需要我们自定义imageGetter,这个对象是用于解析html中的图片.

    public class MImageGetter implements Html.ImageGetter {
        private Context c;
        private TextView container;
    
        public MImageGetter(TextView text, Context c) {
            this.c = c;
            this.container = text;
        }
    
        @Override
        public Drawable getDrawable(String source) {
            Drawable drawable = null;
            InputStream is = null;
            //source便是图片的路径,如果图片在本地,可以这样做        
            is = c.getResources().getAssets().open(source);
    try {
                TypedValue typedValue = new TypedValue();
                typedValue.density = TypedValue.DENSITY_DEFAULT;
                drawable = Drawable.createFromResourceStream(null, typedValue, is, "src");
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                                   drawable.getIntrinsicHeight());
                return drawable;
            } catch (Exception e) {
                System.out.println(e);
                return null;
            }
        }
    

    最终这样调用:

    textView.setText(Html.fromHtml(text, new MImageGetter(textView, this), null));
    

    这样便可以实现图文混排了,在该显示图片的地方显示图片。
    如果是要显示网络上的图片,getDrawable方法可以这样

    public Drawable getDrawable(String source) {
             final LevelListDrawable drawable = new LevelListDrawable();
             Glide.with(c).load(source).asBitmap().into(new SimpleTarget<Bitmap>() {
                 @Override
                 public void onResourceReady(Bitmap resource,  
                          GlideAnimation<? super Bitmap> glideAnimation) {
                     if(resource != null) {
                         BitmapDrawable bitmapDrawable = new BitmapDrawable(resource);
                         drawable.addLevel(1, 1, bitmapDrawable);
                         drawable.setBounds(0, 0, resource.getWidth(),resource.getHeight());
                         drawable.setLevel(1);
                         container.invalidate();
                         container.setText(container.getText());
                     }
                 }
             });
             return drawable;
            }
    

    第三个参数 其作用是把 HTML 带标记的文本内容字符串转化成可以显示效果的Spanned 字符串 。由于并非所有的 HTML 标签都可以转化,所以在使用时,用户需要自己添加一些必要的标签和处理方法时才会使用的.
    对于Android中有些还要求具有点击事件的功能,就需要自定义个 LinkMovementMethodExt类,那么代码如下:

    public class LinkMovementMethodExt extends LinkMovementMethod {
        private static LinkMovementMethod sInstance;
        private  Handler handler = null;
        private  Class spanClass = null;
        
        public static  MovementMethod getInstance(Handler _handler,Class _spanClass) {
            if (sInstance == null) {
                sInstance = new LinkMovementMethodExt();
                ((LinkMovementMethodExt)sInstance).handler = _handler;
                ((LinkMovementMethodExt)sInstance).spanClass = _spanClass;
            }
     
            return sInstance;
        }
        
        int x1;
        int x2;
        int y1;
        int y2;
        
         @Override
            public boolean onTouchEvent(TextView widget, Spannable buffer,
                                        MotionEvent event) {
                int action = event.getAction();
     
                if (event.getAction() == MotionEvent.ACTION_DOWN){
                    x1 = (int) event.getX();
                    y1 = (int) event.getY();
                }
                
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    x2 = (int) event.getX();
                    y2 = (int) event.getY();
                    
                if (Math.abs(x1 - x2) < 10 && Math.abs(y1 - y2) < 10) {
                    x2 -= widget.getTotalPaddingLeft();
                    y2 -= widget.getTotalPaddingTop();
                    x2 += widget.getScrollX();
                    y2 += widget.getScrollY();
                    Layout layout = widget.getLayout();
                    int line = layout.getLineForVertical(y2);
                    int off = layout.getOffsetForHorizontal(line, x2);
                    /**
                     * get you interest span
                     */
                    Object[] spans = buffer.getSpans(off, off, spanClass);
                    if (spans.length != 0) {
                        
                        Selection.setSelection(buffer,
                                buffer.getSpanStart(spans[0]),
                                buffer.getSpanEnd(spans[0]));
                        MessageSpan obj = new MessageSpan();
                        obj.setObj(spans);
                        obj.setView(widget);
                        Message message = handler.obtainMessage();
                        message.obj = obj;
                        message.what = 200;
                        message.sendToTarget();
                        return true;
                    }
                }
                }
                //return false; 
                return super.onTouchEvent(widget, buffer, event);
                
             
            }
     
            
            
         public boolean canSelectArbitrarily() {
                return true;
            }
         
        public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode,
                KeyEvent event) {
            return false;
        }
    

    MessageSpan类如下:

    public class MessageSpan {
        private Object obj;
        private TextView view;
     
        public Object getObj() {
            return obj;
        }
     
        public void setObj(Object obj) {
            this.obj = obj;
        }
     
        public TextView getView() {
            return view;
        }
     
        public void setView(TextView view) {
            this.view = view;
        }
    }
    

    页面及使用代码如下:

    public class MyTestActivity extends BaseActivity {
        TextView tv;
        private String content;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_my_test);
            tv = findViewById(R.id.tv);
        }
        @Override
        protected void initData(Bundle savedInstanceState) {
            content = "1、找出下图中所有轴对称图形,它们是(  )。\n" +
                    "A、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195331478.png\" border=\"0\" align=\"absmiddle\">\n" +
                    "B、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195406586.png\" border=\"0\" align=\"absmiddle\">\n" +
                    "C、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195417277.png\" border=\"0\" align=\"absmiddle\">\n"+
                    "D、<img src=\"http://XXXXXXX//XXXX/TextEditor/eWebEditor/uploadfile/2016/06/20160613195426887.png\" border=\"0\" align=\"absmiddle\">";
            tv.setText(Html.fromHtml(content, new MImageGetter(tv, getApplicationContext()), null));
            final Handler handler = new Handler() {
                public void handleMessage(Message msg) {
                    int what = msg.what;
                    if (what == 200) {
                        MessageSpan ms = (MessageSpan) msg.obj;
                        Object[] spans = (Object[]) ms.getObj();
                        final ArrayList<String> list = new ArrayList<>();
                        for (Object span : spans) {
                            if (span instanceof ImageSpan) {
                                Log.i("picUrl==", ((ImageSpan) span).getSource());
                                list.add(((ImageSpan) span).getSource());
                                Intent intent = new Intent(getApplicationContext(), ImageGalleryActivity.class);
                                intent.putStringArrayListExtra("images", list);
                                startActivity(intent);
                            }
                        }
                    }
                }
            };
            tv.setMovementMethod(LinkMovementMethodExt.getInstance(handler, ImageSpan.class));
        }
    }
    

    相关文章

      网友评论

          本文标题:Android中的富文本

          本文链接:https://www.haomeiwen.com/subject/sxietctx.html