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

Correct Android Screen Size (resizeOnFullScreen true - not full screen) #166

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

itbeyond
Copy link

If you set the preference for resizeOnFullScreen and you do not have your app running (or you allow user settings) in either fullscreen mode (via StatusBar) or Immersive fullscreen mode (via cordova-plugin-fullscreen) the height is calculated wrong and some content between 8 and 40 pixels dependant on device will be off the bottom of the screen. This update looks for isFullScreen as per #156, which was close but we still need to subtract the r.top from the return value hence this PR which has been tested on many devices with and without statusbar and immersive mode.

Based on and fixes #156, #117, #132, #134

…reen)

If you set the preference for resizeOnFullScreen and you do not have your app running in either fullscreen mode (via StatusBar) or Immersive fullscreen mode (via cordova-plugin-fullscreen) the height is calculated wrong and some content between 8 and 40 pixels dependant on device will be off the bottom of the screen. This update looks for isFullScreen

Based on and fixes ionic-team#156, ionic-team#117, ionic-team#132, ionic-team#134
@itbeyond
Copy link
Author

If anyone wants to use this PR you can use the fork I created from Master 2.2.0 which includes this PR. https://github.com/itbeyond/cordova-plugin-ionic-keyboard

@pierresh
Copy link

Hello,

Thanks a lot for your PR, nevertheless I needed to change it a bit to make it render perfectly (otherwise I still have the black bar).

Before

return isFullScreen() ? r.bottom - r.top : r.height();

After

return isFullScreen() ? r.bottom - r.top + 108 : r.height();

I have the option resizeOnFullScreen set to true in config.xml, and the status bar is overlay.

@pierresh
Copy link

pierresh commented Aug 9, 2022

For some Huawei devices, I need to change 108 to 50 to look nice...
Do you have any idea on which criteria this value might depend between devices?

@pierresh
Copy link

Actually, I have a solution to this problem

Create a file named FixScreen.java and put it beside the file called MainActivity.java

Basically it should be in '/platforms/android/app/src/main/java/com/company/app/'

(com/company/app because I assume the app's id is com.company.app, please replace with your app's one, as well as everywhere in files below)

package com.company.app;
 
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
 
import java.lang.reflect.Method;
 
public class FixScreen {
    public static void assistActivity([View](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+view) content) {
        new FixScreen(content);
    }
    private [View](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+view) mChildOfContent;
    private int usableHeightPrevious;
    private ViewGroup.LayoutParams frameLayoutParams;
    private FixScreen([View](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+view) content) {
        mChildOfContent = content;
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = mChildOfContent.getLayoutParams();
    }
    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        Log.d("usableHeightNow", "possiblyResizeChildOfContent() returned: " + usableHeightNow);
        if (usableHeightNow != usableHeightPrevious) {
            frameLayoutParams.height = usableHeightNow;
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }
 
    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom);
    }
    public static boolean checkDeviceHasNavigationBar([Context](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+context) context) {
        boolean hasNavigationBar = false;
        Resources rs = context.getResources();
        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
        if (id > 0) {
            hasNavigationBar = rs.getBoolean(id);
        }
        try {
            Class systemPropertiesClass = Class.forName("android.os.SystemProperties");
            [Method](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+method) m = systemPropertiesClass.getMethod("get", [String](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string).class);
            [String](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string) navBarOverride = ([String](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+string)) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
            if ("1".equals(navBarOverride)) {
                hasNavigationBar = false;
            } else if ("0".equals(navBarOverride)) {
                hasNavigationBar = true;
            }
        } catch ([Exception](http://www.google.com/search?hl=en&q=allinurl%3Adocs.oracle.com+javase+docs+api+exception) e) {
        }
        return hasNavigationBar;
    }
}

Then in MainActivity.java, 3 changes:
add import com.company.app.FixScreen;
add fixScreenOverlap();
add the function private void fixScreenOverlap(){ ... }

package com.company.app;

import android.os.Bundle;

import org.apache.cordova.*;

import com.company.app.FixScreen;

public class MainActivity extends CordovaActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // enable Cordova apps to be started in the background
        Bundle extras = getIntent().getExtras();
        if (extras != null && extras.getBoolean("cdvStartInBackground", false)) {
            moveTaskToBack(true);
        }

        // Set by <content src="index.html" /> in config.xml
        loadUrl(launchUrl);
        fixScreenOverlap();
    }

    private void fixScreenOverlap(){
        if (FixScreen.checkDeviceHasNavigationBar(this)) {
            FixScreen.assistActivity(findViewById(android.R.id.content));
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants