Removing the bottom Padding from a TextView while using HTML Format - android

I try set my html text on TextView like this
my_text.setText(HtmlCompat.fromHtml("<p>This is the awesome place to gain</p><p><strong>awesomeness </strong>and <em>deliciuosness. </em>very<em> </em><u>nice</u></p>", HtmlCompat.FROM_HTML_SEPARATOR_LINE_BREAK_PARAGRAPH))
I try set the TextView with a border, And I got padding bottom like this.
How to remove that? Because My TextView doesn't set anything
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/my_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/border_black_fill_white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>

In kotlin it's just using trim() method:
val stringHtml = "<p>This is the awesome place to gain</p><p><strong>awesomeness </strong>and <em>deliciuosness. </em>very<em> </em><u>nice</u></p>"
val spannedHtml = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(stringHtml, Html.FROM_HTML_MODE_COMPACT)
} else {
Html.fromHtml(stringHtml)
}
my_text.text = spannedHtml.trim()

This extra space that you see is infact line break followed by another line break.
When you dive into the Html.fromHtml(...) implementation which is used internally by HtmlCompat.fromHtml, you'll come across the following method that handles paragraph tags:
private static void handleP(SpannableStringBuilder text) {
int len = text.length();
if (len >= 1 && text.charAt(len - 1) == '\n') {
if (len >= 2 && text.charAt(len - 2) == '\n') {
return;
}
text.append("\n");
return;
}
if (len != 0) {
text.append("\n\n");
}
}
So to handle this just trim the string so space added at the end gets removed.
String html = "<p>This is the awesome place to gain</p><p><strong>awesomeness </strong>and <em>deliciuosness. </em>very<em> </em><u>nice</u></p>"
CharSequence trimmedString = trim(Html.fromHtml(html));
myText.setText(trimmedString);
public static CharSequence trim(CharSequence s) {
int start = 0;
int end = s.length();
while (start < end && Character.isWhitespace(s.charAt(start))) {
start++;
}
while (end > start && Character.isWhitespace(s.charAt(end - 1))) {
end--;
}
return s.subSequence(start, end);
}
This will give you the desired result.

As far as I can see, all existing answers turn the Spanned into a regular string, which removes the additional information in the Spanned. This Kotlin code is preserving the Spanned structure (including links):
fun Spanned.trim() {
if (this is SpannableStringBuilder) {
while (length > 0 && this[length-1].isWhitespace()) {
delete(length-1, length)
}
while (length > 0 && this[0].isWhitespace()) {
delete(0, 1)
}
}
}
Use it like this:
val html = HtmlCompat.fromHtml(rawContent, HtmlCompat.FROM_HTML_MODE_LEGACY)
html.trim()

Check once if you have given any bottom padding to TextView in the html file which is set as a background .
Try below code as well..
String strHtml = "<br>This is the awesome place to gain</br><br><strong>awesomeness </strong>and <em>deliciuosness. </em>very<em> </em><u>nice</u></br>";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
my_text.setText(Html.fromHtml(strHtml, Html.FROM_HTML_MODE_COMPACT));
} else {
my_text.setText(Html.fromHtml(strHtml));
}

Related

How to change First letter of each word to Uppercase in Textview xml

