功能:图文混排,可自动缩放字体,如图:

单点触控使用的代码来自:http://blog.csdn.net/xiaanming/article/details/42833893  谢谢博主!

在该demo中只是将bitmap改为了显示图文混排的效果,不足之处,请大家指正,共同进步!

贴上2个重要的方法:

private void MeasureBitmapTextSize(HSpannableString htr)  //计算图文内容需要的bitmap高宽以及对应的字体大小
{
//根据字体大小重新计算字体大小
int columnSpace = 5; //列间距
int rowSpace = 5; //行间距
float charWidth = 0; //每个字符占的宽度,以一个英文字符为单位
float charHeight = 0; //每个字符的高度 Paint tryPaint = new Paint();
tryPaint.setTextAlign(Paint.Align.CENTER);
tryPaint.setAntiAlias(true); //设置画笔为无锯齿
// tryPaint.setTextSize(mTextSize);
tryPaint.setColor(mTextColor); float curRowLen = 0;
mBmpWidth = 0;
mBmpHeight = 0;
int size = htr.stringList.size(); int curTextSize = (int) mTextSize;
if(mTextSize==min_textsize)
{
curTextSize = max_textsize;
}
for(;curTextSize > min_textsize;curTextSize--) //从当前字体开始循环缩小
{
mBmpHeight = 0;
tryPaint.setTextSize(curTextSize);
FontMetrics fontMetrics = tryPaint.getFontMetrics();
charHeight = fontMetrics.bottom - fontMetrics.top;
curRowLen = columnSpace;
for(int i=0;i<size;i++)
{
Hstring hs = htr.stringList.get(i);
if(hs.type==Hstring.TYPE_TEXT)
{
charWidth = tryPaint.measureText(hs.ch+"",0,1);
}
else //图片元素,,一个图片占一个中文方块字的高宽
{
charWidth = tryPaint.measureText("哈"+"",0,1);
}
curRowLen += (columnSpace + charWidth);
Log.e("resetBitmap", "curRowLen="+curRowLen+";charWidth="+charWidth+";mTextSize="+mTextSize+";mBmpHeight="+mBmpHeight);
if(curRowLen > (mParentWidth-TEXT_PADDING*2)) //换行
{
Log.e("resetBitmap", "TAG1:curRowLen="+curRowLen+";mParentWidth="+mParentWidth+";TEXT_PADDING="+TEXT_PADDING);
//需要换行
curRowLen = charWidth+ columnSpace;
mBmpWidth = (mParentWidth - TEXT_PADDING*2);
mBmpHeight += (charHeight+rowSpace);
Log.e("resetBitmap", "TAG1:mBmpWidth="+mBmpWidth+";i="+i+";size="+size);
if(i>=(size-1)) //说明是最后一行
{
mBmpHeight += (charHeight+rowSpace);
}
}
else if(i>=(size-1) && curRowLen > minBmpWidth && mBmpWidth!=(mParentWidth- TEXT_PADDING*2))//第一行时
{
mBmpWidth = (int) curRowLen;
mBmpHeight = (int)(charHeight+rowSpace);
Log.e("resetBitmap", "TAG2:mBmpWidth="+mBmpWidth);
break;
}
else if(i>=(size-1) && mBmpWidth!=(mParentWidth- TEXT_PADDING*2))//第一行时
{
mBmpWidth = minBmpWidth;
mBmpHeight = (int) (charHeight+rowSpace);
Log.e("resetBitmap", "TAG3:mBmpWidth="+mBmpWidth);
break;
}
else if(i>=(size-1) && mBmpWidth == (mParentWidth- TEXT_PADDING*2)) //当前有换行
{
mBmpWidth = (mParentWidth- TEXT_PADDING*2);
mBmpHeight += (charHeight+rowSpace);
Log.e("resetBitmap", "TAG4:mBmpWidth="+mBmpWidth);
break;
}
}
if(mBmpHeight<=(mParentHeight - TEXT_PADDING*2) || curTextSize <=min_textsize)
{
mTextSize = curTextSize;
break;
}
}
// Log.v("resetBitmap", "mBmpWidth="+mBmpWidth+";mBmpHeight="+mBmpHeight);
}

