android开发 自定义图文混排控件
功能:图文混排,可自动缩放字体,如图:

单点触控使用的代码来自: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开发 自定义图文混排控件的更多相关文章
- Android开发技巧——自定义控件之组合控件
Android开发技巧--自定义控件之组合控件 我准备在接下来一段时间,写一系列有关Android自定义控件的博客,包括如何进行各种自定义,并分享一下我所知道的其中的技巧,注意点等. 还是那句老话,尽 ...
- 使用android SpannableStringBuilder实现图文混排
项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的 ...
- 自定义图文混排视图MyImageTextView
http://blog.csdn.net/xujunfeng000/article/details/36399339?utm_source=tuicool&utm_medium=referra ...
- 使用android SpannableStringBuilder实现图文混排,看到许多其他
项目开发需要达到这种效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmFuY3lsb3ZlamF2YQ==/font/5a6L5L2T/fontsiz ...
- Android TextView中图文混排设置行间距导致高度不一致问题解决
最近项目中需要实现一个评论带表情的功能,刚开始一切顺利,非常easy,突然有一天发现文字跟表情混排的时候,TextView中图文高度不一致,excuse...什么鬼,之前明明测试过图文混排,不存在这个 ...
- Android创建自定义的布局和控件
Android的自带布局有framelayout.linerlayout.relativelayout,外加两个百分比布局,但是这些无法灵活的满足我们的需要,所以我们要自己自定义并引入自己的布局.首先 ...
- [APP] Android 开发笔记 004-Android常用基本控件使用说明
TextView 文本框 EditText控件 Button 与 ImageButton ImageView RadioButton CheckBox复选框 TextView 文本框 ,用于显示文本的 ...
- android 开发-spinner下拉框控件的实现
Android提供实现下拉框功能的非常实用的控件Spinner. spinner控件需要向xml资源文件中添加spinner标签,如下: <Spinner android:id="@+ ...
- 【转】Android TextView SpannableStringBuilder 图文混排颜色斜体粗体下划线删除线
spannableStringBuilder 用法详解: SpannableString ss = new SpannableString("红色打电话斜体删除线绿色下划线图片:." ...
随机推荐
- .NET Framework 中的字符编码
字符是可用多种不同方式表示的抽象实体. 字符编码是一种为受支持字符集中的每个字符进行配对的系统,配对时使用的是表示该字符的某些值. 例如,摩尔斯电码是一种为罗马字母表中的每个字符进行配对的字符编码,配 ...
- JavaScript高级 面向对象的程序设计 (二)《JavaScript高级程序设计(第三版)》
二.继承 OO是面向对象语言最为有魅力的概念.一般的OO语言都实现了两种继承,接口继承和实现继承.接口继承只继承方法签名,而实际继承继承了实际的方法. 而在JS中,函数没有签名,所以无法实现接口继承. ...
- CentOS学习笔记--目录配置
Linux目录配置 类Linux的目录看上去差不多,为什么? 以下内容节选自l 鸟哥的 Linux 私房菜 -- 基础学习篇目录 第六章.Linux 的文件权限与目录配置 3. Linux目录配 ...
- (四)、 nodejs中Async详解之一:流程控制
为了适应异步编程,减少回调的嵌套,我尝试了很多库.最终觉得还是async最靠谱. 地址:https://github.com/caolan/async Async的内容分为三部分: 流程控制:简化十种 ...
- 导出数据库数据制成Excel和txt
引用ICSharpCode.SharpZipLib.dll 1.编写压缩和解压代码 using System; using System.Collections.Generic; using Syst ...
- Eclipse HibernateTools安装
Hibernate Orm是个很强大的东东,可以将数据表映射成实体,EClipse安装了HibernateTools插件后可以生成pojo,配置xml等一系列自动化工作,为我们的开发减轻了很多. 下面 ...
- Android Socket通信
1.TCP: xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns: ...
- SQL 查询优化
优化方法论: 分析实例级的等待. 联系等待和队列. 确定方案. 细化到数据/文件级. 细化到进程级. 优化索引/查询.
- Python脚本控制的WebDriver 常用操作 <九> 定位一组对象
下面将使用WebDriver来模拟操作定位一组对象的操作 测试用例场景 从上一节的例子中可以看出,webdriver可以很方便的使用find_element方法来定位某个特定的对象,不过有时候我们却需 ...
- IE10-浏览器实现placeholder效果
如下图,在文本框为空时显示提示文字 在IE10+和chrome浏览器加placeholder属性及可实现 ,单在IE10-浏览器并不支持该属性, 以下是placeholder在IE10-浏览器的实现 ...