i need to change the text="font roboto regular" to Font Roboto Regular in xml itself, how to do?
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="18sp"
android:textColor="#android:color/black"
android:fontFamily="roboto-regular"
android:text="font roboto regular"
android:inputType="textCapWords"
android:capitalize="words"/>
If someone looking for kotlin way of doing this, then code becomes very simple and beautiful.
yourTextView.text = yourText.split(' ').joinToString(" ") { it.capitalize() }
You can use this code.
String str = "font roboto regular";
String[] strArray = str.split(" ");
StringBuilder builder = new StringBuilder();
for (String s : strArray) {
String cap = s.substring(0, 1).toUpperCase() + s.substring(1);
builder.append(cap + " ");
}
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(builder.toString());
Try this...
Method that convert first letter of each word in a string into an uppercase letter.
private String capitalize(String capString){
StringBuffer capBuffer = new StringBuffer();
Matcher capMatcher = Pattern.compile("([a-z])([a-z]*)", Pattern.CASE_INSENSITIVE).matcher(capString);
while (capMatcher.find()){
capMatcher.appendReplacement(capBuffer, capMatcher.group(1).toUpperCase() + capMatcher.group(2).toLowerCase());
}
return capMatcher.appendTail(capBuffer).toString();
}
Usage:
String chars = capitalize("hello dream world");
//textView.setText(chars);
System.out.println("Output: "+chars);
Result:
Output: Hello Dream World
KOTLIN
val strArrayOBJ = "Your String".split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val builder = StringBuilder()
for (s in strArrayOBJ) {
val cap = s.substring(0, 1).toUpperCase() + s.substring(1)
builder.append("$cap ")
}
txt_OBJ.text=builder.toString()
Modification on the accepted answer to clean out any existing capital letters and prevent the trailing space that the accepted answer leaves behind.
public static String capitalize(#NonNull String input) {
String[] words = input.toLowerCase().split(" ");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < words.length; i++) {
String word = words[i];
if (i > 0 && word.length() > 0) {
builder.append(" ");
}
String cap = word.substring(0, 1).toUpperCase() + word.substring(1);
builder.append(cap);
}
return builder.toString();
}
you can use this method to do it programmatically
public String wordFirstCap(String str)
{
String[] words = str.trim().split(" ");
StringBuilder ret = new StringBuilder();
for(int i = 0; i < words.length; i++)
{
if(words[i].trim().length() > 0)
{
Log.e("words[i].trim",""+words[i].trim().charAt(0));
ret.append(Character.toUpperCase(words[i].trim().charAt(0)));
ret.append(words[i].trim().substring(1));
if(i < words.length - 1) {
ret.append(' ');
}
}
}
return ret.toString();
}
refer this if you want to do it in xml.
You can use
private String capitalize(final String line) {
return Character.toUpperCase(line.charAt(0)) + line.substring(1);
}
refer this How to capitalize the first character of each word in a string
android:capitalize is deprecated.
Follow these steps: https://stackoverflow.com/a/31699306/4409113
Tap icon of ‘Settings’ on the Home screen of your Android Lollipop
Device
At the ‘Settings’ screen, scroll down to the PERSONAL section and
tap the ‘Language & input’ section.
At the ‘Language & input’ section, select your keyboard(which is
marked as current keyboard).
Now tap the ‘Preferences’.
Tap to check the ‘Auto – Capitalization’ to enable it.
And then it should work.
If it didn't, i'd rather to do that in Java.
https://stackoverflow.com/a/1149869/2725203
Have a look at ACL WordUtils.
WordUtils.capitalize("your string") == "Your String"
Another approach is to use StringTokenizer class. The below method works for any number of words in a sentence or in the EditText view. I used this to capitalize the full names field in an app.
public String capWordFirstLetter(String fullname)
{
String fname = "";
String s2;
StringTokenizer tokenizer = new StringTokenizer(fullname);
while (tokenizer.hasMoreTokens())
{
s2 = tokenizer.nextToken().toLowerCase();
if (fname.length() == 0)
fname += s2.substring(0, 1).toUpperCase() + s2.substring(1);
else
fname += " "+s2.substring(0, 1).toUpperCase() + s2.substring(1);
}
return fname;
}
in kotlin, string extension
fun String?.capitalizeText() = (this?.toLowerCase(Locale.getDefault())?.split(" ")?.joinToString(" ") { if (it.length <= 1) it else it.capitalize(Locale.getDefault()) }?.trimEnd())?.trim()
Kotlin extension function for capitalising each word
val String?.capitalizeEachWord
get() = (this?.lowercase(Locale.getDefault())?.split(" ")?.joinToString(" ") {
if (it.length <= 1) it else it.replaceFirstChar { firstChar ->
if (firstChar.isLowerCase()) firstChar.titlecase(
Locale.getDefault()
) else firstChar.toString()
}
}?.trimEnd())?.trim()
As the best way for achieving this used to be the capitalize() fun, but now it got depricated in kotlin. So we have an alternate for this. I've the use case where I'm getting a key from api that'll be customized at front end & will be shown apparently. The value is coming as "RECOMMENDED_OFFERS" which should be updated to be shown as "Recommended Offers".
I've created an extension function :
fun String.updateCapitalizedTextByRemovingUnderscore(specialChar: String): String
that takes a string which need to be replaced with white space (" ") & then customise the words as their 1st character would be in caps. So, the function body looks like :
fun String.updateCapitalizedTextByRemovingUnderscore(
specialChar: String = "") : String {
var tabName = this
// removing the special character coming in parameter & if
exist
if (spclChar.isNotEmpty() && this.contains(specialChar)) {
tabName = this.replace(spclChar, " ")
}
return tabName.lowercase().split(' ').joinToString(" ") {
it.replaceFirstChar { if (it.isLowerCase())
it.titlecase(Locale.getDefault()) else it.toString() } }
}
How to call the extension function :
textView.text =
"RECOMMENDED_OFFERS".updateCapitalizedTextByRemovingUnderscore("_")
OR
textView.text = <api_key>.updateCapitalizedTextByRemovingUnderscore("_")
The desired output will be :
Recommended Offers
Hope this will help.Happy coding :) Cheers!!
capitalize each word
public static String toTitleCase(String string) {
// Check if String is null
if (string == null) {
return null;
}
boolean whiteSpace = true;
StringBuilder builder = new StringBuilder(string); // String builder to store string
final int builderLength = builder.length();
// Loop through builder
for (int i = 0; i < builderLength; ++i) {
char c = builder.charAt(i); // Get character at builders position
if (whiteSpace) {
// Check if character is not white space
if (!Character.isWhitespace(c)) {
// Convert to title case and leave whitespace mode.
builder.setCharAt(i, Character.toTitleCase(c));
whiteSpace = false;
}
} else if (Character.isWhitespace(c)) {
whiteSpace = true; // Set character is white space
} else {
builder.setCharAt(i, Character.toLowerCase(c)); // Set character to lowercase
}
}
return builder.toString(); // Return builders text
}
use String to txt.setText(toTitleCase(stringVal))
don't use android:fontFamily to roboto-regular. hyphen not accept. please rename to roboto_regular.
To capitalize each word in a sentence use the below attribute in xml of that paticular textView.
android:inputType="textCapWords"

