AndroidResideMenu icon indicating copy to clipboard operation
AndroidResideMenu copied to clipboard

Cutting Screen

Open ashishislive opened this issue 8 years ago • 6 comments

Hello, Residemenu measuring whole size of screen for rendering menu effect so it is not showing properly on those device have soft keys (home,back,recent) other then it is working as expected. I guess it is not excluding that extra space (soft key space)

ashishislive avatar Jan 17 '17 22:01 ashishislive

check pull request.

niteshsirohi1 avatar May 01 '17 03:05 niteshsirohi1

You need to change in library source code

@Override
    protected boolean fitSystemWindows(Rect insets) {
        setMyPadding(insets);
        return true;
    }

    @Override
    public WindowInsets onApplyWindowInsets(WindowInsets insets) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
            Rect rect = new Rect(
                    insets.getSystemWindowInsetLeft(),
                    insets.getSystemWindowInsetTop(),
                    insets.getSystemWindowInsetRight(),
                    insets.getSystemWindowInsetBottom()
            );
            setMyPadding(rect);
            return insets.consumeSystemWindowInsets();
        }
        return super.onApplyWindowInsets(insets);
    }

    private void setMyPadding(Rect rect) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (hasNavBar()) {
                WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
                switch (manager.getDefaultDisplay().getRotation()) {
                    case Surface.ROTATION_90:
                        rect.right += viewActivity.getPaddingRight() + getNavBarWidth();
                        break;
                    case Surface.ROTATION_180:
                        rect.top += viewActivity.getPaddingTop() + getNavBarHeight();
                        break;
                    case Surface.ROTATION_270:
                        rect.left += viewActivity.getPaddingLeft() + getNavBarWidth();
                        break;
                    default:
                        rect.bottom += viewActivity.getPaddingBottom() + getNavBarHeight();
                }
            }
        }
        setPadding(rect.left, rect.top, rect.right, rect.bottom);
    }

    private int getNavBarWidth() {
        return getNavBarDimen("navigation_bar_width");
    }

    private int getNavBarHeight() {
        return getNavBarDimen("navigation_bar_height");
    }

    private int getNavBarDimen(String resourceString) {
        Resources r = getResources();
        int id = r.getIdentifier(resourceString, "dimen", "android");
        if (id > 0) {
            return r.getDimensionPixelSize(id);
        } else {
            return 0;
        }
    }

    /**
     * check is system has navigation bar or not* http://stackoverflow.com/a/29120269/3758898
     *
     * @return true if navigation bar is present or false
     */
    boolean hasNavBar() {
        try {
            // check for emulator
            Class<?> serviceManager = Class.forName("android.os.ServiceManager");
            IBinder serviceBinder = (IBinder) serviceManager.getMethod("getService", String.class).invoke(serviceManager, "window");
            Class<?> stub = Class.forName("android.view.IWindowManager$Stub");
            Object windowManagerService = stub.getMethod("asInterface", IBinder.class).invoke(stub, serviceBinder);
            Method hasNavigationBar = windowManagerService.getClass().getMethod("hasNavigationBar");
            return (boolean) hasNavigationBar.invoke(windowManagerService);
        } catch (ClassNotFoundException
                | ClassCastException
                | NoSuchMethodException
                | SecurityException
                | IllegalAccessException
                | IllegalArgumentException
                | InvocationTargetException e) {

            boolean hasBackKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_BACK);
            boolean hasHomeKey = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_HOME);
            return !hasHomeKey && !hasBackKey;
        }

Kishanjvaghela avatar May 26 '17 09:05 Kishanjvaghela

@Kishanjvaghela thanks

Scienticious avatar Aug 17 '17 10:08 Scienticious

Still issue in larger screen. Please help!

Paridhi2502 avatar Apr 05 '18 12:04 Paridhi2502

Go to ResideMenu - > fitSystemWindows function This lines is in comment, just recomment it:

this.setPadding(viewActivity.getPaddingLeft() + insets.left, viewActivity.getPaddingTop() + insets.top, viewActivity.getPaddingRight() + insets.right, viewActivity.getPaddingBottom() + insets.bottom);

yocheved-check-in avatar Jan 21 '19 09:01 yocheved-check-in

I too was facing same issue with ResideMenu and tried different solutions. Finally i have found a clean solution which works in devices with all types of navigations including gesture navigations.

However, the only limitation is that, some other activity should be shown before showing this home activity (in which ResideMenu is used) like some Splash screen

  1. When this splash screen is launched, find its total height dynamically and save in some shared pref.
private void setAppUsableHeight() {
        final View root = findViewById(android.R.id.content);
        if (root != null) {
            root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout()  {
                    root.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    int height = root.getHeight();
                    GILog.d(TAG, "TDV height: " + height);
                    saveLastCalculatedValueForAppUsableHeight(height, SplashActivity.this);
                }
            });
        }
    }
  1. Change attachToActivity() method of ResideMenu as follows
public void attachToActivity(Activity activity, int customHeight) {
       // keep exiting implementation and add below lines to it
        if (customHeight > 0) {
            ViewGroup.LayoutParams params = viewActivity.getLayoutParams();
            if (params != null) {
                params.height = customHeight;
                viewActivity.setLayoutParams(params);
            }    
        }
    }
  1. Now, when Home screen (having reside menu) is launched, initialize ResideMenu as usual, adding these two extra lines
        resideMenu.setFitsSystemWindows(true);
        resideMenu.attachToActivity(this, getLastCalculatedValueForAppUsableHeight(this));
public static void saveLastCalculatedValueForAppUsableHeight(int height, Context context) {
        SharedPreferencesUtils.putSharedPreference(PREF_KEY_APP_USABLE_SCREEN_HEIGHT, String.valueOf(height), context);
    }

    public static int getLastCalculatedValueForAppUsableHeight(Context context) {
        String heightStr = SharedPreferencesUtils.getSharedPreference(PREF_KEY_APP_USABLE_SCREEN_HEIGHT, context);
        int height = 0;
        if (!TextUtils.isEmpty(heightStr)) {
            try {
                height = Integer.parseInt(heightStr);
            } catch (NumberFormatException e) {

            }
        }
        return height;
    }

  1. Also you should remove overriding implementation of public WindowInsets onApplyWindowInsets(WindowInsets insets) and protected boolean fitSystemWindows(Rect insets) methods in ResideMenu

Note: By doing this, the activity contents will not go behind the soft navigation bar. But the ResideMenu will still be behind the soft nav gar. But we can add an empty Menu item in the bottom to make sure all menu items are shown. Also, as our app is restricted to be only in Portrait mode, orientation changes are not handled, but you can do it easily.

mani516 avatar Feb 04 '19 05:02 mani516