高效快捷解决一个TextView显示多种字体的控件SpannableTextView
这个控件本人强烈推荐,它会使得布局非常的简单且高效;
下面这个布局如果是你,你会用多少层?多少控件生成?
告诉你吧,一个SpannableTextView控件就搞定了!
它把TextView和Spannable封装在了一起,可以在一个TextView中显示不同的字体颜色,大小,背景色等;
它支持如下样式:
* Babushka Method Internal Span
* textSize AbsoluteSizeSpan
* textColor ForegroundColorSpan
* textSizeRelative RelativeSizeSpan
* backgroundColor BackgroundColorSpan
* style StyleSpan
* underline UnderlineSpan
* strike StrikethroughSpan
* superscript SuperscriptSpan
* subscript SubscriptSpan
用法也很简单:
- /**
- * 为一个TextView设置多种字体(大小,颜色,背景色等)
- *
- * @param tv
- * @param title
- * @param content
- */
- public void createSpannableTextView(SpannableTextView tv, String title, String content)
- {
- // clear pieces
- tv.reset();
- // Add the first piece
- tv.addPiece(new SpannableTextView.Piece.Builder(title).textColor(App.res.getColor(R.color.text_color_c2))
- .textSize((int) App.res.getDimension(R.dimen.font_xbig)).build());
- // Add the second piece
- tv.addPiece(new SpannableTextView.Piece.Builder(content).textColor(App.res.getColor(R.color.text_color_c8))
- .textSize((int) App.res.getDimension(R.dimen.font_middle)).build());
- // Display the final, styled text
- tv.display();
- }
- SpannableTextView tv = null;
- tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView0));
- context.createSpannableTextView(tv, "血糖\n", "记录血糖指数");
- tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView1));
- context.createSpannableTextView(tv, "血压\n", "记录血压指数");
- tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView2));
- context.createSpannableTextView(tv, "体重\n", "记录体重");
- tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView3));
- context.createSpannableTextView(tv, "饮食\n", "记录日常饮食");
- tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView4));
- context.createSpannableTextView(tv, "运动\n", "记录运动时间");
- <cn.tangdada.tangbang.widget.SpannableTextView
- android:id="@+id/spannableTextView0"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center_vertical"
- android:background="@drawable/line_bottom"
- android:drawableRight="@drawable/arrow_right"
- android:drawableLeft="@drawable/icon_0"
- android:gravity="center_vertical"
- android:lineSpacingExtra="4dp"
- android:paddingRight="16dp"
- android:singleLine="false" />
源码:
- package cn.tangdada.tangbang.widget;
- /*
- * Copyright (C) 2014 Henrique Boregio.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @author Henrique Boregio (hboregio@gmail.com)
- */
- import java.util.ArrayList;
- import java.util.List;
- import android.content.Context;
- import android.graphics.Color;
- import android.graphics.Typeface;
- import android.text.Spannable;
- import android.text.SpannableString;
- import android.text.style.AbsoluteSizeSpan;
- import android.text.style.BackgroundColorSpan;
- import android.text.style.ForegroundColorSpan;
- import android.text.style.RelativeSizeSpan;
- import android.text.style.StrikethroughSpan;
- import android.text.style.StyleSpan;
- import android.text.style.SubscriptSpan;
- import android.text.style.SuperscriptSpan;
- import android.text.style.UnderlineSpan;
- import android.util.AttributeSet;
- import android.widget.TextView;
- /**
- * usage:
- *
- * <pre>
- * SpannableTextView tv = (SpannableTextView) findViewById(R.id.spannable_textview);
- *
- * // Add the first piece "Central Park"
- * tv.addPiece(new SpannableTextView.Piece.Builder("Central Park, NY\n").textColor(Color.parseColor("#414141")).build());
- *
- * // Add the second piece "1.2 mi"
- * tv.addPiece(new SpannableTextView.Piece.Builder("1.2 mi ").textColor(Color.parseColor("#0081E2")).textSizeRelative(0.9f).build());
- *
- * // Add the third piece "from here"
- * tv.addPiece(new SpannableTextView.Piece.Builder("from here").textColor(Color.parseColor("#969696")).textSizeRelative(0.9f).build());
- *
- * // Display the final, styled text
- * tv.display();
- * </pre>
- *
- * <pre>
- * // grab the Piece at position 1
- * Piece piece = babushka.getPiece(1);
- *
- * // modify it's text
- * piece.setText("1.9 km ");
- *
- * // you must always call display after you alter a Piece's text
- * tv.display();
- * </pre>
- *
- * <pre>
- * Babushka Method Internal Span
- * textSize AbsoluteSizeSpan
- * textColor ForegroundColorSpan
- * textSizeRelative RelativeSizeSpan
- * backgroundColor BackgroundColorSpan
- * style StyleSpan
- * underline UnderlineSpan
- * strike StrikethroughSpan
- * superscript SuperscriptSpan
- * subscript SubscriptSpan
- * </pre>
- *
- * BabushkaText is a TextView which lets you customize the styling of parts of your text via Spannables, but without the
- * hassle of having to deal directly with Spannable themselves.
- *
- * The idea behind a BabushkaText is that it is made up of {@code Piece}s. Each Piece represents a section of the final
- * text displayed by this TextView, and each Piece may be styled independently from the other Pieces. When you put it
- * all together, the final results is still a a single TextView, but with a a very different graphic output.
- *
- *
- * https://github.com/quiqueqs/BabushkaText
- */
- public class SpannableTextView extends TextView
- {
- // some default params
- private static int DEFAULT_ABSOLUTE_TEXT_SIZE;
- private static float DEFAULT_RELATIVE_TEXT_SIZE = 1;
- private List<Piece> mPieces;
- /**
- * Create a new instance of a this class
- *
- * @param context
- */
- public SpannableTextView(Context context)
- {
- super(context);
- init();
- }
- public SpannableTextView(Context context, AttributeSet attrs)
- {
- super(context, attrs);
- init();
- }
- public SpannableTextView(Context context, AttributeSet attrs, int defStyleAttr)
- {
- super(context, attrs, defStyleAttr);
- init();
- }
- private void init()
- {
- mPieces = new ArrayList<Piece>();
- SpannableTextView.DEFAULT_ABSOLUTE_TEXT_SIZE = (int) getTextSize();
- }
- /**
- * Use this method to add a {@link SpannableTextView.BabushkaText.Piece} to a BabushkaText. Each
- * {@link SpannableTextView.BabushkaText.Piece } is added sequentially, so the order you call this method matters.
- *
- * @param aPiece the Piece
- */
- public void addPiece(Piece aPiece)
- {
- mPieces.add(aPiece);
- }
- /**
- * Adds a Piece at this specific location. The underlying data structure is a {@link java.util.List}, so expect the
- * same type of behaviour.
- *
- * @param aPiece the Piece to add.
- * @param location the index at which to add.
- */
- public void addPiece(Piece aPiece, int location)
- {
- mPieces.add(location, aPiece);
- }
- /**
- * Replaces the Piece at the specified location with this new Piece. The underlying data structure is a
- * {@link java.util.List}, so expect the same type of behaviour.
- *
- * @param newPiece the Piece to insert.
- * @param location the index at which to insert.
- */
- public void replacePieceAt(int location, Piece newPiece)
- {
- mPieces.set(location, newPiece);
- }
- /**
- * Removes the Piece at this specified location. The underlying data structure is a {@link java.util.List}, so
- * expect the same type of behaviour.
- *
- * @param location the index of the Piece to remove
- */
- public void removePiece(int location)
- {
- mPieces.remove(location);
- }
- /**
- * Clear all the Pieces, same as reset()
- */
- public void clearPiece()
- {
- mPieces.clear();
- }
- /**
- * Get a specific {@link SpannableTextView.BabushkaText.Piece} in position index.
- *
- * @param location position of Piece (0 based)
- * @return Piece o null if invalid index
- */
- public Piece getPiece(int location)
- {
- if (location >= 0 && location < mPieces.size())
- {
- return mPieces.get(location);
- }
- return null;
- }
- /**
- * Call this method when you're done adding {@link SpannableTextView.BabushkaText.Piece}s and want this TextView to
- * display the final, styled version of it's String contents.
- *
- * You MUST also call this method whenever you make a modification to the text of a Piece that has already been
- * displayed.
- */
- public void display()
- {
- // generate the final string based on the pieces
- StringBuilder builder = new StringBuilder();
- for (Piece aPiece : mPieces)
- {
- builder.append(aPiece.text);
- }
- // apply spans
- int cursor = 0;
- SpannableString finalString = new SpannableString(builder.toString());
- for (Piece aPiece : mPieces)
- {
- applySpannablesTo(aPiece, finalString, cursor, cursor + aPiece.text.length());
- cursor += aPiece.text.length();
- }
- // set the styled text
- setText(finalString);
- }
- private void applySpannablesTo(Piece aPiece, SpannableString finalString, int start, int end)
- {
- if (aPiece.subscript)
- {
- finalString.setSpan(new SubscriptSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- if (aPiece.superscript)
- {
- finalString.setSpan(new SuperscriptSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- if (aPiece.strike)
- {
- finalString.setSpan(new StrikethroughSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- if (aPiece.underline)
- {
- finalString.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- // style
- finalString.setSpan(new StyleSpan(aPiece.style), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- // absolute text size
- finalString.setSpan(new AbsoluteSizeSpan(aPiece.textSize), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- // relative text size
- finalString.setSpan(new RelativeSizeSpan(aPiece.textSizeRelative), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- // text color
- finalString.setSpan(new ForegroundColorSpan(aPiece.textColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- // background color
- if (aPiece.backgroundColor != -1)
- {
- finalString.setSpan(new BackgroundColorSpan(aPiece.backgroundColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- }
- /**
- * Resets the styling of this view and sets it's content to an empty String.
- */
- public void reset()
- {
- mPieces = new ArrayList<Piece>();
- setText("");
- }
- /**
- * Change text color of all pieces of textview.
- */
- public void changeTextColor(int textColor)
- {
- for (Piece mPiece : mPieces)
- {
- mPiece.setTextColor(textColor);
- }
- display();
- }
- /**
- * A Piece represents a part of the text that you want to style. Say for example you want this BabushkaText to
- * display "Hello World" such that "Hello" is displayed in Bold and "World" is displayed in Italics. Since these
- * have different styles, they are both separate Pieces.
- *
- * You create a Piece by using it's {@link SpannableTextView.BabushkaText.Piece.Builder}
- *
- */
- public static class Piece
- {
- private String text;
- private int textColor;
- private final int textSize;
- private final int backgroundColor;
- private final float textSizeRelative;
- private final int style;
- private final boolean underline;
- private final boolean superscript;
- private final boolean strike;
- private final boolean subscript;
- public Piece(Builder builder)
- {
- this.text = builder.text;
- this.textSize = builder.textSize;
- this.textColor = builder.textColor;
- this.backgroundColor = builder.backgroundColor;
- this.textSizeRelative = builder.textSizeRelative;
- this.style = builder.style;
- this.underline = builder.underline;
- this.superscript = builder.superscript;
- this.subscript = builder.subscript;
- this.strike = builder.strike;
- }
- /**
- * Sets the text of this Piece. If you're creating a new Piece, you should do so using it's
- * {@link SpannableTextView.BabushkaText.Piece.Builder}.
- *
- * Use this method if you want to modify the text of an existing Piece that is already displayed. After doing
- * so, you MUST call {@code display()} for the changes to show up.
- *
- * @param text the text to display
- */
- public void setText(String text)
- {
- this.text = text;
- }
- /**
- * Sets the text color of this Piece. If you're creating a new Piece, you should do so using it's
- * {@link SpannableTextView.BabushkaText.Piece.Builder}.
- *
- * Use this method if you want to change the text color of an existing Piece that is already displayed. After
- * doing so, you MUST call {@code display()} for the changes to show up.
- *
- * @param color of text (it is NOT android Color resources ID, use getResources().getColor(R.color.colorId) for
- * it)
- */
- public void setTextColor(int textColor)
- {
- this.textColor = textColor;
- }
- /**
- * Builder of Pieces
- */
- public static class Builder
- {
- // required
- private final String text;
- // optional
- private int textSize = DEFAULT_ABSOLUTE_TEXT_SIZE;
- private int textColor = Color.BLACK;
- private int backgroundColor = -1;
- private float textSizeRelative = DEFAULT_RELATIVE_TEXT_SIZE;
- private int style = Typeface.NORMAL;
- private boolean underline = false;
- private boolean strike = false;
- private boolean superscript = false;
- private boolean subscript = false;
- /**
- * Creates a new Builder for this Piece.
- *
- * @param text the text of this Piece
- */
- public Builder(String text)
- {
- this.text = text;
- }
- /**
- * Sets the absolute text size.
- *
- * @param textSize text size in pixels
- * @return a Builder
- */
- public Builder textSize(int textSize)
- {
- this.textSize = textSize;
- return this;
- }
- /**
- * Sets the text color.
- *
- * @param textColor the color
- * @return a Builder
- */
- public Builder textColor(int textColor)
- {
- this.textColor = textColor;
- return this;
- }
- /**
- * Sets the background color.
- *
- * @param backgroundColor the color
- * @return a Builder
- */
- public Builder backgroundColor(int backgroundColor)
- {
- this.backgroundColor = backgroundColor;
- return this;
- }
- /**
- * Sets the relative text size.
- *
- * @param textSizeRelative relative text size
- * @return a Builder
- */
- public Builder textSizeRelative(float textSizeRelative)
- {
- this.textSizeRelative = textSizeRelative;
- return this;
- }
- /**
- * Sets a style to this Piece.
- *
- * @param style see {@link android.graphics.Typeface}
- * @return a Builder
- */
- public Builder style(int style)
- {
- this.style = style;
- return this;
- }
- /**
- * Underlines this Piece.
- *
- * @return a Builder
- */
- public Builder underline()
- {
- this.underline = true;
- return this;
- }
- /**
- * Strikes this Piece.
- *
- * @return a Builder
- */
- public Builder strike()
- {
- this.strike = true;
- return this;
- }
- /**
- * Sets this Piece as a superscript.
- *
- * @return a Builder
- */
- public Builder superscript()
- {
- this.superscript = true;
- return this;
- }
- /**
- * Sets this Piece as a subscript.
- *
- * @return a Builder
- */
- public Builder subscript()
- {
- this.subscript = true;
- return this;
- }
- /**
- * Creates a {@link SpannableTextView.BabushkaText.Piece} with the customized parameters.
- *
- * @return a Piece
- */
- public Piece build()
- {
- return new Piece(this);
- }
- }
- }
- }
试着结合这个类Phrase.java那就更爽了;
ColorPhrase实现处理带颜色的字符串
https://github.com/THEONE10211024/ColorPhrase
https://github.com/quiqueqs/BabushkaText
Spanny实现字符串样式处理
https://github.com/binaryfork/Spanny
高效快捷解决一个TextView显示多种字体的控件SpannableTextView的更多相关文章
- 解决CentOS无法显示中文字体 | 系统运维 | Web2.0
解决CentOS无法显示中文字体 | 系统运维 | Web2.0 About Me 博客园 devops 前端 张家港水蜜桃 傍晚好! 2013年09月12日 17:56:08 ...
- 一个Activity掌握Android5.0新控件 (转)
原文地址:http://blog.csdn.net/lavor_zl/article/details/51279386 谷歌在推出Android5.0的同时推出了一些新控件,Android5.0中最常 ...
- WebBrowser无法显示招商银行password输入控件的问题
本文由CharlesSimonyi发表于CSDN博客:http://blog.csdn.net/charlessimonyi/article/details/30479131转载请注明出处 之前就看到 ...
- 一个Activity掌握Android4.0新控件 (转)
原文地址:http://blog.csdn.net/lavor_zl/article/details/51261380 谷歌在推出Android4.0的同时推出了一些新控件,Android4.0中最常 ...
- C# 时间控件 竖直进度条 饼图显示 仪表盘 按钮基础控件库
Prepare 本文将使用一个NuGet公开的组件来实现一些特殊的控件显示,方便大家进行快速的开发系统. 在Visual Studio 中的NuGet管理器中可以下载安装,也可以直接在NuGet控制台 ...
- 解决SurfaceView调用setZOrderOnTop(true)遮挡其他控件
解决SurfaceView调用setZOrderOnTop(true)遮挡其他控件的问题 http://marller.blog.51cto.com/8699646/1762028 FAQ: Surf ...
- Android中查找一个Layout中指定的子控件
我们通常希望查找一个页面中指定类型的控件,单个控件知道id很容易找到,但是如果是多个呢?或者说是在程序中自定义的控件,且不知道id怎么办呢?如想找到页面中的Spinner,可用以下方法 /** * 从 ...
- 解决tableView中cell动态加载控件的重用问题
解决tableView中cell动态加载控件的重用问题 tableView的cell,有时候需要在运行时取得对应的数据后才能够动态的创建该cell中的控件并加载到该cell中,此时,你一定会遇到重用问 ...
- SilverLight:基础控件使用(4)-日期显示和选择类控件
ylbtech-SilverLight-Basic-Control:基础控件使用(4)-日期显示和选择类控件 Calendar,DatePicker 1.A,返回顶部 Calendar控件(日期控件) ...
随机推荐
- iOS 中如何将View设置为圆角的矩形?
今天刚好需要添加一个圆角的view. 必须先导入头文件. #import <QuartzCore/QuartzCore.h> bgView.layer.cornerRadius = cor ...
- 23. Sum Root to Leaf Numbers
Sum Root to Leaf Numbers Given a binary tree containing digits from 0-9 only, each root-to-leaf path ...
- 魅族手机(魅蓝note)无法作为调试设备连接到mac问题的解决
问题描述: OS X(Yosemite),ADB(1.0.32),Android Studio(1.0.1),魅蓝note手机(m1 note,Android 4.4.4,Flyme OS 4.2.0 ...
- React 附件动画API ReactCSSTransitionGroup
React为动画提供了一个附加组件ReactTransitionGroup,这个附加组件是动画的底层API,并且还提供了一个附件组件ReactCSSTransitionGroup,ReactCSSTr ...
- lintcode-【简单题】快乐数
题目: 写一个算法来判断一个数是不是"快乐数". 一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为他每个位置上的数字的平方和,然后重复这个过程直到这个数变为1,或是 ...
- dedecms 打印出网站所有 文章标题和链接(URL)的方法
{dede:arclist row="100000"} <li>[field:fulltitle/]***网站URL地址***[field:arcurl/]</l ...
- python之fabric(二):执行模式(转)
执行模式 执行模式可以让你在多个主机上执行多个任务. 执行策略: 默认fabric是单个有序地执行方法,其行为如下: 1. 创建一系列任务,通过fab任务执行要执行的任务: 2. 根据主机列表定义,去 ...
- 【译】为什么这样宏定义#define INT_MIN (-2147483647 - 1)?
2的32次方为2147483648*2,0~(2147483648*2-1)这是32位机上无符号整数代表的范围.而32机的int范围为-2147483648~+2147483647 stackover ...
- vbs获取命令行里的参数
var args1=WScript.Arguments.Item(0) var args2=WScript.Arguments.Item(1)
- 基于PHP生成静态页的实现方法
t1.php 复制代码 代码如下: <?php// 方法一根据模版生成静态页面// replaceTemplateString函数用于替换模板中指定字符串function replaceTemp ...