Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Soft KeyBoard problem #877

Closed
MatteCarra opened this issue Dec 13, 2015 · 24 comments
Closed

Soft KeyBoard problem #877

MatteCarra opened this issue Dec 13, 2015 · 24 comments
Assignees
Milestone

Comments

@MatteCarra
Copy link

MaterialDrawer is causing some problem with keyboard.
When I am in landscape mode I click an edittext then keyboard opens.
Then I rotate the device and the bug happens!
Bug here: http://stackoverflow.com/questions/34204230/soft-keyboard-push-up-hidding-action-bar-or-overlay-edittext

I tried to remove this library and all works.
Today I will try to update this library

@mikepenz
Copy link
Owner

@MatteCarra the problem is that we require the FULLSCREEN flag, so we can display the Drawer under the StatusBar. The Android system handles the keyboard different when the full screen flag is set

There were long discussions about this here:
#95
and here:
#183

@MatteCarra
Copy link
Author

I have already Turned on keyboardSupport...

@mikepenz
Copy link
Owner

@MatteCarra yeah it is no perfect solution. It may needs adjustments in landscape mode.
The only really solution is that you go with a non full height drawer. which is below the statusbar

@mikepenz mikepenz self-assigned this Dec 13, 2015
@MatteCarra
Copy link
Author

Ok thank you.

P.s:
I have to do withFullscreen(false)?

@mikepenz
Copy link
Owner

@MatteCarra i'm really sorry for this. I still hope someone comes up with a better solution.

TranslucentStatusbar false, and TranslucentNavigationbar false, (yes Fullscreen false should do the job) and a normal non translucent statusbar theme

@MatteCarra
Copy link
Author

This solution doesn't work.
But I think this is an other bug you can easily fix, but not sure.

To reproduce this bug:

  • Open MaterialDrawer app in Keyboard util fix
  • Rotate the device in landscape mode
  • Click on the latest edittext
  • rotate the device without closing keyboard.
  • click the latest edittext and try to write

@mikepenz
Copy link
Owner

@MatteCarra you also disabled the keyboardutil?

@MatteCarra
Copy link
Author

Ops I forget.
But I can't publish my app with drawer under status bar :(
Try to reproduce the bug.
All works really fine with your keyboard util except this

@mikepenz
Copy link
Owner

perhaps you can open/close the keyboard when rotating?

@MatteCarra
Copy link
Author

I will try, but I think to had already tried this solution.
OnCreateView or onConfigurationChanged or both?
P.s: the problem persist also if you close (manually) the keyboard and then you re-click the edittext

@mikepenz
Copy link
Owner

The sample app includes the KeyboardUtil Drawer, try if it also occurs there. Just tried the keyboard is closed after rotation

@MatteCarra
Copy link
Author

Yes but after rotation click latest edittext and try to write hello

@MatteCarra
Copy link
Author

Have you the same problem?

@mikepenz
Copy link
Owner

@MatteCarra i will check. But the KeyboardUtil shouldn't be the problem as it is recreated after the screen is rotated.
I am really not sure how it reacts when the keyboard keeps shown after rotation, as in landscape the editText is shown in fullscreen with the keyboard (normally)

@MatteCarra
Copy link
Author

No. That isn't the problem.
It creates badly something after rotation. If I close and then reopen the keyboard the problem persist. The problem isn't that the keyboard remain shown, I think

@MatteCarra
Copy link
Author

In keyboard util System.out.println(heightDiffDp - initialDpDiff) after rotating it becomes negative like -482.33334 so the layout doesn't change when keyboard comes up (this happens only when you rotate with keyboard open)

@mikepenz
Copy link
Owner

So you do not recreate the activity as it is recommended? I assume you have the configChanges set in the Manifest.

I highly recommend you to recreate the activity and remember the previous state via the savedInstanceState, as it is recommended.

@MatteCarra
Copy link
Author

No configChanges! My manifest => http://pastebin.com/iuGie38m

Values after 2 rotations (final portait) with keyboard open:
InitialDpDiff = 506.33334
heightDiffDp = 24.0
heightDiffDp - initialDpDiff = -482.33334

Rotation without keyboard open:
InitialDpDiff = 24.0
heightDiffDp = 287.33334
GrandTotal = 263.33334

