当前位置: 首页 > news >正文

怎样建设个人网站广告赚钱优化大师在哪里

怎样建设个人网站广告赚钱,优化大师在哪里,表白网站在线生成,建立电商网站先看下效果图: 上面是MTextView,下面是默认的TextView。 一、原因 用最简单的全英文句子为例,如果有一个很长的单词,这一行剩余的空间显示不下了,那么规则就是不打断单词,而是把整个单词丢到下一行开始显示…

先看下效果图:

上面是MTextView,下面是默认的TextView。

一、原因

用最简单的全英文句子为例,如果有一个很长的单词,这一行剩余的空间显示不下了,那么规则就是不打断单词,而是把整个单词丢到下一行开始显示。这样 本来没有错。一是咱们中国人都是方块字,怎么都放得下,不存在英文的这个问题。所以不习惯那个排版。二是如果TextView里面有图片,如图,不知道判断单词的代码是怎么弄得,总之它觉得最后一个啦字和后面的一串表情应该是一个整体,不能分开,就一起丢到第二行了,也就造成了这种难看的排版。要验证这个说法也很简单,自己去QQ里试一试,在每个表情之间都加一个空格,就会发现排版一下子正常了。

二、解决方法

    最简单的就是表情之间加空格,如果不想这么做,就只有自己来画啦。

    先给初学的朋友解释一下View绘制的流程,首先是onMeasure(int widthMeasureSpec, int heightMeasureSpec),onMeasure执行的时候,就是父View在问你,小朋友,你要占多大的地儿呀?当然,问你的时候,会给你个 限制条件,就是那两参数,以widthMeasureSpec为例,这参数不能直接用,得先拆开,用int widthMode = MeasureSpec.getMode(widthMeasureSpec) 和 int widthSize = MeasureSpec.getSize(widthMeasureSpec);widthMode就三种情况:

MeasureSpec.EXACTLY:你就widthSize那么宽就行了。

MeasureSpec.AT_MOST:你最多只能widthSize那么宽。

MeasureSpec.UNSPECIFIED:未指定,你爱多宽多宽。

当然,其实这只父View给你的建议,遵不遵守你自己看着办,但是自己乱来导致显示不全就不是父View的错了。

最终你听取了建议,思量了一番,觉得自己应该有width那么宽,height那么高,最后就得用setMeasuredDimension(width, height)这个函数真正确定自己的高宽。然后onMeasure()的工作就完了。

然后就是onDraw(Canvas canvas),这个就简单了,canvas就是父View给的一块画布,爱在上面画啥都行,比如写个字drawText(String text,float x, float y, Paint paint),

text是要写的字,paint是写字的笔,值得注意的是x,y坐标是相对于你自己这一小块画布的左上角的。最左上就是0,0右下是width,height

上代码

