• 高效快捷解决一个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 

    用法也很简单: 

    Java代码  收藏代码
    1. /** 
    2.      * 为一个TextView设置多种字体(大小,颜色,背景色等) 
    3.      *  
    4.      * @param tv 
    5.      * @param title 
    6.      * @param content 
    7.      */  
    8.     public void createSpannableTextView(SpannableTextView tv, String title, String content)  
    9.     {  
    10.   
    11.         // clear pieces  
    12.         tv.reset();  
    13.         // Add the first piece  
    14.         tv.addPiece(new SpannableTextView.Piece.Builder(title).textColor(App.res.getColor(R.color.text_color_c2))  
    15.                 .textSize((int) App.res.getDimension(R.dimen.font_xbig)).build());  
    16.   
    17.         // Add the second piece  
    18.         tv.addPiece(new SpannableTextView.Piece.Builder(content).textColor(App.res.getColor(R.color.text_color_c8))  
    19.                 .textSize((int) App.res.getDimension(R.dimen.font_middle)).build());  
    20.   
    21.         // Display the final, styled text  
    22.         tv.display();  
    23.     }  



    Java代码  收藏代码
    1. SpannableTextView tv = null;  
    2.                 tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView0));  
    3.                 context.createSpannableTextView(tv, "血糖 ", "记录血糖指数");  
    4.                 tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView1));  
    5.                 context.createSpannableTextView(tv, "血压 ", "记录血压指数");  
    6.                 tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView2));  
    7.                 context.createSpannableTextView(tv, "体重 ", "记录体重");  
    8.                 tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView3));  
    9.                 context.createSpannableTextView(tv, "饮食 ", "记录日常饮食");  
    10.                 tv = (SpannableTextView) (v.findViewById(R.id.spannableTextView4));  
    11.                 context.createSpannableTextView(tv, "运动 ", "记录运动时间");  



    Xml代码  收藏代码
    1. <cn.tangdada.tangbang.widget.SpannableTextView  
    2.                 android:id="@+id/spannableTextView0"  
    3.                 android:layout_width="match_parent"  
    4.                 android:layout_height="match_parent"  
    5.                 android:layout_gravity="center_vertical"  
    6.                 android:background="@drawable/line_bottom"  
    7.                 android:drawableRight="@drawable/arrow_right"  
    8.                 android:drawableLeft="@drawable/icon_0"  
    9.                 android:gravity="center_vertical"  
    10.                 android:lineSpacingExtra="4dp"  
    11.                 android:paddingRight="16dp"  
    12.                 android:singleLine="false" />  



    源码: 

    Java代码  收藏代码
    1. package cn.tangdada.tangbang.widget;  
    2.   
    3. /* 
    4.  * Copyright (C) 2014 Henrique Boregio. 
    5.  * 
    6.  * Licensed under the Apache License, Version 2.0 (the "License"); 
    7.  * you may not use this file except in compliance with the License. 
    8.  * You may obtain a copy of the License at 
    9.  * 
    10.  *      http://www.apache.org/licenses/LICENSE-2.0 
    11.  * 
    12.  * Unless required by applicable law or agreed to in writing, software 
    13.  * distributed under the License is distributed on an "AS IS" BASIS, 
    14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
    15.  * See the License for the specific language governing permissions and 
    16.  * limitations under the License. 
    17.  * 
    18.  * @author Henrique Boregio (hboregio@gmail.com) 
    19.  */  
    20.   
    21. import java.util.ArrayList;  
    22. import java.util.List;  
    23.   
    24. import android.content.Context;  
    25. import android.graphics.Color;  
    26. import android.graphics.Typeface;  
    27. import android.text.Spannable;  
    28. import android.text.SpannableString;  
    29. import android.text.style.AbsoluteSizeSpan;  
    30. import android.text.style.BackgroundColorSpan;  
    31. import android.text.style.ForegroundColorSpan;  
    32. import android.text.style.RelativeSizeSpan;  
    33. import android.text.style.StrikethroughSpan;  
    34. import android.text.style.StyleSpan;  
    35. import android.text.style.SubscriptSpan;  
    36. import android.text.style.SuperscriptSpan;  
    37. import android.text.style.UnderlineSpan;  
    38. import android.util.AttributeSet;  
    39. import android.widget.TextView;  
    40.   
    41. /** 
    42.  * usage: 
    43.  *  
    44.  * <pre> 
    45.  * SpannableTextView tv = (SpannableTextView) findViewById(R.id.spannable_textview); 
    46.  *  
    47.  * // Add the first piece &quot;Central Park&quot; 
    48.  * tv.addPiece(new SpannableTextView.Piece.Builder(&quot;Central Park, NY &quot;).textColor(Color.parseColor(&quot;#414141&quot;)).build()); 
    49.  *  
    50.  * // Add the second piece &quot;1.2 mi&quot; 
    51.  * tv.addPiece(new SpannableTextView.Piece.Builder(&quot;1.2 mi &quot;).textColor(Color.parseColor(&quot;#0081E2&quot;)).textSizeRelative(0.9f).build()); 
    52.  *  
    53.  * // Add the third piece &quot;from here&quot; 
    54.  * tv.addPiece(new SpannableTextView.Piece.Builder(&quot;from here&quot;).textColor(Color.parseColor(&quot;#969696&quot;)).textSizeRelative(0.9f).build()); 
    55.  *  
    56.  * // Display the final, styled text 
    57.  * tv.display(); 
    58.  * </pre> 
    59.  *  
    60.  * <pre> 
    61.  * // grab the Piece at position 1 
    62.  * Piece piece = babushka.getPiece(1); 
    63.  *  
    64.  * // modify it's text 
    65.  * piece.setText(&quot;1.9 km &quot;); 
    66.  *  
    67.  * // you must always call display after you alter a Piece's text 
    68.  * tv.display(); 
    69.  * </pre> 
    70.  *  
    71.  * <pre> 
    72.  * Babushka Method      Internal Span 
    73.  *     textSize            AbsoluteSizeSpan 
    74.  *     textColor           ForegroundColorSpan 
    75.  *     textSizeRelative    RelativeSizeSpan 
    76.  *     backgroundColor     BackgroundColorSpan 
    77.  *     style               StyleSpan 
    78.  *     underline           UnderlineSpan 
    79.  *     strike              StrikethroughSpan 
    80.  *     superscript         SuperscriptSpan 
    81.  *     subscript           SubscriptSpan 
    82.  * </pre> 
    83.  *  
    84.  * BabushkaText is a TextView which lets you customize the styling of parts of your text via Spannables, but without the 
    85.  * hassle of having to deal directly with Spannable themselves. 
    86.  *  
    87.  * The idea behind a BabushkaText is that it is made up of {@code Piece}s. Each Piece represents a section of the final 
    88.  * text displayed by this TextView, and each Piece may be styled independently from the other Pieces. When you put it 
    89.  * all together, the final results is still a a single TextView, but with a a very different graphic output. 
    90.  *  
    91.  *  
    92.  * https://github.com/quiqueqs/BabushkaText 
    93.  */  
    94. public class SpannableTextView extends TextView  
    95. {  
    96.   
    97.     // some default params  
    98.     private static int DEFAULT_ABSOLUTE_TEXT_SIZE;  
    99.   
    100.     private static float DEFAULT_RELATIVE_TEXT_SIZE = 1;  
    101.   
    102.     private List<Piece> mPieces;  
    103.   
    104.     /** 
    105.      * Create a new instance of a this class 
    106.      *  
    107.      * @param context 
    108.      */  
    109.     public SpannableTextView(Context context)  
    110.     {  
    111.         super(context);  
    112.         init();  
    113.     }  
    114.   
    115.     public SpannableTextView(Context context, AttributeSet attrs)  
    116.     {  
    117.         super(context, attrs);  
    118.         init();  
    119.     }  
    120.   
    121.     public SpannableTextView(Context context, AttributeSet attrs, int defStyleAttr)  
    122.     {  
    123.         super(context, attrs, defStyleAttr);  
    124.         init();  
    125.     }  
    126.   
    127.     private void init()  
    128.     {  
    129.         mPieces = new ArrayList<Piece>();  
    130.         SpannableTextView.DEFAULT_ABSOLUTE_TEXT_SIZE = (int) getTextSize();  
    131.     }  
    132.   
    133.     /** 
    134.      * Use this method to add a {@link SpannableTextView.BabushkaText.Piece} to a BabushkaText. Each 
    135.      * {@link SpannableTextView.BabushkaText.Piece } is added sequentially, so the order you call this method matters. 
    136.      *  
    137.      * @param aPiece the Piece 
    138.      */  
    139.     public void addPiece(Piece aPiece)  
    140.     {  
    141.         mPieces.add(aPiece);  
    142.     }  
    143.   
    144.     /** 
    145.      * Adds a Piece at this specific location. The underlying data structure is a {@link java.util.List}, so expect the 
    146.      * same type of behaviour. 
    147.      *  
    148.      * @param aPiece the Piece to add. 
    149.      * @param location the index at which to add. 
    150.      */  
    151.     public void addPiece(Piece aPiece, int location)  
    152.     {  
    153.         mPieces.add(location, aPiece);  
    154.     }  
    155.   
    156.     /** 
    157.      * Replaces the Piece at the specified location with this new Piece. The underlying data structure is a 
    158.      * {@link java.util.List}, so expect the same type of behaviour. 
    159.      *  
    160.      * @param newPiece the Piece to insert. 
    161.      * @param location the index at which to insert. 
    162.      */  
    163.     public void replacePieceAt(int location, Piece newPiece)  
    164.     {  
    165.         mPieces.set(location, newPiece);  
    166.     }  
    167.   
    168.     /** 
    169.      * Removes the Piece at this specified location. The underlying data structure is a {@link java.util.List}, so 
    170.      * expect the same type of behaviour. 
    171.      *  
    172.      * @param location the index of the Piece to remove 
    173.      */  
    174.     public void removePiece(int location)  
    175.     {  
    176.         mPieces.remove(location);  
    177.     }  
    178.   
    179.     /** 
    180.      * Clear all the Pieces, same as reset() 
    181.      */  
    182.     public void clearPiece()  
    183.     {  
    184.         mPieces.clear();  
    185.     }  
    186.   
    187.     /** 
    188.      * Get a specific {@link SpannableTextView.BabushkaText.Piece} in position index. 
    189.      *  
    190.      * @param location position of Piece (0 based) 
    191.      * @return Piece o null if invalid index 
    192.      */  
    193.     public Piece getPiece(int location)  
    194.     {  
    195.         if (location >= 0 && location < mPieces.size())  
    196.         {  
    197.             return mPieces.get(location);  
    198.         }  
    199.   
    200.         return null;  
    201.     }  
    202.   
    203.     /** 
    204.      * Call this method when you're done adding {@link SpannableTextView.BabushkaText.Piece}s and want this TextView to 
    205.      * display the final, styled version of it's String contents. 
    206.      *  
    207.      * You MUST also call this method whenever you make a modification to the text of a Piece that has already been 
    208.      * displayed. 
    209.      */  
    210.     public void display()  
    211.     {  
    212.   
    213.         // generate the final string based on the pieces  
    214.         StringBuilder builder = new StringBuilder();  
    215.         for (Piece aPiece : mPieces)  
    216.         {  
    217.             builder.append(aPiece.text);  
    218.         }  
    219.   
    220.         // apply spans  
    221.         int cursor = 0;  
    222.         SpannableString finalString = new SpannableString(builder.toString());  
    223.         for (Piece aPiece : mPieces)  
    224.         {  
    225.             applySpannablesTo(aPiece, finalString, cursor, cursor + aPiece.text.length());  
    226.             cursor += aPiece.text.length();  
    227.         }  
    228.   
    229.         // set the styled text  
    230.         setText(finalString);  
    231.     }  
    232.   
    233.     private void applySpannablesTo(Piece aPiece, SpannableString finalString, int start, int end)  
    234.     {  
    235.   
    236.         if (aPiece.subscript)  
    237.         {  
    238.             finalString.setSpan(new SubscriptSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    239.         }  
    240.   
    241.         if (aPiece.superscript)  
    242.         {  
    243.             finalString.setSpan(new SuperscriptSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    244.         }  
    245.   
    246.         if (aPiece.strike)  
    247.         {  
    248.             finalString.setSpan(new StrikethroughSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    249.         }  
    250.   
    251.         if (aPiece.underline)  
    252.         {  
    253.             finalString.setSpan(new UnderlineSpan(), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    254.         }  
    255.   
    256.         // style  
    257.         finalString.setSpan(new StyleSpan(aPiece.style), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    258.   
    259.         // absolute text size  
    260.         finalString.setSpan(new AbsoluteSizeSpan(aPiece.textSize), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    261.   
    262.         // relative text size  
    263.         finalString.setSpan(new RelativeSizeSpan(aPiece.textSizeRelative), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    264.   
    265.         // text color  
    266.         finalString.setSpan(new ForegroundColorSpan(aPiece.textColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    267.   
    268.         // background color  
    269.         if (aPiece.backgroundColor != -1)  
    270.         {  
    271.             finalString.setSpan(new BackgroundColorSpan(aPiece.backgroundColor), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);  
    272.         }  
    273.     }  
    274.   
    275.     /** 
    276.      * Resets the styling of this view and sets it's content to an empty String. 
    277.      */  
    278.     public void reset()  
    279.     {  
    280.         mPieces = new ArrayList<Piece>();  
    281.         setText("");  
    282.     }  
    283.   
    284.     /** 
    285.      * Change text color of all pieces of textview. 
    286.      */  
    287.     public void changeTextColor(int textColor)  
    288.     {  
    289.         for (Piece mPiece : mPieces)  
    290.         {  
    291.             mPiece.setTextColor(textColor);  
    292.         }  
    293.         display();  
    294.     }  
    295.   
    296.     /** 
    297.      * A Piece represents a part of the text that you want to style. Say for example you want this BabushkaText to 
    298.      * display "Hello World" such that "Hello" is displayed in Bold and "World" is displayed in Italics. Since these 
    299.      * have different styles, they are both separate Pieces. 
    300.      *  
    301.      * You create a Piece by using it's {@link SpannableTextView.BabushkaText.Piece.Builder} 
    302.      *  
    303.      */  
    304.     public static class Piece  
    305.     {  
    306.   
    307.         private String text;  
    308.   
    309.         private int textColor;  
    310.   
    311.         private final int textSize;  
    312.   
    313.         private final int backgroundColor;  
    314.   
    315.         private final float textSizeRelative;  
    316.   
    317.         private final int style;  
    318.   
    319.         private final boolean underline;  
    320.   
    321.         private final boolean superscript;  
    322.   
    323.         private final boolean strike;  
    324.   
    325.         private final boolean subscript;  
    326.   
    327.         public Piece(Builder builder)  
    328.         {  
    329.             this.text = builder.text;  
    330.             this.textSize = builder.textSize;  
    331.             this.textColor = builder.textColor;  
    332.             this.backgroundColor = builder.backgroundColor;  
    333.             this.textSizeRelative = builder.textSizeRelative;  
    334.             this.style = builder.style;  
    335.             this.underline = builder.underline;  
    336.             this.superscript = builder.superscript;  
    337.             this.subscript = builder.subscript;  
    338.             this.strike = builder.strike;  
    339.         }  
    340.   
    341.         /** 
    342.          * Sets the text of this Piece. If you're creating a new Piece, you should do so using it's 
    343.          * {@link SpannableTextView.BabushkaText.Piece.Builder}. 
    344.          *  
    345.          * Use this method if you want to modify the text of an existing Piece that is already displayed. After doing 
    346.          * so, you MUST call {@code display()} for the changes to show up. 
    347.          *  
    348.          * @param text the text to display 
    349.          */  
    350.         public void setText(String text)  
    351.         {  
    352.             this.text = text;  
    353.         }  
    354.   
    355.         /** 
    356.          * Sets the text color of this Piece. If you're creating a new Piece, you should do so using it's 
    357.          * {@link SpannableTextView.BabushkaText.Piece.Builder}. 
    358.          *  
    359.          * Use this method if you want to change the text color of an existing Piece that is already displayed. After 
    360.          * doing so, you MUST call {@code display()} for the changes to show up. 
    361.          *  
    362.          * @param color of text (it is NOT android Color resources ID, use getResources().getColor(R.color.colorId) for 
    363.          *            it) 
    364.          */  
    365.         public void setTextColor(int textColor)  
    366.         {  
    367.             this.textColor = textColor;  
    368.         }  
    369.   
    370.         /** 
    371.          * Builder of Pieces 
    372.          */  
    373.         public static class Builder  
    374.         {  
    375.   
    376.             // required  
    377.             private final String text;  
    378.   
    379.             // optional  
    380.             private int textSize = DEFAULT_ABSOLUTE_TEXT_SIZE;  
    381.   
    382.             private int textColor = Color.BLACK;  
    383.   
    384.             private int backgroundColor = -1;  
    385.   
    386.             private float textSizeRelative = DEFAULT_RELATIVE_TEXT_SIZE;  
    387.   
    388.             private int style = Typeface.NORMAL;  
    389.   
    390.             private boolean underline = false;  
    391.   
    392.             private boolean strike = false;  
    393.   
    394.             private boolean superscript = false;  
    395.   
    396.             private boolean subscript = false;  
    397.   
    398.             /** 
    399.              * Creates a new Builder for this Piece. 
    400.              *  
    401.              * @param text the text of this Piece 
    402.              */  
    403.             public Builder(String text)  
    404.             {  
    405.                 this.text = text;  
    406.             }  
    407.   
    408.             /** 
    409.              * Sets the absolute text size. 
    410.              *  
    411.              * @param textSize text size in pixels 
    412.              * @return a Builder 
    413.              */  
    414.             public Builder textSize(int textSize)  
    415.             {  
    416.                 this.textSize = textSize;  
    417.                 return this;  
    418.             }  
    419.   
    420.             /** 
    421.              * Sets the text color. 
    422.              *  
    423.              * @param textColor the color 
    424.              * @return a Builder 
    425.              */  
    426.             public Builder textColor(int textColor)  
    427.             {  
    428.                 this.textColor = textColor;  
    429.                 return this;  
    430.             }  
    431.   
    432.             /** 
    433.              * Sets the background color. 
    434.              *  
    435.              * @param backgroundColor the color 
    436.              * @return a Builder 
    437.              */  
    438.             public Builder backgroundColor(int backgroundColor)  
    439.             {  
    440.                 this.backgroundColor = backgroundColor;  
    441.                 return this;  
    442.             }  
    443.   
    444.             /** 
    445.              * Sets the relative text size. 
    446.              *  
    447.              * @param textSizeRelative relative text size 
    448.              * @return a Builder 
    449.              */  
    450.             public Builder textSizeRelative(float textSizeRelative)  
    451.             {  
    452.                 this.textSizeRelative = textSizeRelative;  
    453.                 return this;  
    454.             }  
    455.   
    456.             /** 
    457.              * Sets a style to this Piece. 
    458.              *  
    459.              * @param style see {@link android.graphics.Typeface} 
    460.              * @return a Builder 
    461.              */  
    462.             public Builder style(int style)  
    463.             {  
    464.                 this.style = style;  
    465.                 return this;  
    466.             }  
    467.   
    468.             /** 
    469.              * Underlines this Piece. 
    470.              *  
    471.              * @return a Builder 
    472.              */  
    473.             public Builder underline()  
    474.             {  
    475.                 this.underline = true;  
    476.                 return this;  
    477.             }  
    478.   
    479.             /** 
    480.              * Strikes this Piece. 
    481.              *  
    482.              * @return a Builder 
    483.              */  
    484.             public Builder strike()  
    485.             {  
    486.                 this.strike = true;  
    487.                 return this;  
    488.             }  
    489.   
    490.             /** 
    491.              * Sets this Piece as a superscript. 
    492.              *  
    493.              * @return a Builder 
    494.              */  
    495.             public Builder superscript()  
    496.             {  
    497.                 this.superscript = true;  
    498.                 return this;  
    499.             }  
    500.   
    501.             /** 
    502.              * Sets this Piece as a subscript. 
    503.              *  
    504.              * @return a Builder 
    505.              */  
    506.             public Builder subscript()  
    507.             {  
    508.                 this.subscript = true;  
    509.                 return this;  
    510.             }  
    511.   
    512.             /** 
    513.              * Creates a {@link SpannableTextView.BabushkaText.Piece} with the customized parameters. 
    514.              *  
    515.              * @return a Piece 
    516.              */  
    517.             public Piece build()  
    518.             {  
    519.                 return new Piece(this);  
    520.             }  
    521.         }  
    522.     }  
    523.   
    524. }  



    试着结合这个类Phrase.java那就更爽了; 
    ColorPhrase实现处理带颜色的字符串 
    https://github.com/THEONE10211024/ColorPhrase 

    https://github.com/quiqueqs/BabushkaText 

    Spanny实现字符串样式处理 
    https://github.com/binaryfork/Spanny

  • 相关阅读:
    POJ 2752 KMP中next数组的理解
    KMP详解
    HDU 3221 矩阵快速幂+欧拉函数+降幂公式降幂
    POJ 3220 位运算+搜索
    反素数深度分析
    POJ 2886 线段树单点更新
    求反素数的方法
    CV第八课 GPU/CPU
    49. 字母异位词分组
    48. 旋转图像
  • 原文地址:https://www.cnblogs.com/gao-chun/p/4849348.html
Copyright © 2020-2023  润新知