Transparent InputMethod for Android

Viewed 2298

Trying to make an Android InputMethod that is transparent - i.e. the underlying content shows through to the keyboard that I am developing.

I've been able to make the View that I pass to the system transparent - I think - but there seems to be something underneath my view that is solid white - and obfuscating the underlying content.

It is definitely possible, these guys do it:

https://play.google.com/store/apps/details?id=com.aitype.android.tablet.p&feature=search_result#?t=W251bGwsMSwxLDEsImNvbS5haXR5cGUuYW5kcm9pZC50YWJsZXQucCJd

3 Answers

I figured it out! Not sure if this is how the guys in your play store link did it, but this is what worked for me. Also, I realize this post is over a year old, but I'm still answering it just in case someone else out there discovers this when trying to create a transparent keyboard.

The "something" under your view is actually nothing - it's empty space. Your keyboard pushed the entire view up and out of the way to make room for its height, leaving empty white space behind. Your transparent keyboard let this white space show through.

Here's the solution: instead of returning your view in onCreateInputView, return it in onCreateCandidatesView. That's the view that normally lives above the keyboard and lists the autocorrect suggestions. But you're going to use this to house your actual keyboard.

The reason you want to have your keyboard be a candidates view is because the input view most often pushes the underlying view up. Individual apps can decide how they want to behave when a keyboard is shown via android:windowSoftInputMode and the input view respects their preference, but the candidates view always uses adjustPan.

From the docs: "Note that because the candidate view tends to be shown and hidden a lot, it does not impact the application UI in the same way as the soft input view: it will never cause application windows to resize, only cause them to be panned if needed for the user to see the current focus." http://developer.android.com/reference/android/inputmethodservice/InputMethodService.html

So, return your transparent view from onCreateCandidatesView, return null from onCreateInputView and make sure to call setCandidatesViewShown(true) so your candidates view shows up (I call it in onWindowShown).

It may such easy to make the full screen keyboard layout extra area transparent via java reflection only if you're quite familiar with InputMethodService.

the extra area has an id name fullscreenArea, you can fetch the area's id, then findViewById() then set its background.

the keyboard look as this before I done my practice :

before appearance

a giant blank cover the below page.

so after is :

after

you can see the below page which contained an EditText and others displayed.

here is my code :

public static void makeKeyboardTransparent(InputMethodService service) {
    try {
        View decorView = service.getWindow().getWindow().getDecorView();
        final int viewId = fetchInternalRId("fullscreenArea");
        View fullscreenArea = decorView.findViewById(viewId);
        if (fullscreenArea != null) {
            modifyView(fullscreenArea);
            return;
        }
    } catch (Exception e) {
    }

    try {
        Class<?> superClass = service.getClass().getSuperclass();
        Field fullscreenAreaField = superClass.getDeclaredField("mFullscreenArea");
        fullscreenAreaField.setAccessible(true);
        View fullscreenArea = (View) fullscreenAreaField.get(service);
        if (fullscreenArea != null) {
            modifyView(fullscreenArea);
        }
    } catch (Exception e) {
    }
}

private static void modifyView(View fullscreenArea) {
    fullscreenArea.setBackgroundColor(Color.TRANSPARENT);
}

private static int fetchInternalRId(String name) throws Exception {
    Class<?> rIdClass = Class.forName("com.android.internal.R$id");
    return rIdClass.getDeclaredField(name).getInt(rIdClass);
}

I provided two approach to make the blank area transparent, both of them worked fine in my test, all you need is pass your InputMethodService into makeKeyboardTransparent() and see what it can do.

Related