Pop up Arabic/Urdu custom keyboard on Edittext Issue

I am working on app where i use Urdu Custom Keyboard its work fine but the problem is that when i type any-word e.g. (سلام), cursor become not works at mid character for example cut/copy/paste or deleting (ا) character from the mid from word are not work.
i uses rough technique just appending characters but is also work fine.
For taping any alphabetic
private void addText(View v) {
// String b = "";
// b = (String) v.getTag();
// urdu_word.setText(b);
if (isEdit == true) {
String b = "";
b = (String) v.getTag();
if (b != null) {
Log.i("buttonsOnclick", b);
// adding text in Edittext
mEt.append(b);
}
}
}
For back button tapping
private void isBack(View v) {
if (isEdit == true) {
CharSequence cc = mEt.getText();
if (cc != null && cc.length() > 0) {
{
mEt.setText("");
mEt.append(cc.subSequence(0, cc.length() - 1));
}
}
}
}
Here the screenshot clear my problem to you people
I used a lot of library and code from github but don't catch good idea
1) Keyboard-1
2) Keyboard-2
3) Keyboard-3
4) Keyboard-4
i checked all these keyboard and more from libs, have same cursor issue, how to manage fully my custom keyboard by deleting character from mid and copy my written text copy paste like normal keyboard with EditText, thanks in advance all of you :)
Thanks God i solved my issue using simple logic.
For back button
private void isBack(View v) {
// char[] tempChar = null;
if ((mEt.getText().toString().length() > 0)) {
int temp = mEt.getSelectionEnd() - 1;
if (temp >= 0) {
mEt.setText((mEt.getText().toString()
.substring(0, mEt.getSelectionEnd() - 1).concat(mEt
.getText()
.toString()
.substring(mEt.getSelectionEnd(),
mEt.getText().length()))));
mEt.setSelection(temp);
}
}
}
For adding any character
private void addText(View v) {
int temp = mEt.getSelectionEnd();
if (temp >= 0) {
String b = "";
b = (String) v.getTag();
mEt.setText((mEt.getText().toString()
.substring(0, mEt.getSelectionEnd()) + b.concat(mEt
.getText().toString()
.substring(mEt.getSelectionEnd(), mEt.getText().length()))));
mEt.setSelection(temp + 1);
}
}
for copy paste i added few lines code to EditText
<EditText
android:id="#+id/xEt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="#drawable/edittextshape"
android:ems="10"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="top"
android:imeOptions="actionDone"
android:padding="15dp"
android:singleLine="false"
android:visibility="visible" />