/*** @author huangwei* @version SocialClient 1.2.0* @功能 图文混排TextView,请使用{@link #setMText(CharSequence)}* @2014年5月27日* @下午5:29:27*/
public class MTextView extends TextView
{/*** 缓存测量过的数据*/private static HashMap<String, SoftReference<MeasuredData>> measuredData = new HashMap<String, SoftReference<MeasuredData>>();private static int hashIndex = 0;/*** 存储当前文本内容,每个item为一行*/ArrayList<LINE> contentList = new ArrayList<LINE>();private Context context;/*** 用于测量字符宽度*/private TextPaint paint = new TextPaint();//    private float lineSpacingMult = 0.5f;private int textColor = Color.BLACK;//行距private float lineSpacing;private int lineSpacingDP = 5;/*** 最大宽度*/private int maxWidth;/*** 只有一行时的宽度*/private int oneLineWidth = -1;/*** 已绘的行中最宽的一行的宽度*/private float lineWidthMax = -1;/*** 存储当前文本内容,每个item为一个字符或者一个SpanObject*/private ArrayList<Object> obList = new ArrayList<Object>();/*** 是否使用默认{@link #onMeasure(int, int)}和{@link #onDraw(Canvas)}*/private boolean useDefault = false;private CharSequence text = "";private int minHeight;/*** 用以获取屏幕高宽*/private DisplayMetrics displayMetrics;/*** {@link android.text.style.BackgroundColorSpan}用*/private Paint textBgColorPaint = new Paint();/*** {@link android.text.style.BackgroundColorSpan}用*/private Rect textBgColorRect = new Rect();public MTextView(Context context){super(context);this.context = context;paint.setAntiAlias(true);lineSpacing = dip2px(context, lineSpacingDP);minHeight = dip2px(context, 30);displayMetrics = new DisplayMetrics();}public MTextView(Context context,AttributeSet attrs){super(context,attrs);this.context = context;paint.setAntiAlias(true);lineSpacing = dip2px(context, lineSpacingDP);minHeight = dip2px(context, 30);displayMetrics = new DisplayMetrics();}public static int px2sp(Context context, float pxValue){final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;return (int) (pxValue / fontScale + 0.5f);}/*** 根据手机的分辨率从 dp 的单位 转成为 px(像素)*/public static int dip2px(Context context, float dpValue){final float scale = context.getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}@Overridepublic void setMaxWidth(int maxpixels){super.setMaxWidth(maxpixels);maxWidth = maxpixels;}@Overridepublic void setMinHeight(int minHeight){super.setMinHeight(minHeight);this.minHeight = minHeight;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){if (useDefault){super.onMeasure(widthMeasureSpec, heightMeasureSpec);return;}int width = 0, height = 0;int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);switch (widthMode){case MeasureSpec.EXACTLY:width = widthSize;break;case MeasureSpec.AT_MOST:width = widthSize;break;case MeasureSpec.UNSPECIFIED:((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);width = displayMetrics.widthPixels;break;default:break;}if (maxWidth > 0)width = Math.min(width, maxWidth);paint.setTextSize(this.getTextSize());paint.setColor(textColor);int realHeight = measureContentHeight((int) width);//如果实际行宽少于预定的宽度,减少行宽以使其内容横向居中int leftPadding = getCompoundPaddingLeft();int rightPadding = getCompoundPaddingRight();width = Math.min(width, (int) lineWidthMax + leftPadding + rightPadding);if (oneLineWidth > -1){width = oneLineWidth;}switch (heightMode){case MeasureSpec.EXACTLY:height = heightSize;break;case MeasureSpec.AT_MOST:height = realHeight;break;case MeasureSpec.UNSPECIFIED:height = realHeight;break;default:break;}height += getCompoundPaddingTop() + getCompoundPaddingBottom();height = Math.max(height, minHeight);setMeasuredDimension(width, height);}@Overrideprotected void onDraw(Canvas canvas){if (useDefault){super.onDraw(canvas);return;}if (contentList.isEmpty())return;int width;Object ob;int leftPadding = getCompoundPaddingLeft();int topPadding = getCompoundPaddingTop();float height = 0 + topPadding + lineSpacing;//只有一行时if (oneLineWidth != -1){height = getMeasuredHeight() / 2 - contentList.get(0).height / 2;}for (LINE aContentList : contentList){//绘制一行float realDrawedWidth = leftPadding;for (int j = 0; j < aContentList.line.size(); j++){ob = aContentList.line.get(j);width = aContentList.widthList.get(j);if (ob instanceof String){canvas.drawText((String) ob, realDrawedWidth, height + aContentList.height - paint.getFontMetrics().descent, paint);realDrawedWidth += width;}else if (ob instanceof SpanObject){Object span = ((SpanObject) ob).span;if(span instanceof ImageSpan){ImageSpan is = (ImageSpan) span;Drawable d = is.getDrawable();int left = (int) (realDrawedWidth);int top = (int) height;int right = (int) (realDrawedWidth + width);int bottom = (int) (height + aContentList.height);d.setBounds(left, top, right, bottom);d.draw(canvas);realDrawedWidth += width;}else if(span instanceof BackgroundColorSpan){textBgColorPaint.setColor(((BackgroundColorSpan) span).getBackgroundColor());textBgColorPaint.setStyle(Style.FILL);textBgColorRect.left = (int) realDrawedWidth;int textHeight = (int) getTextSize();textBgColorRect.top = (int) (height + aContentList.height - textHeight - paint.getFontMetrics().descent);textBgColorRect.right = textBgColorRect.left+width;textBgColorRect.bottom = (int) (height + aContentList.height + lineSpacing  - paint.getFontMetrics().descent);canvas.drawRect(textBgColorRect, textBgColorPaint);canvas.drawText(((SpanObject) ob).source.toString(), realDrawedWidth, height + aContentList.height - paint.getFontMetrics().descent, paint);realDrawedWidth += width;}else//做字符串处理
                    {canvas.drawText(((SpanObject) ob).source.toString(), realDrawedWidth, height + aContentList.height - paint.getFontMetrics().descent, paint);realDrawedWidth += width;}}}height += aContentList.height + lineSpacing;}}@Overridepublic void setTextColor(int color){super.setTextColor(color);textColor = color;}/*** 用于带ImageSpan的文本内容所占高度测量* @param width 预定的宽度* @return 所需的高度*/private int measureContentHeight(int width){int cachedHeight = getCachedData(text.toString(), width);if (cachedHeight > 0){return cachedHeight;}// 已绘的宽度float obWidth = 0;float obHeight = 0;float textSize = this.getTextSize();FontMetrics fontMetrics = paint.getFontMetrics();//行高float lineHeight = fontMetrics.bottom - fontMetrics.top;//计算出的所需高度float height = lineSpacing;int leftPadding = getCompoundPaddingLeft();int rightPadding = getCompoundPaddingRight();float drawedWidth = 0;boolean splitFlag = false;//BackgroundColorSpan拆分用
width = width - leftPadding - rightPadding;oneLineWidth = -1;contentList.clear();StringBuilder sb;LINE line = new LINE();for (int i = 0; i < obList.size(); i++){Object ob = obList.get(i);if (ob instanceof String){obWidth = paint.measureText((String) ob);obHeight = textSize;}else if (ob instanceof SpanObject){Object span = ((SpanObject) ob).span;if(span instanceof ImageSpan){Rect r = ((ImageSpan)span).getDrawable().getBounds();obWidth = r.right - r.left;obHeight = r.bottom - r.top;if (obHeight > lineHeight)lineHeight = obHeight;}else if(span instanceof BackgroundColorSpan){String str = ((SpanObject) ob).source.toString();obWidth = paint.measureText(str);obHeight = textSize;//如果太长,拆分int k= str.length()-1;while(width - drawedWidth < obWidth){obWidth = paint.measureText(str.substring(0,k--));}if(k < str.length()-1){splitFlag = true;SpanObject so1 = new SpanObject();so1.start = ((SpanObject) ob).start;so1.end = so1.start + k;so1.source = str.substring(0,k+1);so1.span = ((SpanObject) ob).span;SpanObject so2 = new SpanObject();so2.start =  so1.end;so2.end = ((SpanObject) ob).end;so2.source = str.substring(k+1,str.length());so2.span = ((SpanObject) ob).span;ob = so1;obList.set(i,so2);i--;}}//做字符串处理else{String str = ((SpanObject) ob).source.toString();obWidth = paint.measureText(str);obHeight = textSize;}}//这一行满了,存入contentList,新起一行if (width - drawedWidth < obWidth || splitFlag){splitFlag = false;contentList.add(line);if (drawedWidth > lineWidthMax){lineWidthMax = drawedWidth;}drawedWidth = 0;height += line.height + lineSpacing;lineHeight = obHeight;line = new LINE();}drawedWidth += obWidth;if (ob instanceof String && line.line.size() > 0 && (line.line.get(line.line.size() - 1) instanceof String)){int size = line.line.size();sb = new StringBuilder();sb.append(line.line.get(size - 1));sb.append(ob);ob = sb.toString();obWidth = obWidth + line.widthList.get(size - 1);line.line.set(size - 1, ob);line.widthList.set(size - 1, (int) obWidth);line.height = (int) lineHeight;}else{line.line.add(ob);line.widthList.add((int) obWidth);line.height = (int) lineHeight;}}if (drawedWidth > lineWidthMax){lineWidthMax = drawedWidth;}if (line != null && line.line.size() > 0){contentList.add(line);height += lineHeight + lineSpacing;}if (contentList.size() <= 1){oneLineWidth = (int) drawedWidth + leftPadding + rightPadding;height = lineSpacing + lineHeight + lineSpacing;}cacheData(width, (int) height);return (int) height;}/*** 获取缓存的测量数据,避免多次重复测量* @param text* @param width* @return height*/@SuppressWarnings("unchecked")private int getCachedData(String text, int width){SoftReference<MeasuredData> cache = measuredData.get(text);if (cache == null)return -1;MeasuredData md = cache.get();if (md != null && md.textSize == this.getTextSize() && width == md.width){lineWidthMax = md.lineWidthMax;contentList = (ArrayList<LINE>) md.contentList.clone();oneLineWidth = md.oneLineWidth;StringBuilder sb = new StringBuilder();for (int i = 0; i < contentList.size(); i++){LINE line = contentList.get(i);sb.append(line.toString());}return md.measuredHeight;}elsereturn -1;}/*** 缓存已测量的数据* @param width* @param height*/@SuppressWarnings("unchecked")private void cacheData(int width, int height){MeasuredData md = new MeasuredData();md.contentList = (ArrayList<LINE>) contentList.clone();md.textSize = this.getTextSize();md.lineWidthMax = lineWidthMax;md.oneLineWidth = oneLineWidth;md.measuredHeight = height;md.width = width;md.hashIndex = ++hashIndex;StringBuilder sb = new StringBuilder();for (int i = 0; i < contentList.size(); i++){LINE line = contentList.get(i);sb.append(line.toString());}SoftReference<MeasuredData> cache = new SoftReference<MeasuredData>(md);measuredData.put(text.toString(), cache);}/*** 用本函数代替{@link #setText(CharSequence)}* @param cs*/public void setMText(CharSequence cs){text = cs;obList.clear();ArrayList<SpanObject> isList = new ArrayList<MTextView.SpanObject>();useDefault = false;if (cs instanceof SpannableString){SpannableString ss = (SpannableString) cs;CharacterStyle[] spans = ss.getSpans(0, ss.length(), CharacterStyle.class);for (int i = 0; i < spans.length; i++){int s = ss.getSpanStart(spans[i]);int e = ss.getSpanEnd(spans[i]);SpanObject iS = new SpanObject();iS.span = spans[i];iS.start = s;iS.end = e;iS.source = ss.subSequence(s, e);isList.add(iS);}}//对span进行排序,以免不同种类的span位置错乱SpanObject[] spanArray = new SpanObject[isList.size()];isList.toArray(spanArray);Arrays.sort(spanArray,0,spanArray.length,new SpanObjectComparator());isList.clear();for(int i=0;i<spanArray.length;i++){isList.add(spanArray[i]);}String str = cs.toString();for (int i = 0, j = 0; i < cs.length(); ){if (j < isList.size()){SpanObject is = isList.get(j);if (i < is.start){Integer cp = str.codePointAt(i);//支持增补字符if (Character.isSupplementaryCodePoint(cp)){i += 2;}else{i++;}obList.add(new String(Character.toChars(cp)));}else if (i >= is.start){obList.add(is);j++;i = is.end;}}else{Integer cp = str.codePointAt(i);if (Character.isSupplementaryCodePoint(cp)){i += 2;}else{i++;}obList.add(new String(Character.toChars(cp)));}}requestLayout();}public void setUseDefault(boolean useDefault){this.useDefault = useDefault;if (useDefault){this.setText(text);this.setTextColor(textColor);}}/*** 设置行距* @param lineSpacingDP 行距,单位dp*/public void setLineSpacingDP(int lineSpacingDP){this.lineSpacingDP = lineSpacingDP;lineSpacing = dip2px(context, lineSpacingDP);}/*** 获取行距* @return 行距,单位dp*/public int getLineSpacingDP(){return lineSpacingDP;}/*** @author huangwei* @version SocialClient 1.2.0* @功能: 存储Span对象及相关信息* @2014年5月27日* @下午5:21:37*/class SpanObject{public Object span;public int start;public int end;public CharSequence source;}/*** @功能: 对SpanObject进行排序* @author huangwei* @2014年6月4日* @下午5:21:30* @version SocialClient 1.2.0*/class SpanObjectComparator implements Comparator<SpanObject>{@Overridepublic int compare(SpanObject lhs, SpanObject rhs){return lhs.start - rhs.start;}}/*** @author huangwei* @version SocialClient 1.2.0* @功能: 存储测量好的一行数据* @2014年5月27日* @下午5:22:12*/class LINE{public ArrayList<Object> line = new ArrayList<Object>();public ArrayList<Integer> widthList = new ArrayList<Integer>();public int height;@Overridepublic String toString(){StringBuilder sb = new StringBuilder("height:" + height + "   ");for (int i = 0; i < line.size(); i++){sb.append(line.get(i) + ":" + widthList.get(i));}return sb.toString();}}/*** @author huangwei* @version SocialClient 1.2.0* @功能: 缓存的数据* @2014年5月27日* @下午5:22:25*/class MeasuredData{public int measuredHeight;public float textSize;public int width;public float lineWidthMax;public int oneLineWidth;public int hashIndex;ArrayList<LINE> contentList;}

为方便在ListView中使用(ListView反复上下滑动会多次重新onMeasure),加了缓存,相同的情况下可以不用重复在测量一次。

对于SpannableString,只支持了ImageSpan,有其它需要者可自行扩展

Demo:http://download.csdn.net/detail/yellowcath/7421147 或:https://github.com/yellowcath/MTextView.git (2014/6/4 更新 添加对BackGroundColorSpan的支持,修复一个会导致最后一行最后一个图形显示不全的bug)

代码:这里

转载于:https://www.cnblogs.com/zhujiabin/p/4269217.html

http://www.lbrq.cn/news/2470195.html

相关文章:

  • 唐山网站建设唐山做网站统计网站访问量
  • 临沂网站排名优化在哪里可以做百度推广
  • wordpress 后台打不开优化网站结构一般包括
  • 教育平台网站seo是免费的吗
  • 网站服务器哪里的好如何写软文赚钱
  • 专门做三国战纪的网站叫什么意思全球热门网站排名
  • c 做网站怎么插入id网络营销的公司有哪些
  • 做文件的网站网站优化建设
  • 织梦播放器网站苏州关键词排名提升
  • 拉萨做网站公司sem网络营销
  • 服务器里面如何做网站江门seo推广公司
  • 用c 做网站可以吗软文发布平台媒体
  • 网站头部固定网络营销过程步骤
  • 开服表网站开发创建一个网站
  • 网站建设比较好的网站发布与推广方式
  • 网站开发费用算无形资产关键词优化上海
  • 湖南土特产销售网网站建设制作武汉网站设计十年乐云seo
  • 代办公司执照重庆seo按天收费
  • 电商网站建设公司网站首页制作网站
  • 企业网站案例分析厦门seo关键词排名
  • 团员信息查询系统入口丽水网站seo
  • 营销网络是什么意思网站优化的主要内容
  • wordpress同步空间seo策略有哪些
  • 免费网站建设seo百度竞价品牌广告
  • 用什么网站推广广州网络优化最早的公司
  • 政府网站建设费用营销型网站定制
  • html5 单页 响应式 网站模板网络营销有什么
  • 明年做哪些网站致富新闻网站排行榜
  • 河北邢台有什么好玩的地方信息流优化师是干什么的
  • 商贸公司的网站建设百度网盘搜索引擎网站
  • Java程序员学从0学AI(六)
  • 渲染篇(二):解密Diff算法:如何用“最少的操作”更新UI
  • Java学习|黑马笔记|Day23】网络编程、反射、动态代理
  • Java——Spring框架全面解析
  • [python][flask]Flask-Login 使用详解
  • LIMA:大语言模型对齐的“少即是多”革命——原理、实验与范式重构