再次,将内容画到bitmap上去(mBmpWidth和 mBmpHeight)

/**
* 将图文内容生成图片
* @param htr
* @param textSize
* @param textColor
* @return
*/
public Bitmap createTextBitmap(HSpannableString htr,float textSize,int textColor)
{
//设置初始属性
int columnSpace = 5; //列间距
int rowSpace = 5; //行间距
float curX =0,curY=0;
// float curRowWidth = 0; //当前所在行的实时宽度
MeasureBitmapTextSize(htr); //重新设置改bitmap的高宽
if(mBmpWidth <=0 || mBmpHeight <=0)
{
mBmpWidth = minBmpWidth;
mBmpHeight = minBmpHeight;
}
Bitmap bitmap = Bitmap.createBitmap(mBmpWidth, mBmpHeight, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
//画背景
Paint bgpaint = new Paint();
bgpaint.setColor(Color.parseColor("#CEFFCE"));
Rect bgrect = new Rect(0, 0, mBmpWidth, mBmpHeight);
canvas.drawRect(bgrect, bgpaint);
//画内容
Paint fontPaint = new Paint();
fontPaint.setTextAlign(Paint.Align.CENTER);
fontPaint.setAntiAlias(true); //设置画笔为无锯齿
fontPaint.setTextSize(textSize);
fontPaint.setColor(textColor); // 计算每一个坐标
// float baseX = 0;
// float baseY = rowSpace;
FontMetrics fontMetrics = fontPaint.getFontMetrics();
float fontTotalHeight = fontMetrics.bottom - fontMetrics.top;
// float offY = fontTotalHeight / 2 - fontMetrics.bottom;
// float newY = baseY + offY;
curX = columnSpace;
curY = fontTotalHeight - fontMetrics.descent;
float charWidth= 0;
float tryCurWidth=0; //用于判断换行的
for(int i=0;i<htr.stringList.size();i++)
{
Hstring hs = htr.stringList.get(i);
if(hs.type==Hstring.TYPE_TEXT) //文本
{
charWidth = fontPaint.measureText(hs.ch+"",0,1);
//计算会不会超出边界
tryCurWidth = curX + (columnSpace + charWidth); if(tryCurWidth > (mParentWidth-TEXT_PADDING*2))
{
curY += rowSpace+fontTotalHeight;
curX = columnSpace;
}
else
{
curX = tryCurWidth-(columnSpace + charWidth);
}
Log.e("createTextBitmap3", "curX="+curX+";hs.ch="+hs.ch+";charWidth="+charWidth);
canvas.drawText(hs.ch+"", curX+charWidth/2, curY, fontPaint);
curX += (columnSpace + charWidth);
tryCurWidth = 0;
}
else //图片
{
charWidth = fontPaint.measureText("哈"+"",0,1);
//预算会不会超出边界
tryCurWidth = curX + (columnSpace + charWidth);
if(tryCurWidth > (mParentWidth-TEXT_PADDING*2))
{
curY += rowSpace+fontTotalHeight;
curX = columnSpace;
}
else
{
curX = tryCurWidth-(columnSpace + charWidth);
}
Rect srcRect = new Rect();
srcRect.left = 0;
srcRect.top = 0;
srcRect.right = htr.stringList.get(i).bmp.getWidth();
srcRect.bottom = htr.stringList.get(i).bmp.getWidth() + htr.stringList.get(i).bmp.getHeight();
Rect bmpRect = new Rect((int)curX,(int)(curY + fontMetrics.ascent+fontMetrics.leading),(int)(curX+columnSpace + charWidth),(int)(curY -fontMetrics.ascent));
Log.v("图片", "curY="+curY+";ascent="+fontMetrics.ascent+";leading="+fontMetrics.leading);
Paint bmpPaint = new Paint();
Log.e("createTextBitmap3", "curX="+curX+";hs.ch="+hs.ch+";charWidth="+charWidth);
canvas.drawBitmap(htr.stringList.get(i).bmp, srcRect,bmpRect, bmpPaint);
curX += (columnSpace + charWidth);
tryCurWidth = 0;
}
}
return bitmap;
}

demo下载地址:http://download.csdn.net/detail/feijian_/9014939

android开发 自定义图文混排控件的更多相关文章

  1. Android开发技巧——自定义控件之组合控件

    Android开发技巧--自定义控件之组合控件 我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等. 还是那句老话,尽 ...

  2. 使用android SpannableStringBuilder实现图文混排

    项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的 ...

  3. 自定义图文混排视图MyImageTextView

    http://blog.csdn.net/xujunfeng000/article/details/36399339?utm_source=tuicool&utm_medium=referra ...

  4. 使用android SpannableStringBuilder实现图文混排,看到许多其他

    项目开发需要达到这种效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmFuY3lsb3ZlamF2YQ==/font/5a6L5L2T/fontsiz ...

  5. Android TextView中图文混排设置行间距导致高度不一致问题解决

    最近项目中需要实现一个评论带表情的功能,刚开始一切顺利,非常easy,突然有一天发现文字跟表情混排的时候,TextView中图文高度不一致,excuse...什么鬼,之前明明测试过图文混排,不存在这个 ...

  6. Android创建自定义的布局和控件

    Android的自带布局有framelayout.linerlayout.relativelayout,外加两个百分比布局,但是这些无法灵活的满足我们的需要,所以我们要自己自定义并引入自己的布局.首先 ...

  7. [APP] Android 开发笔记 004-Android常用基本控件使用说明

    TextView 文本框 EditText控件 Button 与 ImageButton ImageView RadioButton CheckBox复选框 TextView 文本框 ,用于显示文本的 ...

  8. android 开发-spinner下拉框控件的实现

    Android提供实现下拉框功能的非常实用的控件Spinner. spinner控件需要向xml资源文件中添加spinner标签,如下: <Spinner android:id="@+ ...

  9. 【转】Android TextView SpannableStringBuilder 图文混排颜色斜体粗体下划线删除线

    spannableStringBuilder 用法详解: SpannableString ss = new SpannableString("红色打电话斜体删除线绿色下划线图片:." ...

随机推荐

  1. 很不错的安卓FadingActionBar控件源码

    这个我刚刚从一个github下载过来的,自己测试一下运行了,感觉还不错的,安卓FadingActionBar控件源码,现在就给大家分享一下,源码我已经上传到源码天堂那里了,想下载的朋友可以去那里下载吧 ...

  2. leetcode1:在数组中找2个数的和正好等于一个给定值--哈希

    package java_net_test; import java.util.HashMap; import java.util.Iterator; import java.util.Map; pu ...

  3. POJ C++程序设计 编程作业—类和对象 编程题#3

    编程题 #3 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 下面程序的输出 ...

  4. POJ C程序设计进阶 编程题#5:细菌分组实验

    编程题#5:细菌实验分组 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 有 ...

  5. Clearing Search Values

      Use the SearchClear() method which is part of the Field class to clear search values on a particul ...

  6. 封装Html5 Fullscreen API

    复制前言: 使用新的全屏 API,可以将用户的注意力导向特定元素,同时隐藏背景或转移对其他应用的注意力.因为W3C全屏规范还未达到最终版本,所以大多数浏览器供应商都使用唯一标识符为 API 添加前缀. ...

  7. WordPress默认栏目设置

    WordPress是一个注重美学.易用性和网络标准的个人信息发布平台,是全球使用最多的博客系统,只需要在系统后台做一些简单的设计,基本就能实现我们日常个性化发布个人信息的需求,而博客后台的使用其实很简 ...

  8. python中列表和元组的使用方法和区别

    一.二者区别 列表: 1.可以增加列表内容     append 2.可以统计某个列表段在整个列表中出现的次数 count 3.可以插入一个字符串,并把整个字符串的每个字母拆分当作一个列表段追加到列表 ...

  9. openstack命令

    整理了Openstack命令: openstack aggregate add host openstack aggregate createopenstack aggregate deleteope ...

  10. SQL1092N The requested command or operation failed because the user ID does not have the authority to perform the requested command or operation.

    1.前一天安装号db2后,做了如下处理: ************************************************************ 修改 /etc/sudoers 文件 ...