### Background

A custom editor view in Android is able to receive text from a system keyboard though an `InputConnection`. I have been able to make such a view successfully. However, when the device is in landscape mode, the system will sometimes choose to show a extracted text view. When users type in this mode the extracted text view should be updated with the same text that is in the custom view. 

I have not been able to implement the extracted text view functionality. ([Here are some things I've tried.](https://stackoverflow.com/questions/50829361/how-to-update-extracted-text-in-a-custom-editor-view)) 

I also have not been able to find any clear documentation or full examples of how to do it. (Here are some of the better things I've read: [one](https://developer.android.com/guide/topics/text/creating-input-method), [two](https://developer.android.com/reference/android/view/inputmethod/InputConnection), [three](https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/widget/TextView.java), [four](https://android.googlesource.com/platform/frameworks/base/+/37960c7/core/java/android/widget/Editor.java)).

### MCVE

I've created the most basic custom editor that I can. The following gif shows the functionality. It can receive text from the keyboard but it does not update the extracted text view in landscape orientation. Thus you can't see the updated text unless you dismiss the keyboard.

[![enter image description here](https://i.stack.imgur.com/V6BSd.gif)](https://i.stack.imgur.com/V6BSd.gif)

*MyCustomView.java*

```
public class MyCustomView extends View {

    SpannableStringBuilder mText;
    Paint mPaint;

    public MyCustomView(Context context) {
        this(context, null, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyCustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setFocusableInTouchMode(true);
        mText = new SpannableStringBuilder();
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
        mPaint.setTextSize(60);
        mPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText(mText, 0, mText.length(), 50, 100, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (imm == null) return false;
            imm.showSoftInput(this, InputMethodManager.SHOW_FORCED);
        }
        return true;
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        outAttrs.inputType = InputType.TYPE_CLASS_TEXT;
        return new MyInputConnection(this, true);
    }
}

```

*MyInputConnection.java*

```
public class MyInputConnection extends BaseInputConnection {

    private MyCustomView customView;

    MyInputConnection(View targetView, boolean fullEditor) {
        super(targetView, fullEditor);
        customView = (MyCustomView) targetView;
    }

    @Override
    public Editable getEditable() {
        return customView.mText;
    }

    @Override
    public boolean commitText(CharSequence text, int newCursorPosition) {
        boolean returnValue = super.commitText(text, newCursorPosition);
        customView.invalidate();
        return returnValue;
    }
}

```

*MainActivity.java*

```
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

```

*activity\_main.xml*

```
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <net.example.extractedtext.MyCustomView
        android:id="@+id/myCustomView"
        android:background="@android:color/holo_blue_bright"
        android:layout_margin="50dp"
        android:layout_width="300dp"
        android:layout_height="150dp"
        android:layout_centerHorizontal="true"
        />

</RelativeLayout>

```

### Summary

I am looking for a canonical answer that describes and gives an example of how to implement extracted text updates for a custom editor view. 

If I figure it out myself, I will add my own answer. Until then the best I have been able to do it just [disable extracted text altogether](https://stackoverflow.com/a/4726646/3681880). This is not ideal.