Android : Remove last paragraph tag generated by Html.toHtml

I'm editing content that may be html in an EditText. Just before saving the result, I use Html.toHtml to convert the input into a string to be sent to the server. However this method call seems to be generating paragraph tags which I dont need. Eg -
Test edited
seems to get converted to
<p dir="ltr">Test edited</p>
I would like to strip out the last paragraph tag before saving the content. If there are other paragraph tags, I would like to keep those. I have this regex that matches all p tags
"(<p.*>)(.*)(</p>)";
but I'm not sure how to match just the last paragraph and remove just the tags for it.
public static void handleOneParagraph(SpannableStringBuilder text) {
int start = 0;
int end = text.length();
String chars1 = "<p";
if (end < 2)
return;
while (start < end ) {
String seq = text.toString().substring(start, start + 2);
if (seq.equalsIgnoreCase(chars1))
break;
start++;
}
if (text.toString().substring(start, start + 2).equalsIgnoreCase(chars1) ) {
int start2 = start + 1;
String chars2 = ">";
while (start2 < end && !text.subSequence(start2, start2+1).toString().equalsIgnoreCase(chars2) ) {
start2++;
}
if (start2 >= end)
return;
text.replace(start, start2+1, "");
end = text.length();
start = end;
String chars3 = "</p>";
while (start > start2 + 4) {
String last_p = text.subSequence(start - 4, start).toString();
if (last_p.equalsIgnoreCase(chars3) ) {
text.replace(start - 4, start, "");
break;
}
start--;
}
}
}
And now, you can use it like this...
SpannableStringBuilder cleaned_text = new SpannableStringBuilder(Html.toHtml(your_text));
handleOneParagraph(cleaned_text);

Android: Is there a method equivalent to XML android:digits?

