├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── wu
│ │ └── seal
│ │ └── textwithimagedemo
│ │ └── ApplicationTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── wu
│ │ │ └── seal
│ │ │ └── textwithimagedemo
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── wu
│ └── seal
│ └── textwithimagedemo
│ └── ExampleUnitTest.java
├── build.gradle
├── demo.png
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── textwithimagedrawable
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
├── androidTest
└── java
│ └── wu
│ └── seal
│ └── textwithimagedrawable
│ └── ApplicationTest.java
├── main
├── AndroidManifest.xml
├── java
│ └── wu
│ │ └── seal
│ │ └── textwithimagedrawable
│ │ ├── BaseCombinedDrawable.java
│ │ └── TextWithImageDrawable.java
└── res
│ └── values
│ └── strings.xml
└── test
└── java
└── wu
└── seal
└── textwithimagedrawable
└── ExampleUnitTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | /.idea/
10 | /gradle.properties
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TextWithImageDrawable
2 | An android drawable object which contains text and image
3 |
4 | 可以同时包含文字和图像的Drawable,也可以单独只包含文字或是图像
5 |
6 | ##使用步骤
7 | * 在app的构建文件build.gradle中的dependencies中加入下面的代码
8 |
9 | ```groove
10 |
11 | compile 'wu.seal:textwithimagedrawable:1.0.4'
12 |
13 | ```
14 |
15 | * 然后就可以直接在代码中使用就可以了
16 |
17 | ## Api的简单介绍
18 |
19 | ```java
20 |
21 | /**
22 | * 实例化一个同时包含文字和图片的drawable
23 | */
24 | TextWithImageDrawable textWithImageDrawable = new TextWithImageDrawable(thisActivity);
25 | /**
26 | * 设置drawable里的文字
27 | */
28 | textWithImageDrawable.setText(text);
29 | /**
30 | * 设置drawable里的图像资源
31 | */
32 | textWithImageDrawable.setImageRes(leftMenuIconResId);
33 | /**
34 | * 设置drawable里的图像资源
35 | */
36 | textWithImageDrawable.setImageBitmap(mBitmap);
37 | /**
38 | * 设置drawable里的drawable
39 | */
40 | textWithImageDrawable.setDrawable(mDrawable);
41 | /**
42 | * 设置drawable中文字的大小,注意此处的单位是sp
43 | */
44 | textWithImageDrawable.setTextSize(16);
45 | /**
46 | * 设置文字的颜色
47 | */
48 | textWithImageDrawable.setTextColor(getResources().getColor(R.color.text_color_white));
49 | /**
50 | * 设置文字和图像之间的间隔,单位是px
51 | */
52 | textWithImageDrawable.setImagePadding(DensityUtils.dip2px(5));
53 | /**
54 | * 设置此drawable的左边填充大小,单位px
55 | */
56 | textWithImageDrawable.setPaddingLeft(DensityUtils.dip2px(8));
57 | /**
58 | * 设置此drawable上方填充大小,单位px
59 | */
60 | textWithImageDrawable.setPaddingTop(DensityUtils.dip2px(6));
61 | /**
62 | * 设置此drawable的最大文字限制长度
63 | */
64 | textWithImageDrawable.setMaxTextLength(3);
65 | /**
66 | * 设置图像和文字的相对位置,此处设置的是图像在文字右边显示
67 | */
68 | textWithImageDrawable.setImagePosition(TextWithImageDrawable.Position.RIGHT);
69 |
70 | ```
71 | ## 使用示例:
72 |
73 | ```java
74 |
75 | ImageView left, right, top, bottom;
76 |
77 | String mText = "text";
78 |
79 | @Override
80 | protected void onCreate(Bundle savedInstanceState) {
81 | super.onCreate(savedInstanceState);
82 | setContentView(R.layout.activity_main);
83 | /**
84 | * 图像资源显示在文字左边的显示效果
85 | */
86 | left = (ImageView) findViewById(R.id.iv_left);
87 | /**
88 | * 图像资源显示在文字右边的显示效果
89 | */
90 | right = (ImageView) findViewById(R.id.iv_right);
91 | /**
92 | * 图像资源显示在文字上边的显示效果
93 | */
94 | top = (ImageView) findViewById(R.id.iv_top);
95 | /**
96 | * 图像资源显示在文字下边的显示效果
97 | */
98 | bottom = (ImageView) findViewById(R.id.iv_bottom);
99 |
100 | /**
101 | * 图像和文字之间的距离
102 | */
103 | final int drawablePadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
104 |
105 | TextWithImageDrawable drawableLeft = new TextWithImageDrawable(this);
106 | initDrawable(drawablePadding, drawableLeft, mText, TextWithImageDrawable.Position.LEFT);
107 | left.setImageDrawable(drawableLeft);
108 |
109 | TextWithImageDrawable drawableRight = new TextWithImageDrawable(this);
110 | initDrawable(drawablePadding, drawableRight, mText, TextWithImageDrawable.Position.RIGHT);
111 | right.setImageDrawable(drawableRight);
112 |
113 | TextWithImageDrawable drawableTop = new TextWithImageDrawable(this);
114 | initDrawable(drawablePadding, drawableTop, mText, TextWithImageDrawable.Position.TOP);
115 | top.setImageDrawable(drawableTop);
116 |
117 | TextWithImageDrawable drawableBottom = new TextWithImageDrawable(this);
118 | initDrawable(drawablePadding, drawableBottom, mText, TextWithImageDrawable.Position.BOTTOM);
119 | bottom.setImageDrawable(drawableBottom);
120 |
121 |
122 |
123 |
124 | }
125 |
126 | private void initDrawable(int drawablePadding, TextWithImageDrawable drawable, String mText, TextWithImageDrawable.Position position) {
127 | drawable.setText(mText);
128 | drawable.setImagePosition(position);
129 | drawable.setImagePadding(drawablePadding);
130 | drawable.setImageRes(R.mipmap.ic_launcher);
131 | }
132 |
133 | ```
134 |
135 | # BaseCombinedDrawable
136 | An android drawable object which contains two drawables
137 |
138 | 一个组合drawable,能对两个drawable进行拼凑组合成一个新的drawable,两个drawable的位置可以灵活组合,基本能满足所有的drawable的定制,各种图文混排,你懂的
139 |
140 | ##Api介绍
141 |
142 | ```java
143 |
144 | /**
145 | * 设置drawable two 左上角相对于 drawable one左上角 的相对偏移位置
146 | * 偏移以drawable one 的左上角为起始点
147 | * drawable one 会优先放在最前面进行绘制(如果两个drawable的相对偏移值为0则效果如同FrameLayout)
148 | *
149 | * @param relatedX x轴的相对偏移
150 | * @param relatedY y轴的相对偏移值
151 | */
152 | public void setRelatedPosition(int relatedX, int relatedY)
153 |
154 |
155 | /**
156 | * 设置组合后的新的drawable的四个Padding值
157 | *
158 | * @param paddingLeft 左边填充距离
159 | * @param paddingTop 上边填充距离
160 | * @param paddingRight 右边填充距离
161 | * @param paddingBottom 下边填充距离
162 | */
163 | public void setPadding(int paddingLeft, int paddingTop, int paddingRight, int paddingBottom)
164 |
165 | ```
166 |
167 | ##代码示例
168 |
169 | ```java
170 |
171 | BaseCombinedDrawable baseCombinedDrawable = new BaseCombinedDrawable(drawableLeft, drawableRight);
172 | baseCombinedDrawable.setRelatedPosition(drawableLeft.getIntrinsicWidth() + drawablePadding, 0);
173 | combine.setImageDrawable(baseCombinedDrawable);
174 |
175 | ```
176 |
177 |
178 | ##效果图:
179 |
180 |
181 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.3"
6 |
7 | defaultConfig {
8 | applicationId "wu.seal.textwithimagedemo"
9 | minSdkVersion 15
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | testCompile 'junit:junit:4.12'
25 | compile 'com.android.support:appcompat-v7:23.4.0'
26 | compile project(':textwithimagedrawable')
27 | }
28 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\Android_SDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/wu/seal/textwithimagedemo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package wu.seal.textwithimagedemo;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/java/wu/seal/textwithimagedemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package wu.seal.textwithimagedemo;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.util.TypedValue;
6 | import android.widget.ImageView;
7 |
8 | import wu.seal.textwithimagedrawable.BaseCombinedDrawable;
9 | import wu.seal.textwithimagedrawable.TextWithImageDrawable;
10 |
11 |
12 | public class MainActivity extends AppCompatActivity {
13 |
14 | ImageView left, right, top, bottom,combine;
15 |
16 | String mText = "text";
17 |
18 | @Override
19 | protected void onCreate(Bundle savedInstanceState) {
20 | super.onCreate(savedInstanceState);
21 | setContentView(R.layout.activity_main);
22 | left = (ImageView) findViewById(R.id.iv_left);
23 | right = (ImageView) findViewById(R.id.iv_right);
24 | top = (ImageView) findViewById(R.id.iv_top);
25 | bottom = (ImageView) findViewById(R.id.iv_bottom);
26 | combine = (ImageView) findViewById(R.id.iv_combine);
27 |
28 | /**
29 | * 图像和文字之间的距离
30 | */
31 | final int drawablePadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics());
32 |
33 | TextWithImageDrawable drawableLeft = new TextWithImageDrawable(this);
34 | initDrawable(drawablePadding, drawableLeft, mText, TextWithImageDrawable.Position.LEFT);
35 | left.setImageDrawable(drawableLeft);
36 |
37 | TextWithImageDrawable drawableRight = new TextWithImageDrawable(this);
38 | initDrawable(drawablePadding, drawableRight, mText, TextWithImageDrawable.Position.RIGHT);
39 | right.setImageDrawable(drawableRight);
40 |
41 | TextWithImageDrawable drawableTop = new TextWithImageDrawable(this);
42 | initDrawable(drawablePadding, drawableTop, mText, TextWithImageDrawable.Position.TOP);
43 | top.setImageDrawable(drawableTop);
44 |
45 | TextWithImageDrawable drawableBottom = new TextWithImageDrawable(this);
46 | initDrawable(drawablePadding, drawableBottom, mText, TextWithImageDrawable.Position.BOTTOM);
47 | bottom.setImageDrawable(drawableBottom);
48 |
49 | BaseCombinedDrawable baseCombinedDrawable = new BaseCombinedDrawable(drawableLeft, drawableRight);
50 | baseCombinedDrawable.setRelatedPosition(drawableLeft.getIntrinsicWidth() + drawablePadding, 0);
51 | combine.setImageDrawable(baseCombinedDrawable);
52 | }
53 |
54 | private void initDrawable(int drawablePadding, TextWithImageDrawable drawable, String mText, TextWithImageDrawable.Position position) {
55 | drawable.setText(mText);
56 | drawable.setImagePosition(position);
57 | drawable.setImagePadding(drawablePadding);
58 | drawable.setImageRes(R.mipmap.ic_launcher);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
17 |
21 |
22 |
28 |
29 |
35 |
36 |
42 |
43 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuseal/TextWithImageDrawable/ebe8ee0462d9acf30b34747547de4f1d40dd14a1/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuseal/TextWithImageDrawable/ebe8ee0462d9acf30b34747547de4f1d40dd14a1/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuseal/TextWithImageDrawable/ebe8ee0462d9acf30b34747547de4f1d40dd14a1/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuseal/TextWithImageDrawable/ebe8ee0462d9acf30b34747547de4f1d40dd14a1/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuseal/TextWithImageDrawable/ebe8ee0462d9acf30b34747547de4f1d40dd14a1/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TextWithImageDemo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/wu/seal/textwithimagedemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package wu.seal.textwithimagedemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.2'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuseal/TextWithImageDrawable/ebe8ee0462d9acf30b34747547de4f1d40dd14a1/demo.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wuseal/TextWithImageDrawable/ebe8ee0462d9acf30b34747547de4f1d40dd14a1/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':textwithimagedrawable'
2 |
--------------------------------------------------------------------------------
/textwithimagedrawable/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /local.properties
3 |
--------------------------------------------------------------------------------
/textwithimagedrawable/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | android {
3 | compileSdkVersion 23
4 | buildToolsVersion "23.0.3"
5 |
6 | defaultConfig {
7 | minSdkVersion 15
8 | targetSdkVersion 23
9 | versionCode 1
10 | versionName "1.0"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | }
18 | }
19 |
20 | dependencies {
21 | compile fileTree(dir: 'libs', include: ['*.jar'])
22 | testCompile 'junit:junit:4.12'
23 | compile 'com.android.support:appcompat-v7:23.4.0'
24 | }
25 |
--------------------------------------------------------------------------------
/textwithimagedrawable/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\Android_SDK/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/textwithimagedrawable/src/androidTest/java/wu/seal/textwithimagedrawable/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package wu.seal.textwithimagedrawable;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/textwithimagedrawable/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/textwithimagedrawable/src/main/java/wu/seal/textwithimagedrawable/BaseCombinedDrawable.java:
--------------------------------------------------------------------------------
1 | package wu.seal.textwithimagedrawable;
2 |
3 | import android.graphics.Canvas;
4 | import android.graphics.ColorFilter;
5 | import android.graphics.drawable.Drawable;
6 |
7 | /**
8 | * 两个drawable组合成的一个drawable
9 | * drawable one 会优先放在最前面进行绘制(如果两个drawable的相对偏移值为0则效果如同FrameLayout)
10 | * Created By: Seal.Wu
11 | * Date: 2016/7/12
12 | * Time: 14:36
13 | */
14 | public class BaseCombinedDrawable extends Drawable {
15 |
16 | private Drawable one;
17 | private Drawable two;
18 |
19 | /**
20 | * two相对one的相对x轴的距离
21 | */
22 | private int relatedX;
23 |
24 |
25 | /**
26 | * two相对One的相对y轴的距离
27 | */
28 | private int relatedY;
29 |
30 | private int paddingLeft, paddingRight, paddingTop, paddingBottom;
31 |
32 | public BaseCombinedDrawable(Drawable one, Drawable two) {
33 | this.one = one;
34 | this.two = two;
35 | if (one == null || two == null) {
36 | throw new IllegalArgumentException("drawable one or two can't be null!");
37 | }
38 | }
39 |
40 |
41 | /**
42 | * 设置drawable two 左上角相对于 drawable one左上角 的相对偏移位置
43 | * 偏移以drawable one 的左上角为起始点
44 | *
45 | * @param relatedX x轴的相对偏移
46 | * @param relatedY y轴的相对偏移值
47 | */
48 | public void setRelatedPosition(int relatedX, int relatedY) {
49 | this.relatedX = relatedX;
50 | this.relatedY = relatedY;
51 | }
52 |
53 |
54 | /**
55 | * 设置组合后的新的drawable的四个Padding值
56 | *
57 | * @param paddingLeft 左边填充距离
58 | * @param paddingTop 上边填充距离
59 | * @param paddingRight 右边填充距离
60 | * @param paddingBottom 下边填充距离
61 | */
62 | public void setPadding(int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
63 | this.paddingLeft = paddingLeft;
64 | this.paddingTop = paddingTop;
65 | this.paddingRight = paddingRight;
66 | this.paddingBottom = paddingBottom;
67 | }
68 |
69 | @Override
70 | public void draw(Canvas canvas) {
71 | one.setBounds(0, 0, one.getIntrinsicWidth(), one.getIntrinsicHeight());
72 | two.setBounds(0, 0, two.getIntrinsicWidth(), two.getIntrinsicHeight());
73 | canvas.translate(paddingLeft, paddingTop);
74 | canvas.save();
75 | canvas.translate(relatedX < 0 ? Math.abs(relatedX) : 0, relatedY < 0 ? Math.abs(relatedY) : 0);
76 | one.draw(canvas);
77 | canvas.restore();
78 | canvas.save();
79 | canvas.translate(relatedX > 0 ? Math.abs(relatedX) : 0, relatedY > 0 ? Math.abs(relatedY) : 0);
80 | two.draw(canvas);
81 | canvas.restore();
82 | }
83 |
84 | @Override
85 | public int getIntrinsicWidth() {
86 | int width = paddingLeft + paddingRight;
87 | width = width + one.getIntrinsicWidth();
88 | if (relatedX < 0) {
89 | width += Math.abs(relatedX);
90 | } else {
91 | final int del = relatedX + two.getIntrinsicWidth() - one.getIntrinsicWidth();
92 | width += del > 0 ? del : 0;
93 | }
94 | return width;
95 | }
96 |
97 | @Override
98 | public int getIntrinsicHeight() {
99 |
100 | int height = paddingTop + paddingBottom;
101 | height += one.getIntrinsicHeight();
102 | if (relatedY < 0) {
103 | height += Math.abs(relatedY);
104 | } else {
105 | final int del = relatedY + two.getIntrinsicHeight() - one.getIntrinsicHeight();
106 | height += del > 0 ? del : 0;
107 | }
108 |
109 | return height;
110 | }
111 |
112 | @Override
113 | public void setAlpha(int alpha) {
114 | one.setAlpha(alpha);
115 | two.setAlpha(alpha);
116 | }
117 |
118 | @Override
119 | public void setColorFilter(ColorFilter colorFilter) {
120 | one.setColorFilter(colorFilter);
121 | two.setColorFilter(colorFilter);
122 | }
123 |
124 | @Override
125 | public int getOpacity() {
126 | return one.getOpacity();
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/textwithimagedrawable/src/main/java/wu/seal/textwithimagedrawable/TextWithImageDrawable.java:
--------------------------------------------------------------------------------
1 | package wu.seal.textwithimagedrawable;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.graphics.Bitmap;
6 | import android.graphics.BitmapFactory;
7 | import android.graphics.Canvas;
8 | import android.graphics.ColorFilter;
9 | import android.graphics.Paint;
10 | import android.graphics.drawable.BitmapDrawable;
11 | import android.graphics.drawable.Drawable;
12 | import android.os.Build;
13 | import android.text.TextPaint;
14 | import android.util.TypedValue;
15 |
16 | /**
17 | * 文字带图片的drawable
18 | * Created By: Seal.Wu
19 | * Date: 2016/6/17
20 | * Time: 9:56
21 | */
22 | public class TextWithImageDrawable extends Drawable {
23 |
24 | /**
25 | * 图片放置的相对于Text的位置
26 | */
27 | public enum Position {
28 | LEFT, TOP, RIGHT, BOTTOM
29 | }
30 |
31 | /**
32 | * 文字超出大小的省略模式
33 | */
34 | public enum EllipsizeModel {
35 | PRE, MID, END
36 | }
37 |
38 | private Context mContext;
39 |
40 |
41 | private Drawable mDrawable;
42 |
43 | /**
44 | * 文字
45 | */
46 | private String mText;
47 |
48 | /**
49 | * 原始文字
50 | */
51 | private String originText;
52 |
53 | private int paddingLeft, paddingRight, paddingTop, paddingBottom;
54 |
55 | private int drawablePadding;
56 |
57 | private int alpha;
58 |
59 | private Resources mResources;
60 |
61 | private Position position = Position.LEFT;
62 |
63 | private TextPaint mTextPaint;
64 |
65 | private float mTextSize = 14;
66 |
67 | private int mTextHeight;
68 |
69 | /**
70 | * 文字顶部值偏移差
71 | */
72 | private int textTopDelBaseLine;
73 |
74 |
75 | /**
76 | * 文字最大长度
77 | */
78 | private int maxTextLength = Integer.MAX_VALUE;
79 |
80 | /**
81 | * 省略号
82 | */
83 | private final static String SUFFIX = "…";
84 |
85 | /**
86 | * 文字的省略模式
87 | */
88 | private EllipsizeModel ellipsizeModel = EllipsizeModel.END;
89 |
90 | public TextWithImageDrawable(Context context) {
91 | mContext = context;
92 | mResources = context.getResources();
93 | mTextPaint = new TextPaint();
94 | mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
95 | mTextPaint.setTextAlign(Paint.Align.LEFT);
96 | mTextPaint.density = mResources.getDisplayMetrics().density;
97 | mTextPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize, mResources.getDisplayMetrics()));
98 | Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
99 | mTextHeight = Math.round(fontMetrics.descent - fontMetrics.ascent);
100 | textTopDelBaseLine = Math.round(-fontMetrics.ascent - fontMetrics.leading);
101 | }
102 |
103 |
104 | public void setText(String mText) {
105 | originText = mText;
106 | if (maxTextLength != Integer.MAX_VALUE && maxTextLength < mText.length()) {
107 | if (ellipsizeModel == EllipsizeModel.END) {
108 | this.mText = mText.substring(0, maxTextLength) + SUFFIX;
109 | } else if (ellipsizeModel == EllipsizeModel.PRE) {
110 | this.mText = SUFFIX + mText.substring(mText.length() - 3, mText.length());
111 | } else if (ellipsizeModel == EllipsizeModel.MID) {
112 | int firstStringLength = maxTextLength / 2;
113 | this.mText = mText.substring(0, firstStringLength) + SUFFIX +
114 | mText.substring((mText.length() - (maxTextLength - firstStringLength)), mText.length());
115 | }
116 | } else {
117 | this.mText = mText;
118 | }
119 |
120 | invalidateSelf();
121 | }
122 |
123 | public void setImageRes(int imageRes) {
124 | Drawable drawable;
125 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
126 | drawable = mResources.getDrawable(imageRes, mContext.getTheme());
127 | } else {
128 | drawable = mResources.getDrawable(imageRes);
129 | }
130 | setDrawable(drawable);
131 | }
132 |
133 | public void setImageBitmap(Bitmap bitmap) {
134 | setDrawable(new BitmapDrawable(mResources, bitmap));
135 | }
136 |
137 | public void setDrawable(Drawable drawable) {
138 | drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
139 | this.mDrawable = drawable;
140 | invalidateSelf();
141 | }
142 |
143 | public void setPaddingLeft(int paddingLeft) {
144 | this.paddingLeft = paddingLeft;
145 | invalidateSelf();
146 | }
147 |
148 | public void setPaddingRight(int paddingRight) {
149 | this.paddingRight = paddingRight;
150 | invalidateSelf();
151 |
152 | }
153 |
154 | public void setPaddingTop(int paddingTop) {
155 | this.paddingTop = paddingTop;
156 | invalidateSelf();
157 |
158 | }
159 |
160 | public void setPaddingBottom(int paddingBottom) {
161 | this.paddingBottom = paddingBottom;
162 | invalidateSelf();
163 | }
164 |
165 |
166 | public void setImagePadding(int drawablePadding) {
167 | this.drawablePadding = drawablePadding;
168 | invalidateSelf();
169 | }
170 |
171 | /**
172 | * 设置文字省略模式
173 | *
174 | * @param ellipsizeModel 文字省略模式
175 | */
176 | public void setEllipsizeModel(EllipsizeModel ellipsizeModel) {
177 | this.ellipsizeModel = ellipsizeModel;
178 | if (originText != null) {
179 | setText(originText);
180 | }
181 | }
182 |
183 | @Override
184 | public void draw(Canvas canvas) {
185 |
186 | canvas.clipRect(paddingLeft, paddingTop, canvas.getWidth() - paddingRight, canvas.getHeight() - paddingBottom);
187 |
188 | int contentHeight = getIntrinsicHeight() - paddingTop - paddingBottom;
189 | int contentWidth = getIntrinsicWidth() - paddingLeft - paddingRight;
190 |
191 | if (position == Position.LEFT) {
192 | if (mDrawable != null) {
193 | final int bitmapTop = (contentHeight - mDrawable.getIntrinsicHeight()) / 2 + paddingTop;
194 | final int bitmapLeft = this.paddingLeft;
195 | canvas.translate(bitmapLeft, bitmapTop);
196 | mDrawable.draw(canvas);
197 |
198 | if (isNotEmpty(mText)) {
199 |
200 | final int left = this.paddingLeft + mDrawable.getIntrinsicWidth() + drawablePadding;
201 | final int top = (contentHeight - mTextHeight) / 2 + textTopDelBaseLine + paddingTop;
202 | canvas.drawText(mText, left, top, mTextPaint);
203 | }
204 | } else {
205 | if (isNotEmpty(mText)) {
206 |
207 | final int left = this.paddingLeft + drawablePadding;
208 | final int top = (contentHeight - mTextHeight) / 2 + textTopDelBaseLine + paddingTop;
209 | canvas.drawText(mText, left, top, mTextPaint);
210 | }
211 | }
212 | } else if (position == Position.RIGHT) {
213 |
214 | if (isNotEmpty(mText)) {
215 |
216 | final int textLeft = this.paddingLeft;
217 | final int textTop = (contentHeight - mTextHeight) / 2 + textTopDelBaseLine + paddingTop;
218 | canvas.drawText(mText, textLeft, textTop, mTextPaint);
219 | }
220 |
221 | if (mDrawable != null) {
222 | int textWidth = Math.round(mTextPaint.measureText(mText));
223 | final int left = paddingLeft + textWidth + drawablePadding;
224 | final int top = (contentHeight - mDrawable.getIntrinsicHeight()) / 2 + paddingTop;
225 | canvas.translate(left, top);
226 | mDrawable.draw(canvas);
227 | }
228 | } else if (position == Position.TOP) {
229 | if (mDrawable != null) {
230 | final int bitmapLeft = (contentWidth - mDrawable.getIntrinsicWidth()) / 2 + paddingLeft;
231 | final int bitmapTop = paddingTop;
232 | canvas.translate(bitmapLeft, bitmapTop);
233 | mDrawable.draw(canvas);
234 | if (isNotEmpty(mText)) {
235 | final int left = Math.round(contentWidth - mTextPaint.measureText(mText)) / 2 + paddingLeft;
236 | final int top = paddingTop + mDrawable.getIntrinsicHeight() + drawablePadding + textTopDelBaseLine;
237 | canvas.drawText(mText, left, top, mTextPaint);
238 | }
239 | } else {
240 | if ((isNotEmpty(mText))) {
241 | final int left = Math.round(contentWidth - mTextPaint.measureText(mText)) / 2 + paddingLeft;
242 | final int top = paddingTop + drawablePadding + textTopDelBaseLine;
243 | canvas.drawText(mText, left, top, mTextPaint);
244 | }
245 | }
246 | } else if (position == Position.BOTTOM) {
247 | if (isNotEmpty(mText)) {
248 | final int textLeft = Math.round(paddingLeft + (contentWidth - mTextPaint.measureText(mText)) / 2);
249 | final int textTop = paddingTop + textTopDelBaseLine;
250 | canvas.drawText(mText, textLeft, textTop, mTextPaint);
251 |
252 | if (mDrawable != null) {
253 | final int bitmapLeft = Math.round(paddingLeft + ((contentWidth - mDrawable.getIntrinsicWidth()) / 2));
254 | final int bitmapTop = paddingTop + mTextHeight + drawablePadding;
255 | canvas.translate(bitmapLeft, bitmapTop);
256 | mDrawable.draw(canvas);
257 | }
258 | } else {
259 | if (mDrawable != null) {
260 | final int bitmapLeft = Math.round(paddingLeft + ((contentWidth - mDrawable.getIntrinsicWidth()) / 2));
261 | final int bitmapTop = paddingTop + mTextHeight + drawablePadding;
262 | canvas.translate(bitmapLeft, bitmapTop);
263 | mDrawable.draw(canvas);
264 | }
265 | }
266 | }
267 |
268 | }
269 |
270 |
271 | /**
272 | * 设置文字最大长度
273 | *
274 | * @param maxTextLength 文字最大长度(字数)
275 | */
276 | public void setMaxTextLength(int maxTextLength) {
277 | this.maxTextLength = maxTextLength;
278 | if (originText != null) {
279 | setText(originText);
280 | } else {
281 | invalidateSelf();
282 | }
283 | }
284 |
285 | @Override
286 | public int getIntrinsicHeight() {
287 |
288 | int drawableHeight = 0;
289 |
290 | if (mDrawable != null) {
291 |
292 | drawableHeight = mDrawable.getIntrinsicHeight();
293 | }
294 |
295 | if (position == Position.LEFT || position == Position.RIGHT) {
296 |
297 | return Math.max(drawableHeight, mTextHeight) + paddingTop + paddingBottom;
298 |
299 | } else if (position == Position.TOP || position == Position.BOTTOM) {
300 |
301 | return drawableHeight + mTextHeight + paddingTop + drawablePadding + paddingBottom;
302 |
303 | } else {
304 |
305 | throw new IllegalArgumentException("position not known as one of the [ LEFT,TOP,RIGHT,BOTTOM ]!");
306 | }
307 | }
308 |
309 |
310 | @Override
311 | public int getIntrinsicWidth() {
312 |
313 | int drawableWidth = 0;
314 | int textWidth = 0;
315 | if (mDrawable != null) {
316 | drawableWidth = mDrawable.getIntrinsicWidth();
317 | }
318 | if (isNotEmpty(mText)) {
319 | textWidth = Math.round(mTextPaint.measureText(mText));
320 | }
321 |
322 | if (position == Position.LEFT || position == Position.RIGHT) {
323 |
324 | return drawableWidth + textWidth + paddingLeft + paddingRight + drawablePadding;
325 | } else if (position == Position.TOP || position == Position.BOTTOM) {
326 |
327 | return Math.max(drawableWidth, textWidth) + paddingLeft + paddingRight;
328 |
329 | } else {
330 | throw new IllegalArgumentException("position not known as one of the [ LEFT,TOP,RIGHT,BOTTOM ]!");
331 | }
332 |
333 | }
334 |
335 | @Override
336 | public void setAlpha(int alpha) {
337 | if (mTextPaint.getAlpha() != alpha) {
338 | mTextPaint.setAlpha(alpha);
339 | invalidateSelf();
340 | }
341 | }
342 |
343 | @Override
344 | public int getOpacity() {
345 | return mTextPaint.getAlpha();
346 | }
347 |
348 | @Override
349 | public void setColorFilter(ColorFilter cf) {
350 | if (mTextPaint.getColorFilter() != cf) {
351 | mTextPaint.setColorFilter(cf);
352 | invalidateSelf();
353 | }
354 | }
355 |
356 | /**
357 | * 设置文字大小 sp
358 | *
359 | * @param textSize 文字大小单位
360 | */
361 | public void setTextSize(float textSize) {
362 | this.mTextSize = textSize;
363 | mTextPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mTextSize, mResources.getDisplayMetrics()));
364 | Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
365 | mTextHeight = Math.round(fontMetrics.descent - fontMetrics.ascent);
366 | invalidateSelf();
367 | }
368 |
369 |
370 | /**
371 | * 设置文字颜色
372 | *
373 | * @param color 色值
374 | */
375 | public void setTextColor(int color) {
376 | mTextPaint.setColor(color);
377 | }
378 |
379 | /**
380 | * 设置图片在文字的方位(上下左右)
381 | *
382 | * @param position 位置
383 | */
384 | public void setImagePosition(Position position) {
385 | this.position = position;
386 | }
387 |
388 |
389 | private boolean isNotEmpty(String mText) {
390 |
391 | return mText != null && !mText.equals("");
392 | }
393 |
394 | }
395 |
--------------------------------------------------------------------------------
/textwithimagedrawable/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TextWithImageDrawable
3 |
4 |
--------------------------------------------------------------------------------
/textwithimagedrawable/src/test/java/wu/seal/textwithimagedrawable/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package wu.seal.textwithimagedrawable;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------