Android中并没有提供HTML图文环绕效果的View,最接近的算是TextView中的ImageSpan了,但并未完全实现图文环绕(图文混排)的效果。
1、Android系统TextView的ImageSpan实现图文环绕


代码如下:
TextView tv = new TextView(this);        SpannableString spanStr = new SpannableString("掌声那历史的房间里是副经理撒旦法阿斯顿及福利费是到发顺丰");ImageSpan imageSpan = new ImageSpan(this, R.drawable.a);spanStr.setSpan(imageSpan, 3, 5, Spannable.SPAN_INCLUSIVE_INCLUSIVE);tv.setText(spanStr);        setContentView(tv);



2、 Android中自定义View实现图文环绕


代码如下:
FloatImageText view = new FloatImageText(this);view.setText("电视里发生了房间里是积分拉萨积分拉萨积分拉萨减肥啦空间  撒旦法发大水发撒旦法看完了鸡肉味容积率为热键礼物i经二路文件容量为积分拉萨解放路口上飞机撒离开房间爱水立方法拉圣诞节福禄寿");Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.a);view.setImageBitmap(bm, 30, 30);


import java.util.ArrayList;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.Paint.FontMetrics;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.View;/** * 模拟CSS中的float浮动效果 */public class FloatImageText extends View {    private Bitmap mBitmap;    private final Rect bitmapFrame = new Rect();    private final Rect tmp = new Rect();    private int mTargetDentity = DisplayMetrics.DENSITY_DEFAULT;        private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    private String mText;    private ArrayList<TextLine> mTextLines;    private final int[] textSize = new int[2];    public FloatImageText(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init();    }    public FloatImageText(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public FloatImageText(Context context) {        super(context);        init();    }        private void init() {        mTargetDentity = getResources().getDisplayMetrics().densityDpi;        mTextLines = new ArrayList<TextLine>();                mPaint.setTextSize(14);        mPaint.setColor(Color.RED);            }            @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int w = 0, h = 0;        //图片大小        w += bitmapFrame.width();        h += bitmapFrame.height();                //文本宽度        if(null != mText && mText.length() > 0) {            mTextLines.clear();            int size = resolveSize(Integer.MAX_VALUE, widthMeasureSpec);            measureAndSplitText(mPaint, mText, size);            final int textWidth = textSize[0], textHeight = textSize[1];            w += textWidth; //内容宽度            if(h < textHeight) { //内容高度                h = (int) textHeight;            }        }                w = Math.max(w, getSuggestedMinimumWidth());        h = Math.max(h, getSuggestedMinimumHeight());                setMeasuredDimension(                resolveSize(w, widthMeasureSpec),                 resolveSize(h, heightMeasureSpec));    }        @Override    protected void onDraw(Canvas canvas) {        //绘制图片        if(null != mBitmap) {            canvas.drawBitmap(mBitmap, null, bitmapFrame, null);        }                //绘制文本        TextLine line;        final int size = mTextLines.size();        for(int i = 0; i < size; i++) {            line = mTextLines.get(i);            canvas.drawText(line.text, line.x, line.y, mPaint);        }        System.out.println(mTextLines);    }            public void setImageBitmap(Bitmap bm) {        setImageBitmap(bm, null);    }        public void setImageBitmap(Bitmap bm, int left, int top) {        setImageBitmap(bm, new Rect(left, top, 0, 0));    }        public void setImageBitmap(Bitmap bm, Rect bitmapFrame) {        mBitmap = bm;        computeBitmapSize(bitmapFrame);        requestLayout();        invalidate();    }        public void setText(String text) {        mText = text;        requestLayout();        invalidate();    }        private void computeBitmapSize(Rect rect) {        if(null != rect) {            bitmapFrame.set(rect);        }        if(null != mBitmap) {            if(rect.right == 0 && rect.bottom == 0) {                final Rect r = bitmapFrame;                r.set(r.left, r.top,                         r.left + mBitmap.getScaledHeight(mTargetDentity),                         r.top + mBitmap.getScaledHeight(mTargetDentity));            }        } else {            bitmapFrame.setEmpty();        }    }        private void measureAndSplitText(Paint p, String content, int maxWidth) {        FontMetrics fm = mPaint.getFontMetrics();        final int lineHeight = (int) (fm.bottom - fm.top);                final Rect r = new Rect(bitmapFrame);//        r.inset(-5, -5);                final int length = content.length();        int start = 0, end = 0, offsetX = 0, offsetY = 0;        int availWidth = maxWidth;        TextLine line;        boolean onFirst = true;        boolean newLine = true;        while(start < length) {            end++;            if(end == length) { //剩余的不足一行的文本                if(start <= length - 1) {                    if(newLine) offsetY += lineHeight;                    line = new TextLine();                    line.text = content.substring(start, end - 1);                    line.x = offsetX;                    line.y = offsetY;                    mTextLines.add(line);                }                break;            }            p.getTextBounds(content, start, end, tmp);            if(onFirst) { //确定每个字符串的坐标                onFirst = false;                final int height = lineHeight + offsetY;                if(r.top >= height) { //顶部可以放下一行文字                    offsetX = 0;                    availWidth = maxWidth;                    newLine = true;                } else if(newLine && (r.bottom >= height && r.left >= tmp.width())) { //中部左边可以放文字                    offsetX = 0;                    availWidth = r.left;                    newLine = false;                } else if(r.bottom >= height && maxWidth - r.right >= tmp.width()) { //中部右边                    offsetX = r.right;                    availWidth = maxWidth - r.right;                    newLine = true;                } else { //底部                    offsetX = 0;                    availWidth = maxWidth;                    if(offsetY < r.bottom) offsetY = r.bottom;                    newLine = true;                }            }                        if(tmp.width() > availWidth) { //保存一行能放置的最大字符串                onFirst = true;                line = new TextLine();                line.text = content.substring(start, end - 1);                line.x = offsetX;                mTextLines.add(line);                if(newLine) {                    offsetY += lineHeight;                    line.y = offsetY;                } else {                    line.y = offsetY + lineHeight;                }                                start = end - 1;            }        }        textSize[1] = offsetY;    }        class TextLine {        String text;        int x;        int y;                @Override        public String toString() {            return "TextLine [text=" + text + ", x=" + x + ", y=" + y + "]";        }    }}

更多相关文章

  1. 【Android】虚拟环绕声
  2. 在文字周围环绕一层阴影效果[android:shadow] 使用
  3. MixtureTextView 支持Android图文混排、文字环绕图片等效果
  4. android的数据库API操作
  5. android TextView 容纳不下内容,让字向左滚动的办法

随机推荐

  1. Android(安卓)文件绝对路径和Content开头
  2. 【Android Developers Training】 25. 保
  3. Android修改图片颜色-转成灰度图
  4. android命令gradle打包apk
  5. android pullToRefreshListView的item点
  6. Android,子类访问父类私有成员
  7. kotlin常用工具类总结,高效优雅的开发Andr
  8. Android使用SQLiteDatabase操作SQLite数
  9. -Gradle使用手册(一):为什么要用Gradle?
  10. 自定义View实现图片的绘制、旋转、缩放