Friday, May 15, 2026

Android java: calculation for ime wreda keyboard build 2026.09

Code


    // Emoji column and row
    int emojiGridColumns = 8; // store number of emoji
    float emojiGridRows = 3.5f; // store row in emoji
    // IME View size
    int finalWidth=0,finalHeight=0; // final value for IME View
    
    // -------------- set ime view size and emoji -----------------------
    // old version
    private void setIMEViewSizeAndEmojiOld() {
        // 1. Get the Calculator instance
        WindowMetricsCalculator calculator = WindowMetricsCalculator.getOrCreate();
        // 2. Compute current metrics for this specific Activity
        // This works on API 24 (Split Screen) up to API 37
        WindowMetrics metrics = calculator.computeCurrentWindowMetrics(myWredaKeyboard);

        // 3. Get the bounds (Rect)
        Rect bounds = metrics.getBounds();
        float density = myWredaKeyboard.getResources().getDisplayMetrics().density;

        int screenWidth = bounds.width();
        int screenHeight = bounds.height();
        boolean isWide = screenWidth > screenHeight;
        // Handle Navigation Bar Overlap (API 24+ Compatibility)
        // MANUAL INSET
        if (isWide) {
            // In landscape, navigation bars are usually on the left or right.
            // 48dp is the standard minimum size for system bars.
            int navBarWidth = (int) (48 * density);

            // Subtract space for both sides to be safe and centered
            screenWidth = screenWidth - (2 * navBarWidth);
        }

        float screenRatio = (float) screenWidth/screenHeight;
        float smallestWidthDp = Math.min(screenWidth, screenHeight) / density;

        int numberOfKeysColumn = 10;
        int numberOfKeysRow = 5;
        float keyWHRatioPortrait = 0.5f;// width : height = 1:2


        // --- ADAPTIVE ENGINE ---

        if (screenRatio > 0.85f && screenRatio < 1.2f) {
            // 📱 FOLDABLES / SQUARE DEVICES (Unfolded state)

            // 1. Keep it short. 25% is good because the screen is huge vertically.
            finalHeight = (int) (0.25f * screenHeight);

            // 2. Calculate the "Perfect Square" key size
            // If keys are square, width = height.
            int keyHeight = finalHeight / numberOfKeysRow;

            // 3. Set Width based on the Square Key
            // We multiply keyHeight by columns to get a keyboard that fits the keys perfectly.
            int idealWidth = keyHeight * numberOfKeysColumn;

            // 4. Center it
            // This ensures the keyboard doesn't stretch. It will sit in the middle
            // with empty space on the sides, making it reachable for thumbs.
            finalWidth = Math.min(screenWidth, idealWidth);

            // Debug for Foldable
            //Log.e("dedetok", "Foldable Mode active. Width constrained to: " + finalWidth); // debug

        } else if (isWide) {

            // 📺 LANDSCAPE (TV, Tablet, Wide Phone)
            // Goal: "Fat" Keys (Wide). You mentioned "landscape make it fat"
            // To make them fat (wider than tall), we DIVIDE by the 0.5 ratio

            if (smallestWidthDp >= 600) {
                // ️ TABLET LANDSCAPE: Keep it shorter so it doesn't cover the whole screen
                finalHeight = (int) (0.45f * screenHeight);
            } else {
                //  PHONE LANDSCAPE: Make it "bigger" to be usable
                finalHeight = (int) (0.55f * screenHeight);
            }
            // Re-calculate keyHeight AFTER setting finalHeight
            int keyHeight = finalHeight / numberOfKeysRow;
            int idealWidth = (int) (keyHeight / keyWHRatioPortrait * numberOfKeysColumn);
            //Log.e("dedetok", "screenWidth "+screenWidth+" idealWidth "+idealWidth);// debug

            // Use min to ensure it doesn't bleed off screen
            finalWidth = Math.min(screenWidth, idealWidth);

        } else {
            // phone
            if (smallestWidthDp >= 600) {
                // 🏗️ TABLET LANDSCAPE: Keep it shorter so it doesn't cover the whole screen
                finalHeight = (int) (0.30f * screenHeight);
                int keyHeight = finalHeight / numberOfKeysRow;
                int idealWidth = (int) (keyHeight / keyWHRatioPortrait * numberOfKeysColumn);

                // Use min to ensure it doesn't bleed off screen
                finalWidth = Math.min(screenWidth, idealWidth);
            } else {
                // 📱 PHONE PORTRAIT: Make it "bigger" to be usable
                finalHeight = (int) (0.35f * screenHeight);
                finalWidth = screenWidth;
            }

        }
        //Log.e("dedetok", "Width: "+finalWidth+" Height: "+finalHeight); // debug

        // ------------ now calculate emoji grid column and row
        int availableHeight = (int)(finalHeight * 0.8f);
        int emojiSize;
        if (screenRatio > 0.85f && screenRatio < 1.2f) {
            // Treat foldables like portrait tablets
            int targetRows = 4;
            int emojiSizeBox = (availableHeight / targetRows) + 6;
            emojiSize = Math.max(emojiSizeBox, 120); // slightly bigger for the big screen

            emojiGridColumns = finalWidth / emojiSize;
            emojiGridRows = (float) availableHeight / emojiSize;
        } else if (isWide && smallestWidthDp < 600) {
            // Force 9 columns to make emojis large enough to only fit ~2 rows
            emojiGridColumns = 9;
            emojiSize = finalWidth / emojiGridColumns;
            emojiGridRows = (float) availableHeight / emojiSize;
        } else {
            // Portrait: Standard 4 rows
            int targetRows = 4;
            int emojiSizeBox = (availableHeight / targetRows) + 6; // 6 space
            emojiSize = Math.max(emojiSizeBox, 100);

            emojiGridColumns = finalWidth / emojiSize;
            emojiGridRows = (float) availableHeight / emojiSize;
        }
    }    

Build 2026.09