Adding '...' at end of a string in android in TextViews [duplicate] - android

This question already has answers here:
Android: TextView automatically truncate and replace last 3 char of String
(4 answers)
Closed 8 years ago.
Following is my textview in android layout and I want that after a certain width of text, it adds '...' at the end of string. I don't want to do it in java while setting the text but want this to be handled by this textview itself. Is it possible?
<TextView
android:id="#+id/list_contact_name"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/list_contact_icon"
android:paddingLeft="10dp"
android:paddingBottom="10dp"
android:textColor="#222"
android:text="Sandeep Choudhary Mahabali"
android:textSize="18sp" />

add these attributes to your textview :
android:maxLines="1"
android:ellipsize="end"

Add these attributes to your TextView to restrict your TextView's text in one line and to add 3 dots ... at the end of line.
android:singleLine="true"
android:ellipsize="end"

Extend the TextView class, override setText and trim and add your "..." there. If desired, add an attribute that defines how long the text should be before being trimmed, then you can set each TrimmedTextView length in xml as well.
public class TrimmedTextView extends TextView {
#Override
public void setText(CharSequence text, BufferType type) {
int maxLength = 10;
String value = text.toString();
if (text.length() > maxLength) {
value = text.subSequence(0, maxLength) + "...";
}
super.setText(value, type);
}
}

Related

how to allow only specific number in edittext?

am trying to put only a specific value in my edit text.
I have used this this my layout.
android:digits="0123468"
however, i also do not want that number 1 and 3 should work in my edit text.
Sample; enter 32... it gives me a list of items
but enter 3 should not allow me to do something.
Can someone help me on this?
This could be an aproach:
<EditText
android:id="#+id/edtNumber"
android:digits="0123456789"
android:inputType="number" />
And if you want to discard '1' and '3' you could get input number like this:
Integer.parseInt(edtNumber.getText().toString())
and compare it with values you don't want.
Also if for some reason you want to use decimals do this:
<EditText
android:id="#+id/edtNumberDecimal"
android:digits="0123456789."
android:inputType="numberDecimal" />
Use regular expressions.
#Override
public void afterTextChanged(Editable s) {
String text = s.toString();
int length = text.length();
Pattern pattern
= Pattern.compile("(?s)\\d|[024-9]{2,}");
if(length > 0 && !Pattern.matches(pattern, text)) {
s.delete(length - 1, length);
}
}

How to keep a text field empty in Android?