In my layout xml, I use the following to define an EditText that can display currency.
<EditText
android:id="#+id/et1"
android:layout_width="210dp"
android:layout_height="wrap_content"
android:imeOptions= "actionNext"
android:inputType="phone"
android:digits="0123456789.,$" >
However, this is not localized. I want to be able to use the symbol returned by NumberFormat.getCurrencyInstance().getCurrency().getSymbol(); in place of the $ in android:digits.
What I don't know is how to set android:digits from within my program.
Solved thanks to Agarwal. I just need to read the documentation more thoroughly.
Try this:
<EditText
android:inputType="number"
android:digits="0123456789."
/>
From Code:
weightInput.setKeyListener(DigitsKeyListener.getInstance("0123456789."));
But, it allows the user to include several "."
You can also do this for accepting on digits...
EditText input = new EditText(this);
input.setInputType(InputType.TYPE_CLASS_NUMBER);
Yes you can check here
http://developer.android.com/reference/android/widget/EditText.html
for almost every attribute there is equivalent method present.
setKeyListener(KeyListener)
For those interested, here is how I solved the original question. It is the complete implementation of a currency edit text that can handle multiple locales. Still may be some problems (Doesn't seem to display Japanese currency symbol correctly, and I can't get the keyboard I want (12_KEY)), but otherwise, some may find this helpful.
public class CurrencytestActivity extends Activity
{
private static final Integer MAX_VALUE_DIGITS = 9;
EditText et1;
NumberFormat mCurrencyFormatter;
CurrencyTextWatcher tw;
#Override public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Get info about local currency
mCurrencyFormatter = NumberFormat.getCurrencyInstance();
int fractionDigits = mCurrencyFormatter.getCurrency().getDefaultFractionDigits();
et1 = (EditText)findViewById(R.id.et1); // Get a handle to the TextEdit control
// Add local currency symbol to digits allowed for EditText display and use
// DigitsKeyListener to tell the control. Unfortunately, this also resets the inputType
// that is specified in the XML layout file. Don't know how to fix that yet.
// Also, this doesn't seem to work for Japanese (probably due to UNICODE or something).
// The symbol gets added to displayCharacters, but the EditText doesn't use it.
String displayCharacters = "0123456789.," + mCurrencyFormatter.getCurrency().getSymbol();
et1.setKeyListener(DigitsKeyListener.getInstance( displayCharacters ));
// Add a text watcher to the EditText to manage currency digit entry. The TextWatcher
// won't allow the symbol or decimal or comma to be entered by the user, but they are
// still displayed when the result is formatted in afterTextChanged().
tw = new CurrencyTextWatcher( MAX_VALUE_DIGITS, fractionDigits );
et1.addTextChangedListener( tw );
et1.setCursorVisible( false );
((Button)findViewById(R.id.button1)).setOnClickListener(onButtonClick);
}
public class CurrencyTextWatcher implements TextWatcher
{
boolean mEditing; // Used to prevent recursion
Double mAmount;
int mDigitCount, mMaxDigits, mFractionDivisor;
public CurrencyTextWatcher( int maxDigits, int fractionDigits )
{
mEditing = false;
mFractionDivisor = (fractionDigits == 0) ? 1 : ((fractionDigits == 1) ? 10 : 100);
mAmount = 0.0;
mDigitCount = 0;
mMaxDigits = maxDigits;
}
public synchronized void afterTextChanged(Editable s)
{
// Don't update EditText display if we are editing
if ( !mEditing )
{
// Under cover of mEditing, update the EditText display with
// the newly formatted value
mEditing = true;
s.replace( 0, s.length(), mCurrencyFormatter.format( mAmount ));
mEditing = false;
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
public double GetAmount() { return( mAmount ); }
public void onTextChanged(CharSequence s, int start, int before, int count)
{
if ( !mEditing )
{
// Added a digit to the value
if (( count == 1 ) && ( mDigitCount < mMaxDigits ))
{
// Obtain the added character
CharSequence x = s.subSequence( start, start + count );
// Ignore any characters other than number digits for addition to value
if (( x.charAt( 0 ) >= '0') && ( x.charAt( 0 ) <= '9'))
{
// Multiply by ten to shift existing digits to the left and
// add in the new digit as the decimal place appropriate to this currency
mAmount = (mAmount * 10) + (Double.parseDouble( x.toString() ) / mFractionDivisor);
mDigitCount += 1;
}
}
// Delete last digit from the value
else if (( count == 0 ) && ( mDigitCount > 0))
{
// Subtract the amount of the last digit and divide by ten to
// effectively delete the last character entered
mAmount -= (mAmount % (0.001 * mFractionDivisor) );
mAmount /= 10;
mDigitCount -= 1;
}
}
}
}
private View.OnClickListener onButtonClick = new View.OnClickListener()
{
#Override public void onClick(View v)
{
if (v.getId() == R.id.button1 )
{
// Get the value from the textwatcher and display it.
double mAmountTest = tw.GetAmount();
((TextView)findViewById(R.id.tv1)).setText(mCurrencyFormatter.format( mAmountTest ));
}
}
};
}
And the accompanying XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center|top"
android:orientation="vertical" >
<EditText
android:id="#+id/et1"
android:layout_width="210dp"
android:layout_height="wrap_content"
android:imeOptions= "actionNext"
android:inputType="phone" >
<requestFocus />
</EditText>
<TextView
android:id="#+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Extract from TextWatcher" />
</LinearLayout>

How to delete the old lines of a TextView

I'm developping an app which constantly needs to show the results to the user in a TextView like some sort of log.
The app works nicely and it shows the results in the TextView but as long as it keeps running and adding lines the app gets slower and crashes because of the character length of the TextView.
I would like to know if the android API provides any way to force a TexView to automatically delete the oldest lines that were introduced in order to make room for the new ones.
I had the same problem. I just resolved it.
The trick is to use the getEditableText() method of TextView. It has a replace() method, even a delete() one. As you append lines in it, the TextView is already marked as "editable", which is needed to use getEditableText(). I have something like that:
private final static int MAX_LINE = 50;
private TextView _debugTextView; // Of course, must be filled with your TextView
public void writeTerminal(String data) {
_debugTextView.append(data);
// Erase excessive lines
int excessLineNumber = _debugTextView.getLineCount() - MAX_LINE;
if (excessLineNumber > 0) {
int eolIndex = -1;
CharSequence charSequence = _debugTextView.getText();
for(int i=0; i<excessLineNumber; i++) {
do {
eolIndex++;
} while(eolIndex < charSequence.length() && charSequence.charAt(eolIndex) != '\n');
}
if (eolIndex < charSequence.length()) {
_debugTextView.getEditableText().delete(0, eolIndex+1);
}
else {
_debugTextView.setText("");
}
}
}
The thing is, TextView.getLineCount() returns the number of wrapped lines, and not the number of "\n" in the text... It is why I clear the whole text if I reach the end of the text while seeking the lines to delete.
You can do that differently by erasing a number of characters instead of erasing a number of lines.
This solution keeps track of the log lines in a list and overwrites the textview with the contents of the list on each change.
private List<String> errorLog = new ArrayList<String>();
private static final int MAX_ERROR_LINES = 70;
private TextView logTextView;
public void addToLog(String str) {
if (str.length() > 0) {
errorLog.add( str) ;
}
// remove the first line if log is too large
if (errorLog.size() >= MAX_ERROR_LINES) {
errorLog.remove(0);
}
updateLog();
}
private void updateLog() {
String log = "";
for (String str : errorLog) {
log += str + "\n";
}
logTextView.setText(log);
}
Here is an example that adds lines to an output log limited by the set max lines. The scrollview will auto scroll to the bottom after every line is added. This example work purely with the contents of the TextView so it doesn't have the need for a separate data collection.
Add the following to your activity xml:
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" >
<TextView
android:id="#+id/textViewOutput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1000" />
</ScrollView>
In your activity add the following code:
private static final int MAX_OUTPUT_LINES = 50;
private static final boolean AUTO_SCROLL_BOTTOM = true;
private TextView _textViewOutput;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_textViewOutput = (TextView) findViewById(R.id.textViewOutput);
}
//call to add line(s) to TextView
//This should work if either lineText contains multiple
//linefeeds or none at all
private void addLinesToTextView(String lineText) {
_textViewOutput.append(lineText);
removeLinesFromTextView();
if(AUTO_SCROLL_BOTTOM)
_scrollView.post(new Runnable() {
#Override
public void run() {
_scrollView.fullScroll(ScrollView.FOCUS_DOWN);
}
});
}
// remove leading lines from beginning of the output view
private void removeLinesFromTextView() {
int linesToRemove = _textViewOutput.getLineCount() - MAX_OUTPUT_LINES;
if (linesToRemove > 0) {
for (int i = 0; i < linesToRemove; i++) {
Editable text = _textViewOutput.getEditableText();
int lineStart = _textViewOutput.getLayout().getLineStart(0);
int lineEnd = _textViewOutput.getLayout().getLineEnd(0);
text.delete(lineStart, lineEnd);
}
}
}
The TextView shows what you set via setText() method. So this sounds to me like you should cut down the input you provide.
To empty the TextView, you can do setText("");
Kotlin answer of Vincent Hiribarren
fun write_terminal_with_limit(data: String?, limit:Int)
{
log_textView.append(data)
val nb_line_to_del: Int = log_textView.lineCount - limit
// Erase excessive lines
if (nb_line_to_del > 0)
{
var end_of_line_idx = -1
val char_seq: CharSequence = log_textView.text
for (i in 0 until nb_line_to_del)
{
do
{
end_of_line_idx++
}
while (end_of_line_idx < char_seq.length && char_seq[end_of_line_idx] != '\n')
}
if (end_of_line_idx < char_seq.length)
{
log_textView.editableText.delete(0, end_of_line_idx + 1)
}
else
{
log_textView.text = ""
}
}
}
I made personnal adjustment...
I think you are using TextView.append(string) then it will add to old text.
If you are setting using setText it will replace the old text
This is an old one, but I just found looking for a solution to my own problem.
I was able to remove all TextViews from a LinearLayout using nameoflayout.removeAllViews();
There is another method that will allow you to remove views from specified places in the layout using ints, it's: nameoflayout.removeViews(start, count); so I'm sure you could create a time out for how long textviews remain visible.
No, android API doesn't provide any functionally that delete oldest lines from textview automatically till API level 25. you need to do it logically.
Try to write a function that takes an old string on TextView and add new string to it, then get substring last strings that TextView capable. And set it to TextView. Something like this:
String str = textview.getText();
str += newstring;
int ln = str.length();
ln = ln-250;
if (ln<0) ln=0;
str = str.substring(ln);
textview.setText(str);
reference Vincent Hiribarren answer.
make it simple-->
TextView _debugTextView;
//if excess 20 lines keep new 200 chars
if(_debugTextView.getLineCount() >20) _debugTextView.getEditableText().delete(0,_debugTextView.getText().length()-200);

Categories

Resources