Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 972
Jimix Avatar asked Feb 22 '11 12:02

Jimix


2 Answers

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.

like image 140
Vincent Hiribarren Avatar answered Sep 20 '22 08:09

Vincent Hiribarren


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);
}
like image 23
zora Avatar answered Sep 19 '22 08:09

zora