Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does an Android EditText (TextView) draw the blinking cursor?

I'm making my own Mongolian vertical script TextView (and EditText) from scratch by extending View. I'm trying to understand how the blinking cursor is implemented in the Android TextView source code. It seems to be handled by an mEditor instance of the Editor class. In that class I found a drawCursor method:

private void drawCursor(Canvas canvas, int cursorOffsetVertical) {
    final boolean translate = cursorOffsetVertical != 0;
    if (translate) canvas.translate(0, cursorOffsetVertical);
    for (int i = 0; i < mCursorCount; i++) {
        mCursorDrawable[i].draw(canvas);
    }
    if (translate) canvas.translate(0, -cursorOffsetVertical);
}

Apparently, the cursor itself is a Drawable of some type.

So I am finding pieces, but I can't see the forest through the trees. Could someone who understands this better than me tell me in plain English how the blinking cursor works?

Here are some specific points I don't really understand:

  • The cursor's relationship to the TextView (or EditText), Layout, Editor, and Drawable.
  • Every time the cursor blinks, is all the text being redrawn or only the cursor region?

Note:

The accepted answer answers my question as I asked it. However, I would be glad to accept a different answer if anyone can add a more canonical one that explains things in more detail.

like image 291
Suragch Avatar asked Apr 01 '17 04:04

Suragch


2 Answers

  1. EditText is just editable TextView, Layout is used for measurements, calculation, where and how the text will laid out. Drawable is there just to hold the look of the cursor, later being drawn on the Canvas.
  2. Only cursor Path is invalidated.

Blinking basically is recursive Runnable that a Handler executes every 500ms (guessing), in on-off fashion, and it is rescheduled while EditText has focus. This also can be achieved by looping ValueAnimator of int, where the cursor drawable alpha will be toggled between 0 and 255.

like image 83
Nikola Despotoski Avatar answered Oct 20 '22 22:10

Nikola Despotoski


You can find this method in the TextView class:

public void setCursorVisible(boolean visible) {

    if (visible && mEditor == null) return; // visible is the default value with no edit data
    createEditorIfNeeded();
    if (mEditor.mCursorVisible != visible) {
        mEditor.mCursorVisible = visible;
        invalidate();

        mEditor.makeBlink();

        // InsertionPointCursorController depends on mCursorVisible
        mEditor.prepareCursorControllers();
    }
}
like image 41
Fatehali Asamadi Avatar answered Oct 20 '22 22:10

Fatehali Asamadi