Android soft keyboard in a fullscreen Surface View

2019-01-29 10:23发布

HI! I am currently extending an Android Game Framework,which I found in a Book written by Mario Zechner (who also develops Libgdx).

It is working great so far and I accomplished a Java Desktop Implementation of the Framework.

But one tiny thing is missing, the correct usage of the SoftKeyboard.

You can try out and reproduce my bug, the whole project is on github, and the android module is the "app"folder. The java version (left arrow key = key back) is in the javalib module.

https://github.com/Railwanderer/AndroidGameFramework

The Framework uses Window FullScreenFlags and NoTitle Flags in combination with a Surface View for rendering.

The Flags in AndroidGame Class:

// set FullScreen
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

The Surface View:

public class AndroidFastRenderView extends SurfaceView implements Runnable {

AndroidGame game;
Bitmap framebuffer;
Thread renderThread = null;
SurfaceHolder holder;

// Fps Counting Stuff...
static long             lastTime;
static double           fps;
static String           FPS = "";


volatile boolean running = false;


public AndroidFastRenderView(AndroidGame game, Bitmap framebuffer) {
    super(game);
    this.game = game;
    this.framebuffer = framebuffer;
    this.holder = getHolder();
}

public void resume() {
    running = true;
    renderThread = new Thread(this);
    renderThread.start();
}

public void run() {
    Rect dstRect = new Rect();
    long startTime = System.nanoTime();
    while (running) {
        if (!holder.getSurface().isValid())
            continue;

        lastTime = System.nanoTime();
        float deltaTime = (System.nanoTime() - startTime) / 1000000000.0f;
        startTime = System.nanoTime();

        game.getCurrentScreen().update(deltaTime);
        Graphics g = game.getGraphics();
        g.clear(Color.BLACK);
        game.getCurrentScreen().present(deltaTime);
        g.drawString(FPS,framebuffer.getWidth()-100,framebuffer.getHeight()-30);

        Canvas canvas = holder.lockCanvas();
        canvas.getClipBounds(dstRect);
        canvas.drawBitmap(framebuffer, null, dstRect, null);
        holder.unlockCanvasAndPost(canvas);

        //one second(nano) divided by amount of time it takes for one frame to finish
        fps = 1000000000.0 / (System.nanoTime() - lastTime);
        lastTime = System.nanoTime();
        FPS = "FPS: " + (int) fps;
    }
}

public void pause() {
    running = false;
    while (true) {
        try {
            renderThread.join();
            break;
        } catch (InterruptedException e) {
            // retry
        }
    }
}

My Problem is when I try to pull up the SoftKeyboard, it would show when calling with SHOW_FORCED. It also lays itself ontop of my surface view, but the touch events won't trigger the keyboard but somehow pass thru and hit my surface view.

public void showKeyboard(){
    inputManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
}

When I hit the most upper border of the soft keyboard (first line keys upper edges) like crazy, eventually some touch events actually trigger the keys. But it only works for the first Line of keys and not satisfying at all. I get the Impression that the whole thing is shifted since the recorded touch events come back with an offset.

I am currently calling the soft keyboard with any keyEvent ( first line onKey() method of key listener). so the back key will trigger the keyboard. This key is always recognized since it is a hard key on my device.

-Is there a possibility to archive fullscreen with a resizable layout? I guess its the flags preventing the keyboard to work correctly. -any other ideas to combine the both?

Additionally here my android manifest, the only xml file this app uses:

<application android:icon="@mipmap/ic_launcher" android:label="TestGame">

    <activity android:name="railwanderer.androidgameframework.ExampleAndroidGame.StartClass"
        android:label="StartClass"
        android:screenOrientation="landscape"
        android:configChanges="keyboard|keyboardHidden|orientation">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

    </activity>
</application>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="9"/>

1条回答
看我几分像从前
2楼-- · 2019-01-29 10:33

I found a solve :D https://stackoverflow.com/questions/33561137/soft-keyboard-not-receiving-touches-over-surfaceview

I did override onCreateInputConnection method on the CustomSurfaceView class, like in the posted link.

@Override
  public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
   InputConnection conn = super.onCreateInputConnection(outAttrs);
   outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN;
   return conn;
}

it works now, pls try it out, I will upload right away to see if it works on your device too.

查看更多
登录 后发表回答