mDrawableRef;
84 | }
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/textdecor/src/main/java/com/decorator/text/textdecor/custom_decors/TypefaceResourceSpan.java:
--------------------------------------------------------------------------------
1 | package com.decorator.text.textdecor.custom_decors;
2 |
3 | import android.content.Context;
4 | import android.content.res.AssetManager;
5 | import android.graphics.Typeface;
6 | import android.os.Parcel;
7 | import android.text.ParcelableSpan;
8 | import android.text.TextPaint;
9 | import android.text.style.MetricAffectingSpan;
10 | import android.util.Log;
11 |
12 | /**
13 | * Created by caifangmao on 15/2/14.
14 | *
15 | * from http://stackoverflow.com/questions/8710300/how-to-set-font-style-of-selected-text-using-custom-typeface-through-spannable-m
16 | *
17 | */
18 | public class TypefaceResourceSpan extends MetricAffectingSpan implements ParcelableSpan {
19 |
20 | private String resourceName_;
21 | private Typeface tf_;
22 |
23 | private Context context;
24 |
25 | public TypefaceResourceSpan(Context context, String resourceName) {
26 | super();
27 |
28 | this.context = context;
29 | resourceName_=resourceName;
30 | tf_=createTypeface(resourceName_);
31 | }
32 |
33 | public TypefaceResourceSpan(Context context, Parcel src) {
34 | this.context = context;
35 | resourceName_ = src.readString();
36 | tf_=createTypeface(resourceName_);
37 | }
38 |
39 | private Typeface createTypeface(String resourceName) {
40 | Typeface result=null;
41 | Context c=context;
42 | if (c==null) {
43 | Log.e("TypefaceResourceSpan", "Application context is null!");
44 | }
45 | AssetManager am=c.getAssets();
46 | if (am==null) {
47 | Log.e("TypefaceResourceSpan", "AssetManager is null!");
48 | }
49 | result=Typeface.createFromAsset(am, resourceName);
50 | return result;
51 | }
52 |
53 | public void writeToParcel(Parcel dest, int flags) {
54 | dest.writeString(resourceName_);
55 | }
56 |
57 | @Override
58 | public void updateMeasureState(TextPaint p) {
59 | Typeface old=p.getTypeface();
60 | if ( old != null && !old.isBold() && tf_.isBold() ) {
61 | p.setFakeBoldText(true);
62 | }
63 | if ( old != null && !old.isItalic() && tf_.isItalic() ) {
64 | p.setTextSkewX(-0.25f);
65 | }
66 | p.setTypeface(tf_);
67 | }
68 |
69 | @Override
70 | public void updateDrawState(TextPaint tp) {
71 | Typeface old=tp.getTypeface();
72 | if ( old != null && !old.isBold() && tf_.isBold() ) {
73 | tp.setFakeBoldText(true);
74 | }
75 | if ( old != null && !old.isItalic() && tf_.isItalic() ) {
76 | tp.setTextSkewX(-0.25f);
77 | }
78 | tp.setTypeface(tf_);
79 | }
80 |
81 | public int getSpanTypeId() {
82 | // TODO does this work???!?
83 | return 123456;
84 | }
85 |
86 | public int describeContents() {
87 | return 0;
88 | }
89 | }
--------------------------------------------------------------------------------
/textdecor/src/main/java/com/decorator/text/textdecor/custom_decors/RoundedBackgroundSpan.java:
--------------------------------------------------------------------------------
1 | package com.decorator.text.textdecor.custom_decors;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.LinearGradient;
5 | import android.graphics.Paint;
6 | import android.graphics.RectF;
7 | import android.text.style.ReplacementSpan;
8 |
9 | public class RoundedBackgroundSpan extends ReplacementSpan {
10 |
11 | private static final String TAG = "tag";
12 | private int cornerRadius = 1;
13 | private int paddingX = 15;
14 | private int paddingY = 1;
15 | private int backgroundColor;
16 | private int textColor;
17 | private Gravity gravity = Gravity.DEFAULT;
18 | private LinearGradient gradient = null;
19 |
20 | public RoundedBackgroundSpan(int cornerRadius, int paddingX, int backgroundColor, int textColor) {
21 | this.cornerRadius = cornerRadius;
22 | this.paddingX = paddingX;
23 | this.backgroundColor = backgroundColor;
24 | this.textColor = textColor;
25 | }
26 |
27 | public RoundedBackgroundSpan(int cornerRadius, int paddingX, LinearGradient gradient, int textColor) {
28 | this.cornerRadius = cornerRadius;
29 | this.paddingX = paddingX;
30 | this.gradient = gradient;
31 | this.textColor = textColor;
32 | }
33 |
34 | public RoundedBackgroundSpan(int cornerRadius, int paddingX, int backgroundColor, int textColor, Gravity gravity) {
35 | this.cornerRadius = cornerRadius;
36 | this.paddingX = paddingX;
37 | this.backgroundColor = backgroundColor;
38 | this.textColor = textColor;
39 | this.gravity = gravity;
40 | }
41 |
42 | @Override
43 | public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
44 | return (int) (paddingX + paint.measureText(text.subSequence(start, end).toString()) + paddingX);
45 | }
46 |
47 | @Override
48 | public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
49 |
50 | float width = paint.measureText(text.subSequence(start, end).toString());
51 |
52 | RectF rect = new RectF(
53 | x + gravity.getX(),
54 | top + top / gravity.getY(),
55 | x + width + 2 * paddingX,
56 | bottom + bottom / gravity.getY1()
57 | );
58 | if (gradient == null) {
59 | paint.setColor(backgroundColor);
60 | } else {
61 | paint.setShader(gradient);
62 | }
63 | canvas.drawRoundRect(rect, cornerRadius, cornerRadius, paint);
64 | paint.setShader(null);
65 | paint.setColor(textColor);
66 | canvas.drawText(text,
67 | start,
68 | end,
69 | x + paddingX,
70 | y + y / gravity.getY1(),
71 | paint);
72 |
73 | }
74 |
75 | public enum Gravity {
76 | TOP(0, -8, 0, -4),
77 | BOTTOM(0, 4, 0, 99),
78 | CENTER(0, 9, 0, -9),
79 | DEFAULT(0, 99, 0, 99);
80 |
81 | int x;
82 | int y;
83 | int x1;
84 | int y1;
85 |
86 | Gravity(int x, int y, int x1, int y1) {
87 | this.x = x;
88 | this.y = y;
89 | this.x1 = x1;
90 | this.y1 = y1;
91 | }
92 |
93 | public int getX() {
94 | return x;
95 | }
96 |
97 | public int getY() {
98 | return y;
99 | }
100 |
101 | public int getX1() {
102 | return x1;
103 | }
104 |
105 | public int getY1() {
106 | return y1;
107 | }
108 | }
109 | }
--------------------------------------------------------------------------------
/textdecor/src/main/java/com/decorator/text/textdecor/custom_decors/ArrowBackgroundSpan.java:
--------------------------------------------------------------------------------
1 | package com.decorator.text.textdecor.custom_decors;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.Path;
6 | import android.graphics.PointF;
7 |
8 | /**
9 | * Created by caifangmao on 15/2/14.
10 | */
11 | public class ArrowBackgroundSpan extends BackgroundSpannable {
12 |
13 | private Path startArrow;
14 | private Path endArrow;
15 |
16 | private int arrowColor;
17 | private int backgroundColor;
18 |
19 | public ArrowBackgroundSpan(int arrowColor, int backgroundColor){
20 |
21 | paint = new Paint(Paint.ANTI_ALIAS_FLAG);
22 |
23 | this.arrowColor = arrowColor;
24 | this.backgroundColor = backgroundColor;
25 |
26 | this.arrowColor = this.arrowColor >> 24 == 0 ? 0xFF000000 | this.arrowColor : this.arrowColor;
27 | this.backgroundColor = this.backgroundColor >> 24 == 0 ? 0xFF000000 | this.backgroundColor : this.backgroundColor;
28 |
29 | startArrow = new Path();
30 | endArrow = new Path();
31 | }
32 |
33 | @Override
34 | protected void drawLine(Canvas canvas, int width, int height, LinePosition linePosition){
35 | if(linePosition != LinePosition.LinePositionMiddle){
36 | startArrow.reset();
37 | endArrow.reset();
38 | int halfHeight = height / 2;
39 | float startP = (float) (-Math.PI / 2);
40 | float perP = (float) ((Math.PI * 2) / 10);
41 |
42 | PointF correctPoint = centerRadiusPoint(-halfHeight, halfHeight, startP, halfHeight);
43 | startArrow.moveTo(correctPoint.x, correctPoint.y);
44 | correctPoint = centerRadiusPoint(width + halfHeight, halfHeight, startP, halfHeight);
45 | endArrow.moveTo(correctPoint.x, correctPoint.y);
46 | for(int i = 1; i < 10; i++){
47 | if(i % 2 == 0){
48 | correctPoint = centerRadiusPoint(-halfHeight, halfHeight, startP + (i * perP), halfHeight);
49 | startArrow.lineTo(correctPoint.x, correctPoint.y);
50 | correctPoint = centerRadiusPoint(width + halfHeight, halfHeight, startP + (i * perP), halfHeight);
51 | endArrow.lineTo(correctPoint.x, correctPoint.y);
52 | }else{
53 | correctPoint = centerRadiusPoint(-halfHeight, halfHeight, startP + (i * perP), halfHeight / 1.8F);
54 | startArrow.lineTo(correctPoint.x, correctPoint.y);
55 | correctPoint = centerRadiusPoint(width + halfHeight, halfHeight, startP + (i * perP), halfHeight / 1.8F);
56 | endArrow.lineTo(correctPoint.x, correctPoint.y);
57 | }
58 | }
59 |
60 | startArrow.close();
61 | endArrow.close();
62 |
63 | startArrow.moveTo(0, 0);
64 | startArrow.lineTo(halfHeight, 0);
65 | startArrow.lineTo(0, halfHeight);
66 | startArrow.close();
67 |
68 | endArrow.moveTo(width, height);
69 | endArrow.lineTo(width, height - halfHeight);
70 | endArrow.lineTo(width - halfHeight, height);
71 | endArrow.close();
72 |
73 | }
74 |
75 | paint.setColor(backgroundColor);
76 | canvas.drawRect(0, 0, width, height, paint);
77 |
78 | paint.setColor(arrowColor);
79 | switch(linePosition){
80 | case LinePositionStart:
81 | canvas.drawPath(startArrow, paint);
82 | break;
83 | case LinePositionEnd:
84 | canvas.drawPath(endArrow, paint);
85 | break;
86 | case LinePositionSingle:
87 | canvas.drawPath(startArrow, paint);
88 | canvas.drawPath(endArrow, paint);
89 | break;
90 | }
91 | }
92 |
93 | private PointF centerRadiusPoint(int centerX, int centerY, double angle, double radius){
94 | float x = (float) (radius * Math.cos(angle) + centerX);
95 | float y = (float) (radius * Math.sin(angle) + centerY);
96 |
97 | return new PointF(x, y);
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/textdecor/src/main/java/com/decorator/text/textdecor/custom_decors/BackgroundSpannable.java:
--------------------------------------------------------------------------------
1 | package com.decorator.text.textdecor.custom_decors;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.Paint;
5 | import android.graphics.Rect;
6 | import android.text.Layout;
7 | import android.widget.TextView;
8 |
9 | /**
10 | * Created by caifangmao on 15/2/13.
11 | */
12 | public abstract class BackgroundSpannable {
13 |
14 | private int lineStart;
15 | private int lineEnd;
16 |
17 | private Rect[] lines;
18 |
19 | protected Paint paint;
20 |
21 | private TextView tv;
22 |
23 | private int start;
24 | private int end;
25 |
26 | /**当前行的
27 | * LinePositionStart Span从本行开始
28 | * LinePositionMiddle Span的start、end不在本行,但是包括了本行
29 | * LinePositionEnd Span到本行结束
30 | * LinePositionSingle Span的start、end都在本行
31 | */
32 | public enum LinePosition{
33 | LinePositionStart, LinePositionMiddle, LinePositionEnd, LinePositionSingle;
34 | }
35 |
36 | public void setMainTextView(TextView tv){
37 | this.tv = tv;
38 | }
39 |
40 | public void setRange(int start, int end){
41 | this.start = start;
42 | this.end = end;
43 | }
44 |
45 | public int getStart(){
46 | return this.start;
47 | }
48 |
49 | public int getEnd(){
50 | return this.end;
51 | }
52 |
53 | public void updateDrawState(Canvas canvas){
54 | Layout layout = tv.getLayout();
55 |
56 | if(layout != null){
57 |
58 | int saveBound = canvas.save();
59 |
60 | //计算剪裁矩形,保证绘制内容不会超出文本layout
61 | int clipLeft = tv.getPaddingLeft();
62 | int clipTop = tv.getTotalPaddingTop() + tv.getScrollY();
63 | int clipRight = canvas.getWidth() - tv.getPaddingRight();
64 | int clipBottom = clipTop + (tv.getHeight() - tv.getTotalPaddingTop() - tv.getTotalPaddingBottom());
65 |
66 | canvas.clipRect(clipLeft, clipTop, clipRight, clipBottom);
67 |
68 | //根据start end 获得起始行数和结束行数
69 | lineStart = layout.getLineForOffset(start);
70 | lineEnd = layout.getLineForOffset(end);
71 |
72 | if(lineStart != lineEnd){
73 | lines = new Rect[(lineEnd + 1) - lineStart];
74 |
75 | //计算每一行中包含当前span的矩形大小
76 | for(int i = lineStart; i <= lineEnd; i++){
77 | Rect rect = new Rect();
78 | layout.getLineBounds(i, rect);
79 |
80 | if(i == lineStart){
81 | rect.left = (int) layout.getPrimaryHorizontal(start);
82 | }
83 |
84 | if(i == lineEnd){
85 | rect.right = (int) layout.getSecondaryHorizontal(end);
86 | }else{
87 | float[] width = new float[1];
88 | String t = layout.getText().subSequence(layout.getLineEnd(i) - 1, layout.getLineEnd(i)).toString();
89 | layout.getPaint().getTextWidths(t, width);
90 | rect.right = (int) (layout.getSecondaryHorizontal(layout.getLineEnd(i) - 1) + width[0]);
91 | }
92 |
93 | lines[i - lineStart] = rect;
94 | }
95 | }else{
96 | Rect rect = new Rect();
97 | lines = new Rect[1];
98 | layout.getLineBounds(lineStart, rect);
99 | rect.left = (int) layout.getPrimaryHorizontal(start);
100 | rect.right = (int) layout.getSecondaryHorizontal(end);
101 |
102 | lines[0] = rect;
103 | }
104 |
105 | //calculate x & y for padding
106 | int x = tv.getCompoundPaddingLeft();
107 | int y = tv.getTotalPaddingTop();
108 |
109 | int saveTranslate = canvas.save();
110 |
111 | canvas.translate(x, y);
112 |
113 | int length = lineEnd - lineStart;
114 |
115 | //绘制
116 | for(int i = 0; i <= lineEnd - lineStart; i++){
117 | Rect rect = lines[i];
118 |
119 | if(i == 0){
120 | canvas.translate(rect.left, rect.top);
121 | }else{
122 | canvas.translate(-lines[i - 1].left, -lines[i - 1].top);
123 | canvas.translate(rect.left, rect.top);
124 | }
125 |
126 | LinePosition linePosition;
127 |
128 | if(length != 0){
129 | if(i == 0){
130 | linePosition = LinePosition.LinePositionStart;
131 | }else if(i == length){
132 | linePosition = LinePosition.LinePositionEnd;
133 | }else{
134 | linePosition = LinePosition.LinePositionMiddle;
135 | }
136 |
137 | }else{
138 | linePosition = LinePosition.LinePositionSingle;
139 | }
140 |
141 | drawLine(canvas, rect.width(), rect.height(), linePosition);
142 |
143 | }
144 |
145 | canvas.restoreToCount(saveTranslate);
146 | canvas.restoreToCount(saveBound);
147 | }
148 | }
149 |
150 | protected abstract void drawLine(Canvas canvas, int width, int height, LinePosition linePosition);
151 | }
152 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/app/src/main/java/com/decorator/text/textdecorator/App.java:
--------------------------------------------------------------------------------
1 | package com.decorator.text.textdecorator;
2 |
3 | import android.app.Application;
4 | import android.graphics.Color;
5 | import android.graphics.LinearGradient;
6 | import android.graphics.Shader;
7 | import android.view.View;
8 | import android.widget.Toast;
9 |
10 | import com.decorator.text.textdecor.TextDecor;
11 | import com.decorator.text.textdecor.custom_decors.Click;
12 |
13 |
14 | /**
15 | * Created by winify on 5/31/17.
16 | */
17 |
18 | public class App extends Application{
19 |
20 | private static TextDecor line = new TextDecor.Builder()
21 | .decorate(TextDecor.setBackground(Color.WHITE))
22 | .decorate(TextDecor.setTextColor(Color.BLACK))
23 | .decorate(TextDecor.BOLD)
24 | .decorate(TextDecor.STRINKE)
25 | .build();
26 |
27 | private static TextDecor decor1 = new TextDecor.Builder()
28 | .decorate(TextDecor.setBackground(Color.BLUE))
29 | .decorate(TextDecor.UNDERLINE)
30 | .decorate(TextDecor.addShadow(4,4,5,Color.BLACK))
31 | .decorate(TextDecor.setTextColor(Color.GREEN))
32 | .build();
33 |
34 |
35 | private static TextDecor rbackg = new TextDecor.Builder()
36 | .decorate(TextDecor.relativeTextSize(30))
37 | .decorate(TextDecor.BOLD)
38 | .build();
39 |
40 | private static TextDecor bold = new TextDecor.Builder()
41 | .decorate(TextDecor.BOLD)
42 | .decorate(TextDecor.absoluteTextSize(100))
43 | .build();
44 |
45 |
46 | private static TextDecor roundRgadient = new TextDecor.Builder()
47 | .decorate(TextDecor.setRoundBackground(9, 2, new LinearGradient(0, 0, 545, 545, Color.CYAN, Color.BLUE, Shader.TileMode.CLAMP), Color.BLACK))
48 | .decorate(TextDecor.BOLD)
49 | .build();
50 |
51 | private static TextDecor redBack = new TextDecor.Builder()
52 | .decorate(TextDecor.BOLD)
53 | .decorate(TextDecor.setTextColor(Color.RED))
54 | .decorate(TextDecor.setBackground(Color.BLACK))
55 | .decorate(TextDecor.absoluteTextSize(50))
56 | .build();
57 |
58 | private static TextDecor shadowCol = new TextDecor.Builder()
59 | .decorate(TextDecor.addShadow(2, 2, 5, Color.BLACK))
60 | .decorate(TextDecor.absoluteTextSize(40))
61 | .build();
62 |
63 | private static TextDecor alRight = new TextDecor.Builder()
64 | .decorate(TextDecor.alignCenter())
65 | .build();
66 |
67 | private static TextDecor alLeft = new TextDecor.Builder()
68 | .decorate(TextDecor.alignLeft())
69 | .build();
70 |
71 | private static TextDecor alCenter = new TextDecor.Builder()
72 | .decorate(TextDecor.alignRight())
73 | .build();
74 |
75 | private static TextDecor clikable = new TextDecor.Builder()
76 | .decorate(TextDecor.clickableText(new Click(Color.BLACK, Color.CYAN) {
77 | @Override
78 | public void onClick(View view) {
79 | Toast.makeText(view.getContext(), "toast", Toast.LENGTH_LONG).show();
80 | }
81 | }))
82 | .build();
83 |
84 | private static TextDecor roundCorrner = new TextDecor.Builder()
85 | .decorate(TextDecor.setRoundBackground(15, 1, Color.YELLOW, Color.BLACK))
86 | .build();
87 |
88 | private static TextDecor roundCorrner2 = new TextDecor.Builder()
89 | .decorate(TextDecor.setRoundBackground(0, 1, Color.YELLOW, Color.BLACK))
90 | .build();
91 |
92 | // context needed
93 | private static TextDecor IMAGE;
94 | private static TextDecor FONTANDUNDELINE;
95 | private static TextDecor TEST;
96 | private static TextDecor decor2;
97 |
98 | @Override
99 | public void onCreate() {
100 | super.onCreate();
101 |
102 | decor2 = new TextDecor.Builder()
103 | .decorate(TextDecor.setRoundBackground(9,1,new LinearGradient(45,1,1,5,Color.CYAN,Color.BLUE, Shader.TileMode.CLAMP),Color.BLACK))
104 | .decorate(TextDecor.absoluteTextSize(35))
105 | .decorate(TextDecor.font(getBaseContext(), "fonts/Roboto-Thin.ttf"))
106 | .build();
107 | IMAGE = new TextDecor.Builder()
108 | .decorate(TextDecor.replaceTextWithImage(getBaseContext(), R.drawable.tst, 300))
109 | .decorate(TextDecor.alignRight())
110 | .build();
111 |
112 | FONTANDUNDELINE = new TextDecor.Builder()
113 | .decorate(TextDecor.font(getBaseContext(), "fonts/Roboto-Thin.ttf"))
114 | .decorate(TextDecor.UNDERLINE)
115 | .build();
116 |
117 | TEST = new TextDecor.Builder()
118 | .decorate(TextDecor.alignLeft())
119 | .decorate(TextDecor.test(getBaseContext(), R.drawable.im, 200, 1))
120 | .build();
121 |
122 | }
123 |
124 | public static TextDecor getLine() {
125 | return line;
126 | }
127 |
128 | public static TextDecor getDecor1() {
129 | return decor1;
130 | }
131 |
132 | public static TextDecor getRbackg() {
133 | return rbackg;
134 | }
135 |
136 | public static TextDecor getBold() {
137 | return bold;
138 | }
139 |
140 | public static TextDecor getRoundRgadient() {
141 | return roundRgadient;
142 | }
143 |
144 | public static TextDecor getRedBack() {
145 | return redBack;
146 | }
147 |
148 | public static TextDecor getShadowCol() {
149 | return shadowCol;
150 | }
151 |
152 | public static TextDecor getAlRight() {
153 | return alRight;
154 | }
155 |
156 | public static TextDecor getAlLeft() {
157 | return alLeft;
158 | }
159 |
160 | public static TextDecor getAlCenter() {
161 | return alCenter;
162 | }
163 |
164 | public static TextDecor getClikable() {
165 | return clikable;
166 | }
167 |
168 | public static TextDecor getRoundCorrner() {
169 | return roundCorrner;
170 | }
171 |
172 | public static TextDecor getRoundCorrner2() {
173 | return roundCorrner2;
174 | }
175 |
176 | public static TextDecor getIMAGE() {
177 | return IMAGE;
178 | }
179 |
180 | public static TextDecor getFONTANDUNDELINE() {
181 | return FONTANDUNDELINE;
182 | }
183 |
184 | public static TextDecor getTEST() {
185 | return TEST;
186 | }
187 |
188 | public static TextDecor getDecor2() {
189 | return decor2;
190 | }
191 | }
192 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | SimpleDecoratedText helps you create simple, beautiful, intelligent, responsive TextViews.
8 |
9 | 
10 |
11 |
12 |
13 | Features
14 | ------------
15 |
16 | * **Clean, intuitive design** — With SimpleTextView you can create beautiful text views for you application in a single view
17 |
18 | * **Everything on a single TextView** — TextDecor class offers a lot of posibilities, adding simple decors to you text : bold, italic, superscript effects to add click listeners on selected texts, change colors, adding shadows and more
19 |
20 | * **Out-of-the-box** If you need some specific decoration you can add you own by implementing the interface
21 |
22 | * **Performant, smoothly scrolling fonts in lists** adding fonts to text in lists hav no in pact on you scroll performance
23 |
24 |
25 |
26 | Getting started with SimpleDecoratedtext is super easy! Simply add the dependency to you project and follow the instructions below.
27 |
28 | Getting Started
29 | ------------------------------
30 |
31 | ### Prerequisites
32 |
33 | You're going to need:
34 |
35 | - **Gradle or maven** — Windows may work, but is unsupported.
36 | - **Android**
37 |
38 | ### Getting Set Up
39 |
40 | 1. Add the dependency to you project or visit [Bintray](https://bintray.com/dsdmsa/AndroidText/com.dsdmsa.text) for details
41 | ```groovy
42 | compile 'com.dsdmsa.text:text_decor_V01:0.0.5'
43 | ```
44 | or
45 | ```xml
46 |
47 | com.dsdmsa.text
48 | text_decor_V01
49 | 0.0.5
50 | pom
51 |
52 | ```
53 | 2. Add in your xml Prittytext instead of TextView
54 | ```xml
55 |
60 | ```
61 |
62 | 3. Add some decorations in your code
63 | ```java
64 | TextDecor bold = new TextDecor.Builder()
65 | .decorate(TextDecor.BOLD)
66 | .build();
67 | TextDecor fontAndUndeline = new TextDecor.Builder()
68 | .decorate(TextDecor.font(this,"fonts/Roboto-Thin.ttf"))
69 | .decorate(TextDecor.UNDERLINE)
70 | .build();
71 | TextDecor roundRgadient = new TextDecor.Builder()
72 | .decorate(TextDecor.setRoundBackground(9,2,new LinearGradient(0,0,545,545,Color.CYAN,Color.BLUE, Shader.TileMode.CLAMP),Color.BLACK))
73 | .decorate(TextDecor.BOLD)
74 | .build();
75 | TextDecor redBack = new TextDecor.Builder()
76 | .decorate(TextDecor.BOLD)
77 | .decorate(TextDecor.setTextColor(Color.RED))
78 | .decorate(TextDecor.setBackground(Color.BLACK))
79 | .decorate(TextDecor.absoluteTextSize(50))
80 | .build();
81 |
82 | TextDecor shadowCol = new TextDecor.Builder()
83 | .decorate(TextDecor.addShadow(2,2,5,Color.BLACK))
84 | .decorate(TextDecor.absoluteTextSize(40))
85 | .build();
86 |
87 | ```
88 | 4. Get the prittytext from xml :
89 | ```java
90 | prettyText = (PrettyText) findViewById(R.id.textDecor);
91 | ```
92 |
93 | 5. And use the decorations with needed text:
94 | ```java
95 | prettyText.setText(
96 | roundRgadient.withText("Lorem Ipsum"),
97 | fontAndUndeline.withText(" is simply dummy text"),
98 | " of the printing and typesetting industry.",
99 | roundRgadient.withText(" Lorem Ipsum "),
100 | "has been the industry's standard dummy text ever since the ",
101 | redBack.withText("1500s"),
102 | shadowCol.withText(", when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the "),
103 | redBack.withText("1960s"),
104 | " with the release of ",
105 | bold.withText("Letraset"),
106 | " sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of ",
107 | roundRgadient.withText("Lorem Ipsum")
108 | );
109 | ```
110 |
111 | Custom decorations :
112 | ------------------------------
113 |
114 | 1. For spans woth params use code like this :
115 | ```java
116 | public static Decoration decor(final int param){
117 | return new Decoration() {
118 | @Override
119 | public Object newDecorInstance() {
120 | return new CustomSpan(param);
121 | }
122 | };
123 | }
124 | ```
125 | 2. For simple constant spans :
126 | ```java
127 | public static final Decoration STRINKE = new Decoration() {
128 | @Override
129 | public Object newDecorInstance() {
130 | return new StrikethroughSpan();
131 | }
132 | };
133 | ```
134 |
135 | TextDecor Decoration list :
136 | ------------------------------
137 | 1. UNDERLINE
138 | 2. STRINKE
139 | 3. TRANSPARENT_BACKGROUND
140 | 4. SUBSCRIPT
141 | 5. SUPERSCRIPT
142 | 6. BOLD
143 | 7. ITALIC
144 | 8. ITALIC_BOLD
145 | 9. setBlur(final int radius, final BlurMaskFilter.Blur style)
146 | 10. absoluteTextSize(final int size)
147 | 11. relativeTextSize(final int size)
148 | 12. font(final Context context, final String font)
149 | 13. setTextColor(final int color)
150 | 14. setBackground(final int color)
151 | 15. setRoundBackground(final int corner, final int padding, final int backgroundColor, final int textColor)
152 | 16. addShadow(final float dx, final float dy, final float radius, final int color)
153 | 17. alignRight( )
154 | 18. alignLeft( )
155 | 19. alignCenter( )
156 | 20. replaceTextWithImage(final Context context ,final int id,final int size)
157 | 21. clickableText(final Click click)
158 |
159 |
160 | Need Help? Found a bug?
161 | --------------------
162 |
163 | [Submit an issue](https://github.com/dsdmsa/SimpleDecoratedtext/issues) to the SimpleDecoratedText Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes.
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/textdecor/src/main/java/com/decorator/text/textdecor/TextDecor.java:
--------------------------------------------------------------------------------
1 | package com.decorator.text.textdecor;
2 |
3 | import android.content.Context;
4 | import android.graphics.BlurMaskFilter;
5 | import android.graphics.Color;
6 | import android.graphics.LinearGradient;
7 | import android.graphics.Typeface;
8 | import android.graphics.drawable.Drawable;
9 | import android.text.Layout;
10 | import android.text.SpannableString;
11 | import android.text.Spanned;
12 | import android.text.style.AbsoluteSizeSpan;
13 | import android.text.style.AlignmentSpan;
14 | import android.text.style.BackgroundColorSpan;
15 | import android.text.style.CharacterStyle;
16 | import android.text.style.ForegroundColorSpan;
17 | import android.text.style.ImageSpan;
18 | import android.text.style.MaskFilterSpan;
19 | import android.text.style.ReplacementSpan;
20 | import android.text.style.StrikethroughSpan;
21 | import android.text.style.StyleSpan;
22 | import android.text.style.SubscriptSpan;
23 | import android.text.style.SuperscriptSpan;
24 | import android.text.style.UnderlineSpan;
25 |
26 | import com.decorator.text.textdecor.custom_decors.CenteredImageSpan;
27 | import com.decorator.text.textdecor.custom_decors.Click;
28 | import com.decorator.text.textdecor.custom_decors.RoundedBackgroundSpan;
29 | import com.decorator.text.textdecor.custom_decors.ShadowSpan;
30 | import com.decorator.text.textdecor.spans.Decoration;
31 | import com.decorator.text.textdecor.utils.CustomTypefaceSpan;
32 | import com.decorator.text.textdecor.utils.FontUtil;
33 |
34 | import java.util.ArrayList;
35 | import java.util.List;
36 |
37 | /**
38 | * with this class you can create text decoration rules that you can aplly to you text.
39 | */
40 | public class TextDecor {
41 | private List strings = new ArrayList<>();
42 | private List characterStyles = new ArrayList<>();
43 |
44 | /**
45 | * builder class for TextDecor.
46 | *
47 | * @param builder
48 | */
49 | private TextDecor(Builder builder) {
50 | this.characterStyles = builder.decorations;
51 | }
52 |
53 | /**
54 | * getText method used inside text decor
55 | *
56 | * @return
57 | */
58 | protected String getText() {
59 | String text = strings.get(0);
60 | strings.remove(0);
61 | return text;
62 | }
63 |
64 | /**
65 | * use this method to specify what text is using the text decor rule that you created.
66 | *
67 | * @param text
68 | * @return
69 | */
70 | public TextDecor withText(String text) {
71 | strings.add(text);
72 | return this;
73 | }
74 |
75 | /**
76 | * method used to decorate text
77 | *
78 | * @param spannableString
79 | * @param firstCharIndex
80 | * @param lastCharIndex
81 | */
82 | protected void decorateText(SpannableString spannableString,
83 | int firstCharIndex,
84 | int lastCharIndex) {
85 | for (Decoration characterStyle : characterStyles) {
86 | spannableString.setSpan(characterStyle.newDecorInstance(),
87 | firstCharIndex, lastCharIndex, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
88 | }
89 | }
90 |
91 | /**
92 | * with this builder you start adding rules to you object.
93 | */
94 | public static class Builder {
95 |
96 | private List decorations = new ArrayList<>();
97 |
98 | /**
99 | * add the rules to you rule class.
100 | *
101 | * @param decoration
102 | * @return
103 | */
104 | public Builder decorate(Decoration decoration) {
105 | decorations.add(decoration);
106 | return this;
107 | }
108 |
109 | /**
110 | * instantiate decor class eith rules.
111 | *
112 | * @return
113 | */
114 | public TextDecor build() {
115 | return new TextDecor(this);
116 | }
117 | }
118 |
119 | /**
120 | * adds underline to selected text
121 | */
122 | public static final Decoration UNDERLINE = new Decoration() {
123 | @Override
124 | public CharacterStyle newDecorInstance() {
125 | return new UnderlineSpan();
126 | }
127 | };
128 |
129 | /**
130 | * strikes the sellected text
131 | */
132 | public static final Decoration STRINKE = new Decoration() {
133 | @Override
134 | public CharacterStyle newDecorInstance() {
135 | return new StrikethroughSpan();
136 | }
137 | };
138 |
139 | /**
140 | * TRANSPARENT_BACKGROUND decoration
141 | */
142 | public static Decoration TRANSPARENT_BACKGROUND = new Decoration() {
143 | @Override
144 | public CharacterStyle newDecorInstance() {
145 | return new BackgroundColorSpan(Color.TRANSPARENT);
146 | }
147 | };
148 |
149 | public static final Decoration SUBSCRIPT = new Decoration() {
150 | @Override
151 | public CharacterStyle newDecorInstance() {
152 | return new SubscriptSpan();
153 | }
154 | };
155 |
156 | public static final Decoration SUPERSCRIPT = new Decoration() {
157 | @Override
158 | public CharacterStyle newDecorInstance() {
159 | return new SuperscriptSpan();
160 | }
161 | };
162 |
163 | public static final Decoration BOLD = new Decoration() {
164 | @Override
165 | public CharacterStyle newDecorInstance() {
166 | return new StyleSpan(Typeface.BOLD);
167 | }
168 | };
169 |
170 | public static final Decoration ITALIC = new Decoration() {
171 | @Override
172 | public CharacterStyle newDecorInstance() {
173 | return new StyleSpan(Typeface.ITALIC);
174 | }
175 | };
176 |
177 | public static final Decoration ITALIC_BOLD = new Decoration() {
178 | @Override
179 | public CharacterStyle newDecorInstance() {
180 | return new StyleSpan(Typeface.BOLD_ITALIC);
181 | }
182 | };
183 |
184 | /**
185 | * decorations with parrams
186 | */
187 |
188 | public static Decoration setBlur(final int radius, final BlurMaskFilter.Blur style) {
189 |
190 | return new Decoration() {
191 | @Override
192 | public CharacterStyle newDecorInstance() {
193 | return new MaskFilterSpan(new BlurMaskFilter(radius, style));
194 | }
195 | };
196 | }
197 |
198 | public static Decoration absoluteTextSize(final int size) {
199 | return new Decoration() {
200 | @Override
201 | public CharacterStyle newDecorInstance() {
202 | return new AbsoluteSizeSpan(size);
203 | }
204 | };
205 | }
206 |
207 | public static Decoration relativeTextSize(final int size) {
208 | return new Decoration() {
209 | @Override
210 | public CharacterStyle newDecorInstance() {
211 | return new AbsoluteSizeSpan(size);
212 | }
213 | };
214 | }
215 |
216 | public static Decoration font(final Context context, final String font) {
217 | return new Decoration() {
218 | @Override
219 | public CharacterStyle newDecorInstance() {
220 | return new CustomTypefaceSpan(font, FontUtil.get(context, font));
221 | }
222 | };
223 | }
224 |
225 |
226 | public static Decoration setTextColor(final int color) {
227 | return new Decoration() {
228 | @Override
229 | public CharacterStyle newDecorInstance() {
230 | return new ForegroundColorSpan(color);
231 | }
232 | };
233 | }
234 |
235 | public static Decoration setBackground(final int color) {
236 | return new Decoration() {
237 | @Override
238 | public CharacterStyle newDecorInstance() {
239 | return new BackgroundColorSpan(color);
240 | }
241 | };
242 | }
243 |
244 |
245 | /**
246 | * need improvment, not working correctly
247 | * better work allone
248 | *
249 | * @param corner
250 | * @param padding
251 | * @param backgroundColor
252 | * @param textColor
253 | * @return
254 | */
255 | public static Decoration setRoundBackground(final int corner,
256 | final int padding,
257 | final int backgroundColor,
258 | final int textColor,
259 | final RoundedBackgroundSpan.Gravity gravity) {
260 | return new Decoration() {
261 | @Override
262 | public ReplacementSpan newDecorInstance() {
263 | return new RoundedBackgroundSpan(corner,
264 | padding,
265 | backgroundColor,
266 | textColor,
267 | gravity);
268 | }
269 | };
270 | }
271 |
272 | public static Decoration setRoundBackground(final int corner,
273 | final int padding,
274 | final int backgroundColor,
275 | final int textColor) {
276 | return new Decoration() {
277 | @Override
278 | public ReplacementSpan newDecorInstance() {
279 | return new RoundedBackgroundSpan(corner, padding, backgroundColor, textColor);
280 | }
281 | };
282 | }
283 |
284 | public static Decoration setRoundBackground(final int corner,
285 | final int padding,
286 | final LinearGradient backgroundColor,
287 | final int textColor) {
288 | return new Decoration() {
289 | @Override
290 | public ReplacementSpan newDecorInstance() {
291 | return new RoundedBackgroundSpan(corner, padding, backgroundColor, textColor);
292 | }
293 | };
294 | }
295 |
296 | public static Decoration addShadow(final float dx,
297 | final float dy,
298 | final float radius,
299 | final int color) {
300 | return new Decoration() {
301 | @Override
302 | public CharacterStyle newDecorInstance() {
303 | return new ShadowSpan(dx, dy, radius, color);
304 | }
305 | };
306 | }
307 |
308 |
309 | public static Decoration alignRight() {
310 | return new Decoration() {
311 | @Override
312 | public AlignmentSpan newDecorInstance() {
313 | return new AlignmentSpan.Standard(Layout.Alignment.ALIGN_OPPOSITE);
314 | }
315 | };
316 | }
317 |
318 | public static Decoration alignLeft() {
319 | return new Decoration() {
320 | @Override
321 | public AlignmentSpan newDecorInstance() {
322 | return new AlignmentSpan.Standard(Layout.Alignment.ALIGN_NORMAL);
323 | }
324 | };
325 | }
326 |
327 | public static Decoration alignCenter() {
328 | return new Decoration() {
329 | @Override
330 | public AlignmentSpan newDecorInstance() {
331 | return new AlignmentSpan.Standard(Layout.Alignment.ALIGN_CENTER);
332 | }
333 | };
334 | }
335 |
336 | public static Decoration replaceTextWithImage(final Context context,
337 | final int id,
338 | final int size) {
339 | return new Decoration() {
340 | @Override
341 | public ImageSpan newDecorInstance() {
342 | Drawable d = context.getResources().getDrawable(id);
343 | if (d != null) {
344 | d.setBounds(0, 0, size, size);
345 | }
346 | return new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
347 | }
348 | };
349 | }
350 |
351 | public static Decoration clickableText(final Click click) {
352 | return new Decoration() {
353 | @Override
354 | public Click newDecorInstance() {
355 | return click;
356 | }
357 | };
358 | }
359 |
360 |
361 | public static Decoration test(final Context context, final int id,
362 | final int size,
363 | final int alignament) {
364 | return new Decoration() {
365 | @Override
366 | public CenteredImageSpan newDecorInstance() {
367 | Drawable d = context.getResources().getDrawable(id);
368 | if (d != null) {
369 | d.setBounds(0, 0, size, size);
370 | }
371 | return new CenteredImageSpan(d, alignament);
372 | }
373 | };
374 | }
375 |
376 | }
377 |
--------------------------------------------------------------------------------