@mikepenz
Copy link
Owner

@MatteCarra i have modified some things of the KeyboardUtil would you love to test it?

I hope it improves the behavior on your side too

/*
 * Copyright 2015 Mike Penz All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.mikepenz.materialdrawer.util;

import android.app.Activity;
import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;

/**
 * Created by mikepenz on 14.03.15.
 * This class implements a hack to change the layout padding on bottom if the keyboard is shown
 * to allow long lists with editTextViews
 * Basic idea for this solution found here: http://stackoverflow.com/a/9108219/325479
 */
public class KeyboardUtil {
    private View decorView;
    private View contentView;

    public KeyboardUtil(Activity act, View contentView) {
        this.decorView = act.getWindow().getDecorView();
        this.contentView = contentView;

        //only required on newer android versions. it was working on API level 19
        if (Build.VERSION.SDK_INT >= 19) {
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    public void enable() {
        if (Build.VERSION.SDK_INT >= 19) {
            decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }

    public void disable() {
        if (Build.VERSION.SDK_INT >= 19) {
            decorView.getViewTreeObserver().removeOnGlobalLayoutListener(onGlobalLayoutListener);
        }
    }


    //a small helper to allow showing the editText focus
    ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            decorView.getWindowVisibleDisplayFrame(r);

            int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
            int bottom = r.bottom;

            //if it could be a keyboard add the padding to the view
            if (bottom - height != 0) {
                // if the use-able screen height differs from the total screen height we assume that it shows a keyboard now
                //check if the padding is 0 (if yes set the padding for the keyboard)
                if (contentView.getPaddingBottom() == 0) {
                    //set the padding of the contentView for the keyboard
                    contentView.setPadding(0, 0, 0, height - bottom);
                }
            } else {
                //check if the padding is != 0 (if yes reset the padding)
                if (contentView.getPaddingBottom() != 0) {
                    //reset the padding of the contentView
                    contentView.setPadding(0, 0, 0, 0);
                }
            }
        }
    };


    /**
     * Helper to hide the keyboard
     *
     * @param act
     */
    public static void hideKeyboard(Activity act) {
        if (act != null && act.getCurrentFocus() != null) {
            InputMethodManager inputMethodManager = (InputMethodManager) act.getSystemService(Activity.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

@MatteCarra
Copy link
Author

Yes :)
I will test them this afternoon!

@MatteCarra
Copy link
Author

If after rotation I hide keyboard it works (or if I manually close it and then I reopen it)
If I do not this happens:
device-2015-12-15-151404

@MatteCarra
Copy link
Author

I understand why:

if (contentView.getPaddingBottom() == 0) <- problem

Because when I rotate it has already a padding, but it needs to be updated!
Commenting it works but I don't know if it has side-effects

@MatteCarra
Copy link
Author

   //a small helper to allow showing the editText focus
    ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Rect r = new Rect();
            //r will be populated with the coordinates of your view that area still visible.
            decorView.getWindowVisibleDisplayFrame(r);

            int height = decorView.getContext().getResources().getDisplayMetrics().heightPixels;
            int bottom = r.bottom;

            //if it could be a keyboard add the padding to the view
            if (bottom - height != 0) {
                // if the use-able screen height differs from the one is set then we update padding
                int diff = height - bottom;
                if (contentView.getPaddingBottom() != diff) {
                    //set the padding of the contentView for the keyboard
                    contentView.setPadding(0, 0, 0, diff);
                }
            } else {
                //check if the padding is != 0 (if yes reset the padding)
                if (contentView.getPaddingBottom() != 0) {
                    //reset the padding of the contentView
                    contentView.setPadding(0, 0, 0, 0);
                }
            }
        }
    };

@mikepenz
Copy link
Owner

@MatteCarra thanks i will check again.
In general the == 0 check is made that it does not reset the padding over and over again which has a huge performance impact. You solution seems good. Will test it on all supported android versions and include it in the next release if it passes all tests ;)

@mikepenz mikepenz added this to the v4.5 milestone Dec 15, 2015
@mikepenz mikepenz modified the milestones: v4.5.9, v4.5 Dec 15, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants