日期:2014-05-17  浏览次数:20795 次

自定义View实现HTML图文环绕效果
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