I am new to android development , i am trying to develop an app where user can keep a few text field empty,
However when user doesn't provide any input in the text field app crashes.
How do we handle empty text field in android
Following is my code for text Field.
<EditText
android:layout_width="40dp"
android:layout_height="40dp"
android:inputType="number"
android:ems="10"
android:id="#+id/editText1"
android:layout_weight="1"
android:background="#ffb7ffbf"/>`
java code:
TextView t1 = (TextView)findViewById(R.id.editText1);
a1 = Integer.parseInt(t1.getText().toString());
you should cast EditText instead of TextView.
EditText t1 = (EditText)findViewById(R.id.editText1);
Ensure if the TextBox is not empty before parsing the value to the int as
if (e.length()>0) {
int a1= Integer.parseInt(e.getText().toString());
}
Else you can get a java.lang.NumberFormatException: for Invalid int: "";
Try this:
TextView t1=(TextView)findViewById(R.id.editText1);
String aux = t1.getText.toString();
if(aux.length() > 0)
a1= Integer.parseInt(aux);
else
// the text is empty
getText.toString will bring you something always so it can be and string size 0, wich is empty. that will make the parseInt() throw an error because it won find a number in the string.
So you have to ask if the length of the string > 0, before the parse.

Decimal Amount Format Issue-Android

Declaration :
DecimalFormat mAmtFormat = new DecimalFormat("##,##,##,##0.00");
edtAmounts = (EditText) findViewById(R.id.txtAmounts);
From xml File Edit text as
<EditText
android:id="#+id/txtAmounts"
android:layout_height="50dip"
android:layout_marginLeft="10dip"
android:background="#FFFFFF"
android:gravity="center_vertical"
android:inputType="numberDecimal"
android:singleLine="true"
android:textSize="18dip"
android:textStyle="bold"
android:width="170dip" />
From Back End mCurtotamt is 565656565(double)
Fetching Data From Sqlite DataBase:
edtAmounts.setText(String.valueOf(mAmtFormat.format(mDoubleformat
.parse(mCurtotamt).doubleValue())))
but the value set into the edit text as 56,56,57,000.00
what is happening over here.
When you get the value from the back end, do not get it as a String like this:
String mCurtotamt = cursor.getString(cursor.getColumnIndex("column_name"));
Instead, get it as a double directly, like this:
double mCurtotamt = cursor.getDouble(cursor.getColumnIndex("column_name"));
Then you don't need to parse it when you set the edit text, but can format it directly:
edtAmounts.setText(String.valueOf(mAmtFormat.format(mCurtoamt)));
The problem is being introduced when converting it to a String when you call cursor.getString().
Use this one for indian format like this "##,##,##0.00" :
static public String formatCurrency(Double doubleVal) {
return new DecimalFormat("##,##,##0.00").format(doubleVal);
}
This function return the value in correct given format. If you pass 5555555.00 value then function return 55,55,555.00 as a string.

Breaking a line without increasing text length

I'm able to break a line using following code:
String str1 = "TEST1"; // length = 5
String str2 = "TEST2"; // length = 5
TextView textView = (TextView)findViewById( R.id.text_view );
textView.setText(str1 + '\n' + str2);
But the final text length is equal to 11.
Question:
Is there any special character or method that will allow me to reach the same result inside my TextView without increasing text length?
What I'm trying to achieve:
I have a data format, which is stored in JSON. It looks like
[{type: line, params: {line params}}, {type: text, params: {text params}, ...]
There is always line at the start
Each paragraph begins with line ( so it acts like a line separator which is stored at the beginning of line, not at the end )
Size of each line equals to 1, i.e. each line counts as a single character
Each paragraph ends with text's last character ( not '\n' )
There are some line params ( like BulletList, Numeric list, Paragraph )
I need a strict mapping between my TextView and source data, i.e. for each cursor position in my TextView I need to count how many characters preceed it in source data.
Take two TextViews and add one below another .Then you won't find any length problem.
like : <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView1" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/textView1"
android:text="TextView2" />
</RelativeLayout>
String str1 = "TEST1";
String str2 = "TEST2";
TextView text=(TextView)vi.findViewById(R.id.text);
text.setText(str1);
text.append(Html.fromHtml(< br>));
text.append(str2);
Hope it works :)
For your question my answer will be no. But you could make your own TextView and change how it calculates the length of the text by for example ignoring "/n" when counting the length.
Well there is tricky way
String str1 = "TEST1"; // length = 5
String str2 = "TEST2"; // length = 5
textView = (TextView)findViewById( R.id.textView1 );
textView.setWidth(120);
textView.setTextSize(20);
textView.setText(str1 + str2);
//textView.getText().toString().length() length = 10
in XMl
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="TextView" />

How to make part of the text Bold in android at runtime?

A ListView in my application has many string elements like name, experience, date of joining, etc. I just want to make name bold. All the string elements will be in a single TextView.
my XML:
<ImageView
android:id="#+id/logo"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="15dp" >
</ImageView>
<TextView
android:id="#+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/logo"
android:padding="5dp"
android:textSize="12dp" >
</TextView>
My code to set the TextView of the ListView item:
holder.text.setText(name + "\n" + expirience + " " + dateOfJoininf);
Let's say you have a TextView called etx. You would then use the following code:
final SpannableStringBuilder sb = new SpannableStringBuilder("HELLOO");
final StyleSpan bss = new StyleSpan(android.graphics.Typeface.BOLD); // Span to make text bold
final StyleSpan iss = new StyleSpan(android.graphics.Typeface.ITALIC); //Span to make text italic
sb.setSpan(bss, 0, 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make first 4 characters Bold
sb.setSpan(iss, 4, 6, Spannable.SPAN_INCLUSIVE_INCLUSIVE); // make last 2 characters Italic
etx.setText(sb);
Based on Imran Rana's answer, here is a generic, reusable method if you need to apply StyleSpans to several TextViews, with support for multiple languages (where indices are variable):
void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style) {
SpannableStringBuilder sb = new SpannableStringBuilder(text);
int start = text.indexOf(spanText);
int end = start + spanText.length();
sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(sb);
}
Use it in an Activity like so:
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
StyleSpan boldStyle = new StyleSpan(Typeface.BOLD);
setTextWithSpan((TextView) findViewById(R.id.welcome_text),
getString(R.string.welcome_text),
getString(R.string.welcome_text_bold),
boldStyle);
// ...
}
strings.xml
<string name="welcome_text">Welcome to CompanyName</string>
<string name="welcome_text_bold">CompanyName</string>
Result:
Welcome to CompanyName
You can do it using Kotlin and buildSpannedString extension function from core-ktx
holder.textView.text = buildSpannedString {
bold { append("$name\n") }
append("$experience $dateOfJoining")
}
The answers provided here are correct, but can't be called in a loop because the StyleSpan object is a single contiguous span (not a style that can be applied to multiple spans). Calling setSpan multiple times with the same bold StyleSpan would create one bold span and just move it around in the parent span.
In my case (displaying search results), I needed to make all instances of all the search keywords appear bold. This is what I did:
private static SpannableStringBuilder emboldenKeywords(final String text,
final String[] searchKeywords) {
// searching in the lower case text to make sure we catch all cases
final String loweredMasterText = text.toLowerCase(Locale.ENGLISH);
final SpannableStringBuilder span = new SpannableStringBuilder(text);
// for each keyword
for (final String keyword : searchKeywords) {
// lower the keyword to catch both lower and upper case chars
final String loweredKeyword = keyword.toLowerCase(Locale.ENGLISH);
// start at the beginning of the master text
int offset = 0;
int start;
final int len = keyword.length(); // let's calculate this outside the 'while'
while ((start = loweredMasterText.indexOf(loweredKeyword, offset)) >= 0) {
// make it bold
span.setSpan(new StyleSpan(Typeface.BOLD), start, start+len, SPAN_INCLUSIVE_INCLUSIVE);
// move your offset pointer
offset = start + len;
}
}
// put it in your TextView and smoke it!
return span;
}
Keep in mind that the code above isn't smart enough to skip double-bolding if one keyword is a substring of the other. For example, if you search for "Fish fi" inside "Fishes in the fisty Sea" it will make the "fish" bold once and then the "fi" portion. The good thing is that while inefficient and a bit undesirable, it won't have a visual drawback as your displayed result will still look like
Fishes in the fisty Sea
if you don't know exactly the length of the text before the text portion that you want to make Bold, or even you don't know the length of the text to be Bold, you can easily use HTML tags like the following:
yourTextView.setText(Html.fromHtml("text before " + "<font><b>" + "text to be Bold" + "</b></font>" + " text after"));
<string name="My_Name">Given name is <b>Not Right</b>Please try again </string>
use "b" tag in string.xml file.
also for Italic "i" and Underline "u".
Extending frieder's answer to support case and diacritics insensitivity.
public static String stripDiacritics(String s) {
s = Normalizer.normalize(s, Normalizer.Form.NFD);
s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", "");
return s;
}
public static void setTextWithSpan(TextView textView, String text, String spanText, StyleSpan style, boolean caseDiacriticsInsensitive) {
SpannableStringBuilder sb = new SpannableStringBuilder(text);
int start;
if (caseDiacriticsInsensitive) {
start = stripDiacritics(text).toLowerCase(Locale.US).indexOf(stripDiacritics(spanText).toLowerCase(Locale.US));
} else {
start = text.indexOf(spanText);
}
int end = start + spanText.length();
if (start > -1)
sb.setSpan(style, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(sb);
}
If you are using the # srings / your_string annotation, access the strings.xml file and use the <b></b> tag in the part of the text you want.
Example:
<string><b>Bold Text</b><i>italic</i>Normal Text</string>
I recommend to use strings.xml file with CDATA
<string name="mystring"><![CDATA[ <b>Hello</b> <i>World</i> ]]></string>
Then in the java file :
TextView myTextView = (TextView) this.findViewById(R.id.myTextView);
myTextView.setText(Html.fromHtml( getResources().getString(R.string.mystring) ));
To better support translations and remove any dependency on length of the string or particular index, you should use android.text.Annotation in you string defined strings.xml.
In your particular case, you can create a string like below
<string name="bold_name_experience_text"><annotation type="bold">name</annotation> \nexpirience dateOfJoininf</string>
or if you want to substitute these in runtime, you can create a string as follow
<string name="bold_name_experience_text"><annotation type="bold">name</annotation> \n%d %s</string>
You must apply this bold_name_experience_text in your text view label. These annotation class spans get added to your string and then you can iterate on them to apply the bold span.
You can refer to my SO answer which shows the Kotlin code to iterate through these spans and apply the bold span
Remember all the above answers has one of the following flows:
They are using some hard-coded index logic which may crash or give wrong results in some other language
They are using hardcode string in Java code which will result in lots of complicated logic to maintain internalisation
Some used Html.fromHtml which can be acceptable answer depending on the use-case. As Html.fromHtml doesn't always work for all types of HTML attributes for example there is not support of click span. Also depending on OEM you might get different rendered TextView

Categories

Resources