├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── cc
│ │ └── ibooker
│ │ └── ztextview
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── cc
│ │ │ └── ibooker
│ │ │ └── ztextview
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── cc
│ └── ibooker
│ └── ztextview
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── settings.gradle
└── ztextviewlib
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
├── androidTest
└── java
│ └── cc
│ └── ibooker
│ └── ztextviewlib
│ └── ExampleInstrumentedTest.java
├── main
├── AndroidManifest.xml
├── java
│ └── cc
│ │ └── ibooker
│ │ └── ztextviewlib
│ │ ├── AutoVerticalScrollTextView.java
│ │ ├── AutoVerticalScrollTextViewUtil.java
│ │ ├── MarqueeTextView.java
│ │ ├── SpannableStringTextViewUtil.java
│ │ └── ZTextViewClickUtil.java
└── res
│ └── values
│ └── strings.xml
└── test
└── java
└── cc
└── ibooker
└── ztextviewlib
└── 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 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ZTextView
2 | Android:不一样的TextView(一)水平滚动-跑马灯,以及自定义跑马灯TextView(MarqueeTextView)。Android:不一样的TextView(二)自定义垂直滚动TextView(AutoVerticalScrollTextView)。Android:不一样的TextView(三)SpannableStringTextView。使用工具Android Studio
3 |
4 | 引入Android Studio:
5 |
6 | 1、在build.gradle文件中添加以下代码:
7 | ```
8 | allprojects {
9 | repositories {
10 | maven { url 'https://jitpack.io' }
11 | }
12 | }
13 | ```
14 | ```
15 | dependencies {
16 | compile 'com.github.zrunker:ZTextView:v1.0.2'
17 | }
18 | ```
19 | 2、在maven文件中添加以下代码:
20 | ```
21 |
22 |
23 | jitpack.io
24 | https://jitpack.io
25 |
26 |
27 | ```
28 | ```
29 |
30 | com.github.zrunker
31 | ZTextView
32 | v1.0.2
33 |
34 | ```
35 |
36 | 用法:
37 |
38 | Android:不一样的TextView(一)水平滚动-跑马灯,以及自定义跑马灯TextView(MarqueeTextView):
39 | 只需要在XML布局文件中引入(android:singleLine="true"一定要有):
40 | ```
41 |
45 | ```
46 | Android:不一样的TextView(二)自定义垂直滚动TextView(AutoVerticalScrollTextView)。
47 | 1、在XML布局文件中引入:
48 | ```
49 |
61 | ```
62 | 2、在java文件中进行调用(AutoVerticalScrollTextViewUtil):
63 | ```
64 | public class MainActivity extends AppCompatActivity implements AutoVerticalScrollTextViewUtil.OnMyClickListener {
65 | private ArrayList list;
66 | private AutoVerticalScrollTextViewUtil aUtil;
67 |
68 | @Override
69 | protected void onCreate(Bundle savedInstanceState) {
70 | super.onCreate(savedInstanceState);
71 | setContentView(R.layout.activity_main);
72 |
73 | AutoVerticalScrollTextView textView = (AutoVerticalScrollTextView) findViewById(R.id.autoVerticalScrollTextView);
74 |
75 | list = new ArrayList<>();
76 | for (int i = 0; i < 5; i++) {
77 | if (i == 0 || i == 2 || i == 4) {
78 | list.add(Html.fromHtml("" + "测试垂直滚动" + "" + i + "特殊"));
79 | } else {
80 | list.add("测试垂直滚动" + i);
81 | }
82 | }
83 |
84 | // 初始化
85 | aUtil = new AutoVerticalScrollTextViewUtil(textView, list);
86 | aUtil.setDuration(5000)// 设置上下滚动事件间隔
87 | .start();
88 | // 点击事件监听
89 | aUtil.setOnMyClickListener(this);
90 | }
91 |
92 | // autoVerticalScrollTextView点击事件监听
93 | @Override
94 | public void onMyClickListener(int position, CharSequence title) {
95 | Toast.makeText(this, list.get(position) + " --- " + title, Toast.LENGTH_SHORT).show();
96 | if (aUtil.getIsRunning())
97 | // 停止滚动
98 | aUtil.stop();
99 | else
100 | // 开启滚动
101 | aUtil.start();
102 | }
103 |
104 | @Override
105 | protected void onDestroy() {
106 | super.onDestroy();
107 | aUtil.stop();
108 | }
109 | }
110 | ```
111 | Android:不一样的TextView(三)SpannableStringTextView。
112 | ```
113 | TextView testTv = (TextView) findViewById(R.id.tv_test);
114 |
115 | // testTv.setText("测试修改颜色");
116 | // SpannableStringTextViewUtil.updateForeColorSpan(testTv, 1, 3, "#40aff2");
117 |
118 | // testTv.setText("测试添加颜色");
119 | // SpannableStringTextViewUtil.addForeColorSpan(testTv, "TEST", 1, 3 , "#40aff2");
120 |
121 | // testTv.setText("测试修改颜色");
122 | // SpannableStringTextViewUtil.updateBackColorSpan(testTv, 1, 3, "#40aff2");
123 |
124 | // testTv.setText("测试添加颜色");
125 | // SpannableStringTextViewUtil.addBackColorSpan(testTv, "TEST", 1, 3 , "#40aff2");
126 |
127 | // testTv.setText("测试添加文本大小");
128 | // SpannableStringTextViewUtil.addFontSizeSpan(testTv, "TEST", 1, 3, 60);
129 |
130 | // testTv.setText("测试添加超链接");
131 | // SpannableStringTextViewUtil.addUrlSpan(testTv, "超链接", 0, 3, "http://www.baidu.com");
132 |
133 | // testTv.setText("测试添加点击");
134 | // SpannableStringTextViewUtil.addClickableSpan(testTv, "点击", 0, 2, new SpannableStringTextViewUtil.OnClickSpanListener() {
135 | // @override
136 | // public void onClickSpan() {
137 | // Toast.makeText(MainActivity.this, "点击", Toast.LENGTH_SHORT).show();
138 | // }
139 | // });
140 |
141 | // testTv.setText("测试添加粗体+斜体");
142 | // SpannableStringTextViewUtil.addStyleSpan(testTv, "TEST", 0, 3);
143 |
144 | // testTv.setText("测试添加粗体");
145 | // SpannableStringTextViewUtil.addStyleBoldSpan(testTv, "TEST", 0, 3);
146 |
147 | // testTv.setText("测试添加斜体");
148 | // SpannableStringTextViewUtil.addStyleItalicSpan(testTv, "TEST", 0, 3);
149 |
150 | // testTv.setText("测试添加删除线");
151 | // SpannableStringTextViewUtil.addStrikeSpan(testTv, "TEST", 0 , 3);
152 |
153 | // testTv.setText("测试修改删除线");
154 | // SpannableStringTextViewUtil.updateStrikeMySelfSpan(testTv, 0 , 3);
155 |
156 | // testTv.setText("测试添加下划线");
157 | // SpannableStringTextViewUtil.addUnderLineSpan(testTv, "下划线", 0, 3);
158 |
159 | testTv.setText("测试添加图片");
160 | SpannableStringTextViewUtil.addImageSpan(testTv, getResources().getDrawable(R.mipmap.ic_launcher)
161 | ```
162 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion '26.0.2'
6 | defaultConfig {
7 | applicationId "cc.ibooker.ztextview"
8 | minSdkVersion 15
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
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(include: ['*.jar'], dir: 'libs')
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:25.4.0'
28 | compile 'com.android.support.constraint:constraint-layout:1.0.2'
29 | testCompile 'junit:junit:4.12'
30 | compile project(':ztextviewlib')
31 | }
32 |
--------------------------------------------------------------------------------
/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 E:\Android_Stadio\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 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/cc/ibooker/ztextview/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextview;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("cc.ibooker.ztextview", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/java/cc/ibooker/ztextview/MainActivity.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextview;
2 |
3 | import android.graphics.Color;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.text.Html;
7 | import android.widget.TextView;
8 | import android.widget.Toast;
9 |
10 | import java.util.ArrayList;
11 |
12 | import cc.ibooker.ztextviewlib.AutoVerticalScrollTextView;
13 | import cc.ibooker.ztextviewlib.AutoVerticalScrollTextViewUtil;
14 | import cc.ibooker.ztextviewlib.SpannableStringTextViewUtil;
15 |
16 | public class MainActivity extends AppCompatActivity implements AutoVerticalScrollTextViewUtil.OnMyClickListener {
17 | private ArrayList list;
18 | private AutoVerticalScrollTextViewUtil aUtil;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_main);
24 |
25 | AutoVerticalScrollTextView textView = (AutoVerticalScrollTextView) findViewById(R.id.autoVerticalScrollTextView);
26 |
27 | list = new ArrayList<>();
28 | for (int i = 0; i < 5; i++) {
29 | if (i == 0 || i == 2 || i == 4) {
30 | list.add(Html.fromHtml("" + "测试垂直滚动" + "" + i + "特殊"));
31 | } else {
32 | list.add("测试垂直滚动" + i);
33 | }
34 | }
35 |
36 | // 初始化
37 | aUtil = new AutoVerticalScrollTextViewUtil(textView, list);
38 |
39 | aUtil.setDuration(5000)// 设置上下滚动事件间隔
40 | .setTextColor(Color.parseColor("#40aff2"))
41 | .setTextSize(12)
42 | .start();
43 |
44 | // 点击事件监听
45 | aUtil.setOnMyClickListener(this);
46 |
47 |
48 | TextView testTv = (TextView) findViewById(R.id.tv_test);
49 |
50 | // testTv.setText("测试修改颜色");
51 | // SpannableStringTextViewUtil.updateForeColorSpan(testTv, 1, 3, "#40aff2");
52 |
53 | // testTv.setText("测试添加颜色");
54 | // SpannableStringTextViewUtil.addForeColorSpan(testTv, "TEST", 1, 3 , "#40aff2");
55 |
56 | // testTv.setText("测试修改颜色");
57 | // SpannableStringTextViewUtil.updateBackColorSpan(testTv, 1, 3, "#40aff2");
58 |
59 | // testTv.setText("测试添加颜色");
60 | // SpannableStringTextViewUtil.addBackColorSpan(testTv, "TEST", 1, 3 , "#40aff2");
61 |
62 | // testTv.setText("测试添加文本大小");
63 | // SpannableStringTextViewUtil.addFontSizeSpan(testTv, "TEST", 1, 3, 60);
64 |
65 | // testTv.setText("测试添加超链接");
66 | // SpannableStringTextViewUtil.addUrlSpan(testTv, "超链接", 0, 3, "http://www.baidu.com");
67 |
68 | // testTv.setText("测试添加点击");
69 | // SpannableStringTextViewUtil.addClickableSpan(testTv, "点击", 0, 2, new SpannableStringTextViewUtil.OnClickSpanListener() {
70 | // @Override
71 | // public void onClickSpan() {
72 | // Toast.makeText(MainActivity.this, "点击", Toast.LENGTH_SHORT).show();
73 | // }
74 | // });
75 |
76 | // testTv.setText("测试添加粗体+斜体");
77 | // SpannableStringTextViewUtil.addStyleSpan(testTv, "TEST", 0, 3);
78 |
79 | // testTv.setText("测试添加粗体");
80 | // SpannableStringTextViewUtil.addStyleBoldSpan(testTv, "TEST", 0, 3);
81 |
82 | // testTv.setText("测试添加斜体");
83 | // SpannableStringTextViewUtil.addStyleItalicSpan(testTv, "TEST", 0, 3);
84 |
85 | // testTv.setText("测试添加删除线");
86 | // SpannableStringTextViewUtil.addStrikeSpan(testTv, "TEST", 0 , 3);
87 |
88 | // testTv.setText("测试修改删除线");
89 | // SpannableStringTextViewUtil.updateStrikeMySelfSpan(testTv, 0 , 3);
90 |
91 | // testTv.setText("测试添加下划线");
92 | // SpannableStringTextViewUtil.addUnderLineSpan(testTv, "下划线", 0, 3);
93 |
94 | testTv.setText("测试添加图片");
95 | SpannableStringTextViewUtil.addImageSpan(testTv, getResources().getDrawable(R.mipmap.ic_launcher));
96 | }
97 |
98 | // autoVerticalScrollTextView点击事件监听
99 | @Override
100 | public void onMyClickListener(int position, CharSequence title) {
101 | Toast.makeText(this, list.get(position) + " --- " + title, Toast.LENGTH_SHORT).show();
102 | if (aUtil.getIsRunning())
103 | // 停止滚动
104 | aUtil.stop();
105 | else
106 | // 开启滚动
107 | aUtil.start();
108 | }
109 |
110 | @Override
111 | protected void onDestroy() {
112 | super.onDestroy();
113 | aUtil.stop();
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
19 |
20 |
21 |
25 |
26 |
27 |
39 |
40 |
45 |
46 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zrunker/ZTextView/aeb5210e8be33ca2a4c63adcb170070b4dbd553a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ZTextView
3 | 案例,通过在XML中进行TextView属性设置来实现跑马灯!这里需要三个方面,简单,文本长度,单行显示。
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/cc/ibooker/ztextview/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextview;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/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 | google()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:3.0.1'
10 |
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | google()
20 | }
21 | }
22 |
23 | task clean(type: Delete) {
24 | delete rootProject.buildDir
25 | }
26 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':ztextviewlib'
2 |
--------------------------------------------------------------------------------
/ztextviewlib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/ztextviewlib/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.2"
6 |
7 | defaultConfig {
8 | minSdkVersion 15
9 | targetSdkVersion 25
10 | versionCode 1
11 | versionName "1.0"
12 |
13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14 |
15 | }
16 | buildTypes {
17 | release {
18 | minifyEnabled false
19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
20 | }
21 | }
22 | }
23 |
24 | dependencies {
25 | compile fileTree(dir: 'libs', include: ['*.jar'])
26 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
27 | exclude group: 'com.android.support', module: 'support-annotations'
28 | })
29 | compile 'com.android.support:appcompat-v7:25.3.1'
30 | testCompile 'junit:junit:4.12'
31 | }
32 |
--------------------------------------------------------------------------------
/ztextviewlib/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 E:\Android_Stadio\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 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/ztextviewlib/src/androidTest/java/cc/ibooker/ztextviewlib/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextviewlib;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("cc.ibooker.ztextviewlib.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/ztextviewlib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ztextviewlib/src/main/java/cc/ibooker/ztextviewlib/AutoVerticalScrollTextView.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextviewlib;
2 |
3 | import android.content.Context;
4 | import android.graphics.Camera;
5 | import android.graphics.Color;
6 | import android.graphics.Matrix;
7 | import android.text.TextUtils;
8 | import android.util.AttributeSet;
9 | import android.view.Gravity;
10 | import android.view.View;
11 | import android.view.animation.AccelerateInterpolator;
12 | import android.view.animation.Animation;
13 | import android.view.animation.Transformation;
14 | import android.widget.TextSwitcher;
15 | import android.widget.TextView;
16 | import android.widget.ViewSwitcher;
17 |
18 | /**
19 | * 自动垂直滚动的TextView
20 | */
21 | public class AutoVerticalScrollTextView extends TextSwitcher implements ViewSwitcher.ViewFactory {
22 | private Context mContext;
23 | // mInUp,mOutUp分别构成向下翻页的进出动画
24 | private Rotate3dAnimation mInUp;
25 | private Rotate3dAnimation mOutUp;
26 |
27 | private float textSize = 13; // 设置字体大小
28 | private int textColor = Color.parseColor("#555555");// 设置字体颜色
29 |
30 | float getTextSize() {
31 | return textSize;
32 | }
33 |
34 | void setTextSize(float textSize) {
35 | for (int i = 0; i < getChildCount(); i++) {
36 | ((TextView) getChildAt(i)).setTextSize(textSize);
37 | }
38 | this.textSize = textSize;
39 | }
40 |
41 | int getTextColor() {
42 | return textColor;
43 | }
44 |
45 | protected void setTextColor(int textColor) {
46 | for (int i = 0; i < getChildCount(); i++) {
47 | ((TextView) getChildAt(i)).setTextColor(textColor);
48 | }
49 | this.textColor = textColor;
50 | }
51 |
52 | // 构造方法
53 | public AutoVerticalScrollTextView(Context context) {
54 | this(context, null);
55 | }
56 |
57 | public AutoVerticalScrollTextView(Context context, AttributeSet attrs) {
58 | super(context, attrs);
59 |
60 | mContext = context;
61 | init();
62 | }
63 |
64 | // 初始化
65 | private void init() {
66 | setFactory(this);
67 |
68 | mInUp = createAnim(true, true);
69 | mOutUp = createAnim(false, true);
70 |
71 | setInAnimation(mInUp);//当View显示时动画资源ID
72 | setOutAnimation(mOutUp);//当View隐藏是动画资源ID。
73 | }
74 |
75 | // 创建Rotate3dAnimation
76 | private Rotate3dAnimation createAnim(boolean turnIn, boolean turnUp) {
77 | Rotate3dAnimation rotation = new Rotate3dAnimation(turnIn, turnUp);
78 | rotation.setDuration(1000);//执行动画的时间
79 | rotation.setFillAfter(false);//是否保持动画完毕之后的状态
80 | rotation.setInterpolator(new AccelerateInterpolator());//设置加速模式
81 | return rotation;
82 | }
83 |
84 | // 这里返回的TextView,就是我们看到的View,可以设置自己想要的效果
85 | @Override
86 | public View makeView() {
87 | TextView textView = new TextView(mContext);
88 | textView.setGravity(Gravity.START);
89 | textView.setTextSize(textSize);
90 | textView.setSingleLine(true);
91 | textView.setGravity(Gravity.CENTER_VERTICAL);
92 | textView.setEllipsize(TextUtils.TruncateAt.END);
93 | textView.setTextColor(textColor);
94 | return textView;
95 | }
96 |
97 | // 定义动作,向上滚动翻页
98 | public void next() {
99 | //显示动画
100 | if (getInAnimation() != mInUp)
101 | setInAnimation(mInUp);
102 | //隐藏动画
103 | if (getOutAnimation() != mOutUp)
104 | setOutAnimation(mOutUp);
105 | }
106 |
107 | private class Rotate3dAnimation extends Animation {
108 | private float mCenterX;
109 | private float mCenterY;
110 | private final boolean mTurnIn;
111 | private final boolean mTurnUp;
112 | private Camera mCamera;// 用来保存初始Camera
113 |
114 | Rotate3dAnimation(boolean turnIn, boolean turnUp) {
115 | mTurnIn = turnIn;
116 | mTurnUp = turnUp;
117 | }
118 |
119 | @Override
120 | public void initialize(int width, int height, int parentWidth, int parentHeight) {
121 | super.initialize(width, height, parentWidth, parentHeight);
122 | // 用来记录,初始Camera 高度 宽度
123 | mCamera = new Camera();
124 | mCenterY = getHeight();
125 | mCenterX = getWidth();
126 | }
127 |
128 | /**
129 | * interpolatedTime 0~1
130 | * t 转换
131 | */
132 | @Override
133 | protected void applyTransformation(float interpolatedTime, Transformation t) {
134 | final float centerX = mCenterX;
135 | final float centerY = mCenterY;
136 | final Camera camera = mCamera;
137 | // 标记是进入还是退出,-1进入,1推送
138 | final int derection = mTurnUp ? 1 : -1;
139 | // 获取转换矩阵
140 | final Matrix matrix = t.getMatrix();
141 |
142 | camera.save();
143 | if (mTurnIn) {
144 | // 进入时候,0 -> (derection * mCenterY * (interpolatedTime - 1.0f))[负值] -> 0
145 | camera.translate(0.0f, derection * mCenterY * (interpolatedTime - 1.0f), 0.0f);
146 | } else {
147 | // 退出时候,0 -> (derection * mCenterY * (interpolatedTime - 1.0f))[正值] -> 0
148 | camera.translate(0.0f, derection * mCenterY * (interpolatedTime), 0.0f);
149 | }
150 | camera.getMatrix(matrix);
151 | camera.restore();
152 |
153 | matrix.preTranslate(-centerX, -centerY);
154 | matrix.postTranslate(centerX, centerY);
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/ztextviewlib/src/main/java/cc/ibooker/ztextviewlib/AutoVerticalScrollTextViewUtil.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextviewlib;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 | import android.support.annotation.ColorInt;
6 | import android.text.TextUtils;
7 | import android.view.View;
8 |
9 | import java.lang.ref.WeakReference;
10 | import java.util.ArrayList;
11 | import java.util.concurrent.ExecutorService;
12 | import java.util.concurrent.Executors;
13 |
14 | /**
15 | * 用来管理AutoVerticalScrollTextView
16 | * Created by 邹峰立 on 2017/6/30.
17 | */
18 | public class AutoVerticalScrollTextViewUtil {
19 | private static final int MESSAGE_CODE = 200;
20 |
21 | private long duration = 1000;// 停顿时间毫秒(ms)-默认1s
22 |
23 | private MyHandler handler = new MyHandler(this);
24 |
25 | private AutoVerticalScrollTextView textView;// 目标TextView
26 |
27 | private ExecutorService executorService;// 线程池
28 |
29 | private boolean isRunning;// 标记是否为滚动状态
30 |
31 | private int number = 0;// 用来记录滚动次数
32 | private int currentPos = 0;// 标记当前显示哪一项
33 |
34 | private ArrayList mDatas = new ArrayList<>();// 需要轮播的数据源
35 |
36 | private CharSequence title;// 需要改变TextView上面的文本内容
37 |
38 | // 构造方法
39 | public AutoVerticalScrollTextViewUtil(final AutoVerticalScrollTextView textView, ArrayList datas) {
40 | this.mDatas = datas;
41 | this.textView = textView;
42 | // 控件点击事件监听
43 | this.textView.setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | if (ZTextViewClickUtil.isFastClick())
47 | return;
48 | if (onMyClickListener != null)
49 | onMyClickListener.onMyClickListener(currentPos, title);
50 | }
51 | });
52 | }
53 |
54 | // 设置停顿时间ms
55 | public AutoVerticalScrollTextViewUtil setDuration(long duration) {
56 | this.duration = duration;
57 | return this;
58 | }
59 |
60 | // 开始轮播
61 | public void start() {
62 | isRunning = true;
63 | // 开启线程
64 | startThread();
65 | }
66 |
67 | // 关闭轮播
68 | public void stop() {
69 | isRunning = false;
70 | if (executorService != null)
71 | executorService.shutdownNow();
72 | }
73 |
74 | // 获取当前运行状态
75 | public boolean getIsRunning() {
76 | return isRunning;
77 | }
78 |
79 | // 设置字体大小
80 | public AutoVerticalScrollTextViewUtil setTextSize(float textSize) {
81 | textView.setTextSize(textSize);
82 | return this;
83 | }
84 |
85 | // 设置字体颜色
86 | public AutoVerticalScrollTextViewUtil setTextColor(@ColorInt int textColor) {
87 | textView.setTextColor(textColor);
88 | return this;
89 | }
90 |
91 | // 开启线程
92 | private void startThread() {
93 | // 定义一个执行线程
94 | Thread thread = new Thread(new Runnable() {
95 | @Override
96 | public void run() {
97 | try {
98 | if (mDatas == null || mDatas.size() <= 0) {
99 | // 当数据源为空的时候,什么都不做
100 | isRunning = false;
101 | } else {
102 | while (isRunning) {
103 | // 获取要显示的数据
104 | currentPos = number % mDatas.size();
105 | title = mDatas.get(currentPos);
106 | number++;
107 | // 改变文本显示
108 | handler.sendEmptyMessage(MESSAGE_CODE);
109 | // 停顿
110 | Thread.sleep(duration);
111 | }
112 | }
113 | } catch (InterruptedException e) {
114 | e.printStackTrace();
115 | }
116 | }
117 | });
118 | // 线程池进行管理
119 | if (executorService == null || executorService.isShutdown())
120 | executorService = Executors.newSingleThreadScheduledExecutor();
121 | executorService.execute(thread);
122 | }
123 |
124 | // 定义Handler修改主线程
125 | private static class MyHandler extends Handler {
126 | // 软引用
127 | private final WeakReference mUtil;
128 |
129 | MyHandler(AutoVerticalScrollTextViewUtil util) {
130 | mUtil = new WeakReference<>(util);
131 | }
132 |
133 | @Override
134 | public void handleMessage(Message msg) {
135 | AutoVerticalScrollTextViewUtil currentUtil = mUtil.get();
136 | if (msg.what == MESSAGE_CODE) {
137 | currentUtil.textView.next();
138 | if (!TextUtils.isEmpty(currentUtil.title))
139 | currentUtil.textView.setText(currentUtil.title);
140 | }
141 | }
142 | }
143 |
144 | // 点击事件监听
145 | public interface OnMyClickListener {
146 | void onMyClickListener(int position, CharSequence title);
147 | }
148 |
149 | private OnMyClickListener onMyClickListener;
150 |
151 | public void setOnMyClickListener(OnMyClickListener onMyClickListener) {
152 | this.onMyClickListener = onMyClickListener;
153 | }
154 | }
--------------------------------------------------------------------------------
/ztextviewlib/src/main/java/cc/ibooker/ztextviewlib/MarqueeTextView.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextviewlib;
2 |
3 | import android.content.Context;
4 | import android.text.TextUtils;
5 | import android.util.AttributeSet;
6 |
7 | /**
8 | * 跑马灯TextView-自动聚焦
9 | * Created by 邹峰立 on 2017/6/12.
10 | */
11 | public class MarqueeTextView extends android.support.v7.widget.AppCompatTextView {
12 |
13 | public MarqueeTextView(Context context) {
14 | this(context, null);
15 | }
16 |
17 | public MarqueeTextView(Context context, AttributeSet attrs) {
18 | this(context, attrs, 0);
19 | }
20 |
21 | public MarqueeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
22 | super(context, attrs, defStyleAttr);
23 | init();
24 | }
25 |
26 | // 初始化
27 | private void init() {
28 | // 设置文本超出部分模式
29 | this.setEllipsize(TextUtils.TruncateAt.MARQUEE);
30 | // 设置跑马灯重复次数,-1为无限重复
31 | this.setMarqueeRepeatLimit(-1);
32 | // 单行显示
33 | this.setSingleLine(true);
34 | this.setMaxLines(1);
35 | }
36 |
37 | // 焦点 聚焦
38 | @Override
39 | public boolean isFocused() {
40 | return true;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/ztextviewlib/src/main/java/cc/ibooker/ztextviewlib/SpannableStringTextViewUtil.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextviewlib;
2 |
3 | import android.graphics.Color;
4 | import android.graphics.Typeface;
5 | import android.graphics.drawable.Drawable;
6 | import android.text.Spannable;
7 | import android.text.SpannableString;
8 | import android.text.SpannableStringBuilder;
9 | import android.text.Spanned;
10 | import android.text.method.LinkMovementMethod;
11 | import android.text.style.AbsoluteSizeSpan;
12 | import android.text.style.BackgroundColorSpan;
13 | import android.text.style.ClickableSpan;
14 | import android.text.style.ForegroundColorSpan;
15 | import android.text.style.ImageSpan;
16 | import android.text.style.StrikethroughSpan;
17 | import android.text.style.StyleSpan;
18 | import android.text.style.URLSpan;
19 | import android.text.style.UnderlineSpan;
20 | import android.view.View;
21 | import android.widget.TextView;
22 |
23 | /**
24 | * TextView文本管理类
25 | * 注意几个属性:
26 | * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE(前后都不包括)、
27 | * Spanned.SPAN_INCLUSIVE_EXCLUSIVE(前面包括,后面不包括)、
28 | * Spanned.SPAN_EXCLUSIVE_INCLUSIVE(前面不包括,后面包括)、
29 | * Spanned.SPAN_INCLUSIVE_INCLUSIVE(前后都包括)
30 | * Created by 邹峰立 on 2017/7/10.
31 | */
32 | public class SpannableStringTextViewUtil {
33 | /**
34 | * 修改TextView原有字体颜色
35 | *
36 | * @param tv TextView
37 | * @param start 开始位置
38 | * @param end 结束位置
39 | * @param color 颜色 16进制
40 | */
41 | public static void updateForeColorSpan(TextView tv, int start, int end, String color) {
42 | try {
43 | String text = tv.getText().toString();
44 | SpannableStringBuilder builder = new SpannableStringBuilder(text);
45 | // ForegroundColorSpan为文字前景色
46 | ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.parseColor(color));
47 | builder.setSpan(colorSpan, start, end >= text.length() ? text.length() : end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
48 | tv.setText(builder);
49 | } catch (Exception e) {
50 | e.printStackTrace();
51 | }
52 | }
53 |
54 | /**
55 | * 在TextView文本最后添加新文本,新文本可自定义颜色
56 | *
57 | * @param tv 要修改的TextView
58 | * @param text 添加的文本
59 | * @param tStart 修改开始的位置
60 | * @param tEnd 修改结束的位置
61 | * @param color 文本颜色 16进制
62 | */
63 | public static void addForeColorSpan(TextView tv, String text, int tStart, int tEnd, String color) {
64 | try {
65 | SpannableString spanString = new SpannableString(text);
66 | // ForegroundColorSpan为文字前景色
67 | ForegroundColorSpan span = new ForegroundColorSpan(Color.parseColor(color));
68 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
69 | tv.append(spanString);
70 | } catch (Exception e) {
71 | e.printStackTrace();
72 | }
73 | }
74 |
75 | /**
76 | * 修改TextView原有字体背景颜色
77 | *
78 | * @param tv TextView
79 | * @param start 开始位置
80 | * @param end 结束位置
81 | * @param color 颜色 16进制
82 | */
83 | public static void updateBackColorSpan(TextView tv, int start, int end, String color) {
84 | try {
85 | String text = tv.getText().toString();
86 | SpannableStringBuilder builder = new SpannableStringBuilder(text);
87 | // BackgroundColorSpan为文字背景色
88 | BackgroundColorSpan colorSpan = new BackgroundColorSpan(Color.parseColor(color));
89 | builder.setSpan(colorSpan, start, end >= text.length() ? text.length() : end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
90 | tv.setText(builder);
91 | } catch (Exception e) {
92 | e.printStackTrace();
93 | }
94 | }
95 |
96 | /**
97 | * 在TextView文本最后添加新文本,新文本可自定义背景颜色
98 | *
99 | * @param tv 要修改的TextView
100 | * @param text 添加的文本
101 | * @param tStart 修改开始的位置
102 | * @param tEnd 修改结束的位置
103 | * @param color 文本颜色 16进制
104 | */
105 | public static void addBackColorSpan(TextView tv, String text, int tStart, int tEnd, String color) {
106 | try {
107 | SpannableString spanString = new SpannableString(text);
108 | // BackgroundColorSpan为文字背景色
109 | BackgroundColorSpan span = new BackgroundColorSpan(Color.parseColor(color));
110 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
111 | tv.append(spanString);
112 | } catch (Exception e) {
113 | e.printStackTrace();
114 | }
115 | }
116 |
117 | /**
118 | * 在TextView文本最后添加新文本,新文本可自定义字体大小
119 | *
120 | * @param tv 要修改的TextView
121 | * @param text 添加的文本
122 | * @param tStart 修改开始的位置
123 | * @param tEnd 修改结束的位置
124 | * @param size 文本大小
125 | */
126 | public static void addFontSizeSpan(TextView tv, String text, int tStart, int tEnd, int size) {
127 | try {
128 | SpannableString spanString = new SpannableString(text);
129 | AbsoluteSizeSpan span = new AbsoluteSizeSpan(size);
130 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
131 | tv.append(spanString);
132 | } catch (Exception e) {
133 | e.printStackTrace();
134 | }
135 | }
136 |
137 | /**
138 | * 在TextView文本最后添加新文本,新文本可自定义超链接
139 | *
140 | * @param tv 要修改的TextView
141 | * @param text 添加的文本
142 | * @param tStart 修改开始的位置
143 | * @param tEnd 修改结束的位置
144 | * @param oper 所要进行的操作如:"http://www.baidu.com"、"tel:10086"、"sms:10086"
145 | */
146 | public static void addUrlSpan(TextView tv, String text, int tStart, int tEnd, String oper) {
147 | try {
148 | SpannableString spanString = new SpannableString(text);
149 | URLSpan span = new URLSpan(oper);
150 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
151 | tv.setMovementMethod(LinkMovementMethod.getInstance());//不设置,没有点击效果
152 | tv.append(spanString);
153 | } catch (Exception e) {
154 | e.printStackTrace();
155 | }
156 | }
157 |
158 | /**
159 | * 在TextView文本最后添加新文本,新文本可自定义点击效果
160 | *
161 | * @param tv 要修改的TextView
162 | * @param text 添加的文本
163 | * @param tStart 修改开始的位置
164 | * @param tEnd 修改结束的位置
165 | * @param onClickSpanListener 所要进行的操作
166 | */
167 | public static void addClickableSpan(TextView tv, String text, int tStart, int tEnd, final OnClickSpanListener onClickSpanListener) {
168 | try {
169 | SpannableStringBuilder builder = new SpannableStringBuilder(text);
170 | // 设置文字点击事件
171 | ClickableSpan clickableSpan = new ClickableSpan() {
172 | @Override
173 | public void onClick(View widget) {
174 | if (onClickSpanListener != null)
175 | onClickSpanListener.onClickSpan();
176 | }
177 | };
178 | builder.setSpan(clickableSpan, tStart, tEnd >= text.length() ? text.length() : tEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
179 | tv.setMovementMethod(LinkMovementMethod.getInstance());//不设置,没有点击效果
180 | tv.append(builder);
181 | } catch (Exception e) {
182 | e.printStackTrace();
183 | }
184 | }
185 |
186 | // ClickableSpan点击监听接口
187 | public interface OnClickSpanListener {
188 | void onClickSpan();
189 | }
190 |
191 | /**
192 | * 在TextView文本最后添加新文本,新文本可自定义粗体,斜体
193 | *
194 | * @param tv 要修改的TextView
195 | * @param text 添加的文本
196 | * @param tStart 修改开始的位置
197 | * @param tEnd 修改结束的位置
198 | */
199 | public static void addStyleSpan(TextView tv, String text, int tStart, int tEnd) {
200 | try {
201 | SpannableString spanString = new SpannableString(text);
202 | StyleSpan span = new StyleSpan(Typeface.BOLD_ITALIC);
203 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
204 | tv.append(spanString);
205 | } catch (Exception e) {
206 | e.printStackTrace();
207 | }
208 | }
209 |
210 | /**
211 | * 在TextView文本最后添加新文本,新文本可自定义粗体
212 | *
213 | * @param tv 要修改的TextView
214 | * @param text 添加的文本
215 | * @param tStart 修改开始的位置
216 | * @param tEnd 修改结束的位置
217 | */
218 | public static void addStyleBoldSpan(TextView tv, String text, int tStart, int tEnd) {
219 | try {
220 | SpannableString spanString = new SpannableString(text);
221 | StyleSpan span = new StyleSpan(Typeface.BOLD);
222 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
223 | tv.append(spanString);
224 | } catch (Exception e) {
225 | e.printStackTrace();
226 | }
227 | }
228 |
229 | /**
230 | * 在TextView文本最后添加新文本,新文本可自定义斜体
231 | *
232 | * @param tv 要修改的TextView
233 | * @param text 添加的文本
234 | * @param tStart 修改开始的位置
235 | * @param tEnd 修改结束的位置
236 | */
237 | public static void addStyleItalicSpan(TextView tv, String text, int tStart, int tEnd) {
238 | try {
239 | SpannableString spanString = new SpannableString(text);
240 | StyleSpan span = new StyleSpan(Typeface.ITALIC);
241 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
242 | tv.append(spanString);
243 | } catch (Exception e) {
244 | e.printStackTrace();
245 | }
246 | }
247 |
248 | /**
249 | * 在TextView文本最后添加新文本,新文本可自定义删除线
250 | *
251 | * @param tv 要修改的TextView
252 | * @param text 添加的文本
253 | * @param tStart 修改开始的位置
254 | * @param tEnd 修改结束的位置
255 | */
256 | public static void addStrikeSpan(TextView tv, String text, int tStart, int tEnd) {
257 | try {
258 | SpannableString spanString = new SpannableString(text);
259 | StrikethroughSpan span = new StrikethroughSpan();
260 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
261 | tv.append(spanString);
262 | } catch (Exception e) {
263 | e.printStackTrace();
264 | }
265 | }
266 |
267 | /**
268 | * 修改原有文本删除线效果
269 | *
270 | * @param tv 要修改的TextView
271 | * @param start 修改开始的位置
272 | * @param end 修改结束的位置
273 | */
274 | public static void updateStrikeMySelfSpan(TextView tv, int start, int end) {
275 | try {
276 | String text = tv.getText().toString().trim();
277 | SpannableString spanString = new SpannableString(text);
278 | StrikethroughSpan span = new StrikethroughSpan();
279 | spanString.setSpan(span, start, end >= text.length() ? text.length() : end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
280 | tv.setText(spanString);
281 | } catch (Exception e) {
282 | e.printStackTrace();
283 | }
284 | }
285 |
286 | /**
287 | * 在TextView文本最后添加新文本,新文本可自定义下划线
288 | *
289 | * @param tv 要修改的TextView
290 | * @param text 添加的文本
291 | * @param tStart 修改开始的位置
292 | * @param tEnd 修改结束的位置
293 | */
294 | public static void addUnderLineSpan(TextView tv, String text, int tStart, int tEnd) {
295 | try {
296 | SpannableString spanString = new SpannableString(text);
297 | UnderlineSpan span = new UnderlineSpan();
298 | spanString.setSpan(span, tStart, tEnd >= text.length() ? text.length() : tEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
299 | tv.append(spanString);
300 | } catch (Exception e) {
301 | e.printStackTrace();
302 | }
303 | }
304 |
305 | /**
306 | * 在TextView文本最后添加图片
307 | *
308 | * @param tv 要修改的TextView
309 | * @param d 图片
310 | */
311 | public static void addImageSpan(TextView tv, Drawable d) {
312 | try {
313 | SpannableString spanString = new SpannableString(" ");
314 | d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
315 | ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
316 | spanString.setSpan(span, 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
317 | tv.append(spanString);
318 | } catch (Exception e) {
319 | e.printStackTrace();
320 | }
321 | }
322 | }
323 |
--------------------------------------------------------------------------------
/ztextviewlib/src/main/java/cc/ibooker/ztextviewlib/ZTextViewClickUtil.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextviewlib;
2 |
3 | /**
4 | * 点击事件处理
5 | */
6 | public class ZTextViewClickUtil {
7 | private static long lastClickTime;
8 |
9 | // 判断是否为快速点击事件
10 | public synchronized static boolean isFastClick() {
11 | long time = System.currentTimeMillis();
12 | if (time - lastClickTime < 500)
13 | return true;
14 | lastClickTime = time;
15 | return false;
16 | }
17 | }
--------------------------------------------------------------------------------
/ztextviewlib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | ZTextViewLib
3 |
4 |
--------------------------------------------------------------------------------
/ztextviewlib/src/test/java/cc/ibooker/ztextviewlib/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package cc.ibooker.ztextviewlib;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------