I'm looking for the best way to meet this requirement. I apologize if it's been answered elsewhere, I can't find a solution to what seems like an easy problem.
You have a line of text in a list that looks something like this:
Title of the item - (5 items)
If the title of the item gets to be too long, then it wraps, which is expected. However, it shouldn't wrap between the "5" and the "items". If it needs to wrap, then the whole "(5 items)" should wrap to the next line. And the text of the title should ellipse.
I can't seem to find a way to create a layout that will work for this.
This may help. You can define which part of the text is going to be truncated by using the android:ellipsize attribute.
In your case, as per the linked answer, I would use android:ellipsize="middle" or android:ellipsize="marquee", which makes the text slide to be read.
While this does not actually answers your requirements (number of items automatically going to line two) I think it might be a better solution.
See official info here.
The other thing that comes to my mind is using two different TextViews, one for title and another one (right-aligned?) for item counts. I would give android:ellipsize="end" to the first and android:layout_width="wrap_content" to the latter.
Also you could go for a count TextView below the title, that gets appended to the title if there's enough room.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/container"
android:orientation="vertical" >
<TextView android:id="@+id/text1"
android:text="a very very very long title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end" />
<TextView android:id="@+id/text2"
android:text="(5 items)"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
And in your code you can check for width:
View container = findViewById(R.id.container);
TextView tv1 = (TextView) findViewById(R.id.text1);
TextView tv2 = (TextView) findViewById(R.id.text2);
String HEADER = tv1.getText();
String COUNT = tv2.getText();
int widthHeader = tv1.getWidth();
int widthCount = tv1.getWidth();
int widthAvailable = container.getWidth();
if (widthAvailable - widthHeader > widthCount) {
tv1.setText(HEADER + " - " + COUNT);
tv2.setText("");
}
The TextUtils classs has as method called ellipsize
public static CharSequence ellipsize (CharSequence text, TextPaint p, float avail, TextUtils.TruncateAt where) Added in API level 1
Returns the original text if it fits in the specified width given the properties of the specified Paint, or, if it does not fit, a truncated copy with ellipsis character added at the specified edge or center.
Here is how we can use it. Lets assume "Title of the item - (5 items)" is fullText, (5 items) is suffix, textView is your text view containing the text.
String ellipsizedText = TextUtils.ellipsize(fullText, textView.getPaint(), fullTexViewtWidth ,TextUtils.TruncateAt.END);
Now either the text will be ellipsized or it won't. We can check this by checking for the presence of suffix in the ellipsizedText. If it is ellipsized (suffix is removed), we should call the ellipsize function again but this time with reduced width since we want to preserve a space for our suffix string and remove suffix since we are adding it separately. So, the new call will be
ellipsizedText = TextUtils.ellipsize(removedSuffixText, textView.getPaint(), reducedWidth ,TextUtils.TruncateAt.END);
finally we set the text of the textView as ellipsizedText+suffix;
Few values we need to find out
reducedWidth - This is even more tricky. To calculate this we need to find the width occupied by suffix and subtract it from fullTexViewtWidth. This answer explains how to find width occupied by suffix
final float densityMultiplier = getContext().getResources().getDisplayMetrics().density;
final float scaledPx = 20 * densityMultiplier;
paint.setTextSize(scaledPx);
final float size = paint.measureText("sample text");
I am afraid this will only work when maxLines is 1 and width is set to matchparent for textView.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With