Skip to content

Commit 0cf4243

Browse files
committed
Improve AnsiTextView and add optional Emoji2 support on it.
1 parent 4a0abc8 commit 0cf4243

File tree

6 files changed

+80
-22
lines changed

6 files changed

+80
-22
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# AndroidANSI
22
Android ANSI rendering library!
33

4-
See [Wikipedia ANSI Page](https://en.wikipedia.org/wiki/ANSI_escape_code)
4+
See [Wikipedia ANSI Page](https://en.wikipedia.org/wiki/ANSI_escape_code)
55
for more info on ANSI escape codes.
66

77
## Supported ANSI Codes
@@ -65,7 +65,7 @@ textView.setAnsiText("\\e[1;38;2;164;198;57mAndroid\\e[0;35mAN\u001B[2mSI\u001B[
6565
AnsiParser.FLAG_PARSE_DISABLE_SUBSCRIPT);
6666
```
6767

68-
## TextView w/o Java (Currently not working)
68+
## TextView w/o Java (WIP)
6969
```xml
7070
<?xml version="1.0" encoding="utf-8"?>
7171
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
@@ -78,12 +78,14 @@ textView.setAnsiText("\\e[1;38;2;164;198;57mAndroid\\e[0;35mAN\u001B[2mSI\u001B[
7878
<com.fox2code.androidansi.AnsiTextView
7979
android:layout_width="wrap_content"
8080
android:layout_height="wrap_content"
81-
app:setAnsiText="\e[38;5;82mHello \e[38;5;198mWorld"
81+
app:ansiText="\e[38;5;82mHello \e[38;5;198mWorld"
8282
android:id="@+id/ansiView"
8383
app:layout_constraintBottom_toBottomOf="parent"
8484
app:layout_constraintEnd_toEndOf="parent"
8585
app:layout_constraintStart_toStartOf="parent"
8686
app:layout_constraintTop_toTopOf="parent" />
8787

8888
</androidx.constraintlayout.widget.ConstraintLayout>
89-
```
89+
```
90+
91+
Note: AnsiTextView support Emoji2 if the library `androidx.emoji2:emoji2-views-helper:*` is added.

androidansiapp/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ dependencies {
3131
implementation(project(":library"))
3232
implementation 'androidx.appcompat:appcompat:1.4.1'
3333
implementation 'com.google.android.material:material:1.6.0'
34-
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
34+
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
3535
testImplementation 'junit:junit:4.13.2'
3636
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
3737
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
plugins {
3-
id 'com.android.library' version '7.2.0' apply false
4-
id 'com.android.application' version '7.2.0' apply false
3+
id 'com.android.library' version '7.2.1' apply false
4+
id 'com.android.application' version '7.2.1' apply false
55
}
66

77
task clean(type: Delete) {

library/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ android {
3131

3232
dependencies {
3333
api 'androidx.annotation:annotation:1.3.0'
34+
compileOnly('androidx.emoji2:emoji2-views-helper:1.1.0') {
35+
transitive = false
36+
}
3437
}
3538

3639
afterEvaluate {

library/src/main/java/com/fox2code/androidansi/AnsiTextView.java

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,95 @@
22

33
import static com.fox2code.androidansi.AnsiParser.parseAsSpannable;
44

5-
import android.annotation.SuppressLint;
65
import android.content.Context;
6+
import android.content.res.Resources;
77
import android.content.res.TypedArray;
8+
import android.text.InputFilter;
89
import android.util.AttributeSet;
10+
import android.util.Log;
911
import android.widget.TextView;
1012

1113
import androidx.annotation.NonNull;
14+
import androidx.emoji2.viewsintegration.EmojiTextViewHelper;
1215

13-
public class AnsiTextView extends TextView{
16+
public class AnsiTextView extends TextView {
17+
public static final int FLAG_PARSE_DISABLE_COLORS = AnsiParser.FLAG_PARSE_DISABLE_COLORS;
18+
public static final int FLAG_PARSE_DISABLE_ATTRIBUTES = AnsiParser.FLAG_PARSE_DISABLE_ATTRIBUTES;
19+
public static final int FLAG_PARSE_DISABLE_EXTRAS_COLORS = AnsiParser.FLAG_PARSE_DISABLE_EXTRAS_COLORS;
20+
public static final int FLAG_PARSE_DISABLE_SUBSCRIPT = AnsiParser.FLAG_PARSE_DISABLE_SUBSCRIPT;
1421

15-
public final int FLAG_PARSE_DISABLE_COLORS = AnsiParser.FLAG_PARSE_DISABLE_COLORS;
16-
public final int FLAG_PARSE_DISABLE_ATTRIBUTES = AnsiParser.FLAG_PARSE_DISABLE_ATTRIBUTES;
17-
public final int FLAG_PARSE_DISABLE_EXTRAS_COLORS = AnsiParser.FLAG_PARSE_DISABLE_EXTRAS_COLORS;
18-
public final int FLAG_PARSE_DISABLE_SUBSCRIPT = AnsiParser.FLAG_PARSE_DISABLE_SUBSCRIPT;
22+
private Object mEmojiTextViewHelper; // Hold reference without requiring hard references
23+
private int parseFlags = 0;
1924

2025
public AnsiTextView(Context context) {
2126
super(context);
27+
preInit();
2228
}
2329

2430
public AnsiTextView(Context context, AttributeSet attrs) {
2531
super(context, attrs);
26-
readAttr(context,attrs);
32+
preInit();
33+
readAttr(context, attrs);
2734
}
2835

2936
public AnsiTextView(Context context, AttributeSet attrs, int defStyle) {
3037
super(context, attrs, defStyle);
31-
readAttr(context,attrs);
38+
preInit();
39+
readAttr(context, attrs);
3240
}
3341

3442
public void setAnsiText(@NonNull String ansiText) {
35-
super.setText(parseAsSpannable(ansiText));
43+
super.setText(parseAsSpannable(ansiText, this.parseFlags));
3644
}
3745

3846
public void setAnsiText(@NonNull String ansiText, int parseFlags) {
3947
super.setText(parseAsSpannable(ansiText, parseFlags));
4048
}
4149

50+
private void preInit() {
51+
try { // Using "new" for optional classes is ok with ART
52+
mEmojiTextViewHelper = new EmojiTextViewHelper(this, false);
53+
((EmojiTextViewHelper) mEmojiTextViewHelper).updateTransformationMethod();
54+
} catch (Exception ignored) {
55+
mEmojiTextViewHelper = null;
56+
}
57+
}
58+
4259
private void readAttr(Context context, AttributeSet attrs) {
43-
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AnsiTextView);
44-
@NonNull String text = a.getString(R.styleable.AnsiTextView_setAnsiText) ;
45-
if (text != null) {
46-
super.setText(parseAsSpannable(text));
60+
TypedArray a = null;
61+
try {
62+
a = context.obtainStyledAttributes(attrs, R.styleable.AnsiTextView);
63+
@NonNull String text = a.getString(R.styleable.AnsiTextView_ansiText);
64+
int parseFlags = a.getInt(R.styleable.AnsiTextView_ansiText, -1);
65+
a.recycle(); a = null;
66+
if (parseFlags != -1) {
67+
this.parseFlags = parseFlags;
68+
} else {
69+
parseFlags = this.parseFlags;
70+
}
71+
if (text != null) {
72+
super.setText(parseAsSpannable(text, parseFlags));
73+
}
74+
} catch (Resources.NotFoundException e) {
75+
Log.w("AnsiTextView", "Failed to resolve ansiText resource!", e);
76+
} finally {
77+
if (a != null) a.recycle();
78+
}
79+
}
80+
81+
@Override
82+
public void setFilters(InputFilter[] filters) {
83+
if (this.mEmojiTextViewHelper != null) {
84+
filters = ((EmojiTextViewHelper) this.mEmojiTextViewHelper).getFilters(filters);
85+
}
86+
super.setFilters(filters);
87+
}
88+
89+
@Override
90+
public void setAllCaps(boolean allCaps) {
91+
super.setAllCaps(allCaps);
92+
if (this.mEmojiTextViewHelper != null) {
93+
((EmojiTextViewHelper) this.mEmojiTextViewHelper).setAllCaps(allCaps);
4794
}
48-
a.recycle();
4995
}
5096
}
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources>
33
<declare-styleable name="AnsiTextView">
4-
<attr name="setAnsiText" format="string" />
4+
<attr name="ansiText" format="string" />
5+
<attr name="ansiParseFlags">
6+
<flag name="none" value="0x0000" />
7+
<flag name="disableColors" value="0x0001" />
8+
<flag name="disableAttributes" value="0x0002" />
9+
<flag name="disableExtrasColors" value="0x0004" />
10+
<flag name="disableSubscript" value="0x0008" />
11+
</attr>
512
</declare-styleable>
613
</resources>

0 commit comments

Comments
 (0)