Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ dependencies {
android:maxLines="10"
app:expandAction="More"
app:limitedMaxLines="2"
app:expandActionColor="@color/blue_500"
app:actionColor="@color/blue_500"
app:originalText="@string/long_text" />
```

Expand All @@ -72,15 +72,15 @@ dependencies {
|:---------------------:|:------:|:-----------------------------------------------------------:|:-------------------------------------------------------:|
| app:limitedMaxLines | Int | The maximum line counts when the text is collapsed | 3 |
| app:expandAction | String | The action at the end of truncated text such as "View more" | "" (Nothing will be shown at the end of truncated text) |
| app:expandActionColor | Color | The color of expand action | #ffaa66cc |
| app:actionColor | Color | The color of expand/collapse action | #ffaa66cc |
| app:originalText | String | The text to be displayed on this text view | "" |

#### Public functions

- `limitedMaxLines` public getter & setter for the maximum line counts when the text is collapsed.
- `expandAction` public getter & setter for the action at the end of truncated text such as "View
more".
- `expandActionColor` public getter & setter for the color of expand action.
- `actionColor` public getter & setter for the color of expand/collapse action.
- `originalText` public getter & setter for the text to be displayed on this text view.
- `collapsed` public getter to determine if the text is being collapsed
- `expanded` public getter to determine if the text is being expanded
Expand Down Expand Up @@ -108,7 +108,7 @@ ExpandableText(
originalText = "a very long text that will be truncated at some points",
expandAction = "See more",
expand = expand,
expandActionColor = Color.Blue,
actionColor = Color.Blue,
limitedMaxLines = 2,
animationSpec = spring(),
modifier = Modifier
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/io/github/giangpham96/app/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class MainActivity : AppCompatActivity() {
btnExpandCtaColor.setOnClickListener {
val ctaColorSet =
setOf(Color.WHITE, Color.BLACK, Color.BLUE, Color.CYAN, Color.MAGENTA, Color.RED, Color.DKGRAY)
tvDynamic.expandActionColor = ctaColorSet.random()
tvDynamic.actionColor = ctaColorSet.random()
}
btnMaxLines.setOnClickListener {
tvDynamic.maxLines = Random.nextInt(7, 20)
Expand Down Expand Up @@ -120,7 +120,7 @@ class MainActivity : AppCompatActivity() {
originalText = stringResource(id = R.string.long_text),
expandAction = "See more",
expand = expand,
expandActionColor = androidx.compose.ui.graphics.Color.Blue,
actionColor = androidx.compose.ui.graphics.Color.Blue,
)
}
}
Expand Down
25 changes: 22 additions & 3 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,26 @@
android:background="@color/purple_100"
android:padding="16dp"
app:expandAction="More"
app:expandActionColor="@color/blue_500"
app:actionColor="@color/blue_500"
app:originalText="@string/long_text" />

<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/purple_500"
android:padding="16dp"
android:text="More / Less Text"
android:textColor="@android:color/white"
android:textStyle="bold"
tools:ignore="HardcodedText" />
<io.github.giangpham96.expandable_textview.ExpandableTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/purple_100"
android:padding="16dp"
app:expandAction="More"
app:actionColor="@color/blue_500"
app:collapseAction="Less More"
app:originalText="@string/long_text" />

<androidx.appcompat.widget.AppCompatTextView
Expand Down Expand Up @@ -104,7 +123,7 @@
android:padding="16dp"
app:limitedMaxLines="2"
app:expandAction="More"
app:expandActionColor="@color/blue_500"
app:actionColor="@color/blue_500"
app:originalText="@string/long_text" />

<androidx.appcompat.widget.AppCompatTextView
Expand Down Expand Up @@ -155,7 +174,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:text="Change expandActionColor"
android:text="Change actionColor"
tools:ignore="HardcodedText" />

<androidx.appcompat.widget.AppCompatButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import androidx.compose.ui.unit.dp
* @param originalText The text that might be truncated/collapsed if too long
* @param expandAction The text that is appended at the end of the collapsed text
* @param expand Whether the text should be expanded or not. Default to false
* @param expandActionColor The color of [expandAction]
* @param actionColor The color of [expandAction]
* @param limitedMaxLines The number of lines displayed when the text collapses
* @param modifier [Modifier] to apply to this layout node.
* @param color [Color] to apply to the text. If [Color.Unspecified], and [style] has no color set,
Expand All @@ -78,7 +78,7 @@ fun ExpandableText(
expandAction: String,
modifier: Modifier = Modifier,
expand: Boolean = false,
expandActionColor: Color = Color.Unspecified,
actionColor: Color = Color.Unspecified,
limitedMaxLines: Int = 3,
color: Color = Color.Unspecified,
fontSize: TextUnit = TextUnit.Unspecified,
Expand Down Expand Up @@ -110,7 +110,7 @@ fun ExpandableText(
originalText = originalText,
expandAction = expandAction,
expand = expand,
expandActionColor = expandActionColor,
actionColor = actionColor,
limitedMaxLines = limitedMaxLines,
softWrap = softWrap,
textStyle = mergedStyle,
Expand Down Expand Up @@ -143,7 +143,7 @@ fun Constraints.rememberExpandableTextData(
originalText: String,
expandAction: String,
expand: Boolean,
expandActionColor: Color,
actionColor: Color,
limitedMaxLines: Int,
softWrap: Boolean,
textStyle: TextStyle,
Expand Down Expand Up @@ -175,7 +175,7 @@ fun Constraints.rememberExpandableTextData(
originalText = originalText,
expandAction = expandAction,
expandActionWidth = expandActionWidth,
expandActionColor = expandActionColor,
actionColor = actionColor,
)
var displayedText by remember {
mutableStateOf(if (expand) AnnotatedString(originalText) else collapsedText)
Expand Down Expand Up @@ -215,11 +215,11 @@ private fun TextLayoutResult.rememberCollapsedText(
originalText: String,
expandAction: String,
expandActionWidth: Int,
expandActionColor: Color,
actionColor: Color,
): AnnotatedString {
val lastLine = lineCount - 1
val lastCharacterIndex = getLineEnd(lastLine)
return remember(originalText, expandAction, expandActionWidth, expandActionColor) {
return remember(originalText, expandAction, expandActionWidth, actionColor) {
if (lastCharacterIndex == originalText.length) {
AnnotatedString(originalText)
} else {
Expand Down Expand Up @@ -247,7 +247,7 @@ private fun TextLayoutResult.rememberCollapsedText(
append(cutText)
append('…')
append(' ')
withStyle(SpanStyle(color = expandActionColor)) {
withStyle(SpanStyle(color = actionColor)) {
append(expandAction)
}
}
Expand Down Expand Up @@ -335,7 +335,7 @@ private fun PreviewRtl() = CompositionLocalProvider(LocalLayoutDirection provide
.background(Color.Gray)
.padding(16.dp),
expand = expand,
expandActionColor = Color.Blue
actionColor = Color.Blue
)
}
}
Expand All @@ -360,6 +360,6 @@ private fun Preview() = Box {
.background(Color.Gray)
.padding(16.dp),
expand = expand,
expandActionColor = Color.Blue
actionColor = Color.Blue
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,25 @@ class ExpandableTextView @JvmOverloads constructor(
val start = ellipsis.toString().length
expandActionSpannable = SpannableString("$ellipsis $value")
expandActionSpannable.setSpan(
ForegroundColorSpan(expandActionColor),
ForegroundColorSpan(actionColor),
start,
expandActionSpannable.length,
SPAN_EXCLUSIVE_EXCLUSIVE
)
updateCollapsedDisplayedText(ctaChanged = true)
}
private var collapseAction: String? = null
set(value) {
field = value
if(field == null) return
collapseActionSpannable = SpannableString(" $value")
collapseActionSpannable.setSpan(
ForegroundColorSpan(actionColor),
0,
collapseActionSpannable.length,
SPAN_EXCLUSIVE_EXCLUSIVE
)
}
var limitedMaxLines: Int = 3
set(value) {
check(maxLines == -1 || value <= maxLines) {
Expand All @@ -64,7 +76,7 @@ class ExpandableTextView @JvmOverloads constructor(
}

@ColorInt
var expandActionColor: Int = ContextCompat.getColor(context, android.R.color.holo_purple)
var actionColor: Int = ContextCompat.getColor(context, android.R.color.holo_purple)
set(value) {
field = value
val colorSpan = ForegroundColorSpan(value)
Expand All @@ -83,14 +95,16 @@ class ExpandableTextView @JvmOverloads constructor(
private var expandActionSpannable = SpannableString("")
private var expandActionStaticLayout: StaticLayout? = null
private var collapsedDisplayedText: CharSequence? = null
private var collapseActionSpannable = SpannableString("")

init {
ellipsize = END
val a = context.obtainStyledAttributes(attrs, R.styleable.ExpandableTextView)
expandAction = a.getString(R.styleable.ExpandableTextView_expandAction) ?: expandAction
expandActionColor = a.getColor(R.styleable.ExpandableTextView_expandActionColor, expandActionColor)
actionColor = a.getColor(R.styleable.ExpandableTextView_actionColor, actionColor)
originalText = a.getString(R.styleable.ExpandableTextView_originalText) ?: originalText
limitedMaxLines = a.getInt(R.styleable.ExpandableTextView_limitedMaxLines, limitedMaxLines)
collapseAction = a.getString(R.styleable.ExpandableTextView_collapseAction)
check(maxLines == -1 || limitedMaxLines <= maxLines) {
"""
maxLines ($maxLines) must be greater than or equal to limitedMaxLines ($limitedMaxLines).
Expand Down Expand Up @@ -143,7 +157,7 @@ class ExpandableTextView @JvmOverloads constructor(
return
}
val height0 = height
text = if (collapsed) originalText else collapsedDisplayedText
text = if (collapsed) originalText.addLessMoreSpan() else collapsedDisplayedText
measure(MeasureSpec.makeMeasureSpec(width, EXACTLY), MeasureSpec.makeMeasureSpec(height, UNSPECIFIED))
val height1 = measuredHeight
animator?.cancel()
Expand All @@ -166,7 +180,7 @@ class ExpandableTextView @JvmOverloads constructor(

override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation)
text = if (collapsed) collapsedDisplayedText else originalText
text = if (collapsed) collapsedDisplayedText else originalText.addLessMoreSpan()
val params = layoutParams
layoutParams.height = WRAP_CONTENT
layoutParams = params
Expand Down Expand Up @@ -271,4 +285,12 @@ class ExpandableTextView @JvmOverloads constructor(
}
}

private fun CharSequence.addLessMoreSpan(): CharSequence {
return when (collapseAction) {
null -> this@addLessMoreSpan
else -> return SpannableStringBuilder(this)
.append(collapseActionSpannable)
}
}

}
3 changes: 2 additions & 1 deletion expandable_textview/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
<attr name="limitedMaxLines" format="integer" />
<attr name="originalText" format="string" />
<attr name="expandAction" format="string" />
<attr name="expandActionColor" format="string" />
<attr name="actionColor" format="string" />
<attr name="collapseAction" format="string" />
</declare-styleable>

</resources>