iojjj / roundedcornersbackgroundspan Goto Github PK
View Code? Open in Web Editor NEWImplementation of LineBackgroundSpan that adds rounded rectangle backgrounds to text.
Implementation of LineBackgroundSpan that adds rounded rectangle backgrounds to text.
Hi, thanks for great library.
My use case more difficult than example. I using RoundedCornersBackgroundSpan and SizeSpan at the same time. But Paint object does not define new text size and background not change. Proof below.
for (int i = 0; i < parts.length; i++) {
final String part = parts[i];
final String color = colors[i];
final SpannableString string = new SpannableString(part);
if (i == 3) {
string.setSpan(new RelativeSizeSpan(1.5 f), 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (!TextUtils.isEmpty(color)) {
final ForegroundColorSpan colorSpan = new ForegroundColorSpan(Color.WHITE);
string.setSpan(colorSpan, 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textPartsBuilder.addTextPart(string, Color.parseColor(color));
} else {
textPartsBuilder.addTextPart(part);
}
}
When setting a textview's span with the parameter ALIGN_CENTER, the end of the background is cut off. This only happens when the text does not wrap to the next line.
Also adding a space to the end of text causes the background to display correctly... but the background does not fit the text correctly anymore.
When text wraps to multiple lines it is displayed correctly
Here is an example activity and layout:
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.Gravity
import android.widget.TextView
import com.github.iojjj.rcbs.RoundedCornersBackgroundSpan
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val testTv = findViewById<TextView>(R.id.testTv)
val test2Tv = findViewById<TextView>(R.id.test2Tv)
val test3Tv = findViewById<TextView>(R.id.test3Tv)
testTv.gravity = Gravity.CENTER_HORIZONTAL
test2Tv.gravity = Gravity.CENTER_HORIZONTAL
test3Tv.gravity = Gravity.CENTER_HORIZONTAL
val padding = convertDpToPixel(4f, this)
val radius = convertDpToPixel(5f, this)
val span = RoundedCornersBackgroundSpan.Builder(this)
.addTextPart("Test",0x990000CC.toInt())
.setCornersRadius(radius)
.setTextPadding(padding)
.setTextAlignment(RoundedCornersBackgroundSpan.ALIGN_CENTER)
.build()
testTv.setText(span)
val span2 = RoundedCornersBackgroundSpan.Builder(this)
.addTextPart("Test ",0x990000CC.toInt())
.setCornersRadius(radius)
.setTextPadding(padding)
.setTextAlignment(RoundedCornersBackgroundSpan.ALIGN_CENTER)
.build()
test2Tv.setText(span2)
val span3 = RoundedCornersBackgroundSpan.Builder(this)
.addTextPart("Test Test Test",0x990000CC.toInt())
.setCornersRadius(radius)
.setTextPadding(padding)
.setTextAlignment(RoundedCornersBackgroundSpan.ALIGN_CENTER)
.build()
test3Tv.setText(span3)
}
fun convertDpToPixel(dp: Float, context: Context): Float {
val resources = context.resources
val metrics = resources.displayMetrics
return dp * (metrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.lucaspinazzola.testbug.MainActivity">
<TextView
android:id="@+id/testTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="10dp"
android:padding="4dp"
android:shadowColor="#00000001"
android:shadowDx="0"
android:shadowDy="0"
android:shadowRadius="16"
android:textSize="80sp"
android:textStyle="bold"
android:typeface="sans"
app:layout_constraintBottom_toTopOf="@+id/test2Tv"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/test2Tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="10dp"
android:padding="4dp"
android:shadowColor="#00000001"
android:shadowDx="0"
android:shadowDy="0"
android:shadowRadius="16"
android:textSize="80sp"
android:textStyle="bold"
android:typeface="sans"
app:layout_constraintBottom_toTopOf="@+id/test3Tv"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/testTv" />
<TextView
android:id="@+id/test3Tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:lineSpacingExtra="10dp"
android:padding="4dp"
android:shadowColor="#00000001"
android:shadowDx="0"
android:shadowDy="0"
android:shadowRadius="16"
android:textSize="80sp"
android:textStyle="bold"
android:typeface="sans"
app:layout_constraintTop_toBottomOf="@+id/test2Tv"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
Hi,
In drawBackground the variables start and startInText will always have the same value.
Because line 94 you assign the start + trimmedLengthStart to the variable start.
So when you measure with p.measureText(text, start, startInText) the returned value is wrong
I managed to fix the issue by assigning line 94 to a new variable like "actualStart"
I'm using max and min so when I assign the left value, I will avoid having negative value. If you don't do this, you won't have the rounded corner on the left.
#3
I also added the fix in this code
This is my code
int actualStart = start;
int actualEnd = end;
if (trimmedLength != part.length()) {
final int trimmedLengthStart = getTrimmedLengthStart(part);
final int trimmedLengthEnd = getTrimmedLengthEnd(part, trimmedLengthStart);
actualStart = start + trimmedLengthStart;
actualEnd = end - trimmedLengthEnd;
}
final int startInText = actualStart < backgroundHolder.mStart ? backgroundHolder.mStart : actualStart;
final int endInText = actualEnd > backgroundHolder.mEnd ? backgroundHolder.mEnd : actualEnd;
// skip empty parts
if (endInText <= startInText) {
continue;
}
float l = Math.max(p.measureText(text, start, startInText) - mPadding, 0); // Left
float t = Math.max(top - mPadding, 0); // Top
float r = Math.min(l + p.measureText(text, startInText, endInText) + mPadding, right); // right
float b = Math.min(baseline + p.descent() + mPadding, bottom); // bottom
mRectangle.set(l, t, r, b);
mPaint.setColor(backgroundHolder.mBgColor);
c.drawRoundRect(mRectangle, mRadius, mRadius, mPaint);
java.lang.IndexOutOfBoundsException
at android.graphics.Paint.measureText(Paint.java:1780)
at com.github.iojjj.rcbs.RoundedCornersBackgroundSpan.drawBackground(RoundedCornersBackgroundSpan.java:104)
setSpacingSize not found in code
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.