[FREE/OS] AutoFontResizer Extension

🧩 FontResizer

An extension for MIT App Inventor 2.
Responsive Font Resizer (screen-width based, min–max bounded)

:memo: Specifications


:package: Package: jsr.fontresizer
:floppy_disk: Size: 8.60 KB
:mobile_phone: Minimum API Level: 14
:date: Updated On: 2026-01-13T18:30:00Z
:laptop: Built & documented using: FAST v5.3.2-premium

Special thanks to @JEWEL for his wounderfull platform for making extension.

:+1:


:blue_book: FontResizer Extension – Quick Guide

:small_blue_diamond: What this extension does

FontResizer automatically adjusts font sizes based on screen width only.

:check_mark: Text is readable on small phones
:check_mark: Text scales up on big phones, tablets, foldables
:check_mark: Font size stays within minimum and maximum limits
:check_mark: When screen size returns β†’ font size also returns
:check_mark: No manual font setting needed per device


:small_blue_diamond: How it works (simple idea)

The extension uses this rule:

Font Size = Base Font Γ— (Current Screen Width Γ· 360dp)

  • Base screen width: 360dp
  • Base font size: 14sp
  • Final font size is always kept between minSp and maxSp

So the same screen width always gives the same font size.


:small_blue_diamond: Functions

:one: ResizeSingleComponent

Resize font for one component (Label, Button, TextBox, etc.)

ResizeSingleComponent(component, minSp, maxSp)

Example

ResizeSingleComponent(Button1, 8, 26)

:two: ResizeInArrangement

Resize font for all text components inside an arrangement

ResizeInArrangement(Arrangement1, 8, 26)

:three: ResizeAll

Resize font for the entire screen

ResizeAll(8, 26)

:white_check_mark: This is the most commonly used function.


:small_blue_diamond: Event

Resized

Triggered after fonts are resized.

Resized(oldSizes, newSize, success)
  • oldSizes β†’ list of previous font sizes
  • newSize β†’ applied responsive font size
  • success β†’ true if resize worked

(Event is optional; you can ignore it if not needed.)


:small_blue_diamond: Automatic behavior (important)

:check_mark: Fonts resize automatically when the app opens
:check_mark: Works even if the app opens directly on a big or small screen

Recommended extra call:

when Screen.OrientationChanged
    call FontResizer.ResizeAll(8, 26)

This ensures perfect resizing on rotation.


:small_blue_diamond: Recommended usage (best practice)

  1. Set all component font sizes to 14sp in Designer

  2. Add FontResizer extension

  3. Use:

    ResizeAll(8, 26)
    
  4. (Optional) Call again on orientation change

That’s it :white_check_mark:


:small_blue_diamond: What this extension does NOT use

:cross_mark: Text width auto-fit
:cross_mark: Screen height
:cross_mark: Device-specific hacks
:cross_mark: Manual per-device font sizes

This keeps behavior stable, predictable, and readable.


:small_blue_diamond: Ideal for

:check_mark: Phones
:check_mark: Tablets
:check_mark: Foldables
:check_mark: Accessibility-friendly apps
:check_mark: Apps with many screen sizes


:white_check_mark: In short

Design once, read everywhere.
FontResizer handles screen size β€” you focus on your app.

:blush:

How to set autoResponsive for a particular arrangemnt?

How to set AutoResponsive for the whole screen?

Suggestions are welcome.

@Still-learning

9 Likes

This is something I have been struggling to create but no lucky to archive, I remember you always have my back, I mean I learned a lot from you, as based to your name as Still-learning I also still learning, if you don’t mind, can I see how you created this aix? Maybe you can PM me, I mean the java code, I won’t publish it anywhere just a sturdy
.

Anyways, amazing work

1 Like

Thats gives me good sound @Ibrahim_Jamar

Let me share the java here by changing few names alone :rofl:

package jsr.fontresizer;

import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.runtime.*;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.runtime.util.YailList;
import com.google.appinventor.components.runtime.EventDispatcher;

import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.util.TypedValue;
import android.content.res.Configuration;

import java.util.ArrayList;
import java.util.List;

@DesignerComponent(
    version = 9,
    description = "Responsive Font Resizer (screen-width based, min–max bounded)",
    category = ComponentCategory.EXTENSION,
    nonVisible = true,
    iconName = "icon.png"
)
@SimpleObject(external = true)
public class FontResizer extends AndroidNonvisibleComponent {

    // πŸ”’ Baseline reference
    private static final float BASE_SCREEN_DP = 360f;
    private static final float BASE_FONT_SP  = 14f;

    public FontResizer(ComponentContainer container) {
        super(container.$form());
    }

    // ─────────────────────────────────────────────────────────────
    // EVENT (SIMPLIFIED)
    // ─────────────────────────────────────────────────────────────

    @SimpleEvent(description = "Triggered after responsive font resize")
    public void Resized(YailList oldSizes, float newSize, boolean success) {
        EventDispatcher.dispatchEvent(this, "Resized", oldSizes, newSize, success);
    }

    // ─────────────────────────────────────────────────────────────
    // PUBLIC FUNCTIONS (SHORT & CLEAR)
    // ─────────────────────────────────────────────────────────────

    @SimpleFunction(description = "Resize font responsively for one component")
    public void ResizeOne(Component component, float minSp, float maxSp) {
        List<Float> oldSizes = new ArrayList<>();
        boolean success = false;

        View v = getView(component);
        if (v instanceof TextView) {
            TextView tv = (TextView) v;
            oldSizes.add(getFontSp(tv));

            float newSp = calcSize(minSp, maxSp);
            tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, newSp);
            success = true;
        }

        Resized(YailList.makeList(oldSizes),
                success ? calcSize(minSp, maxSp) : 0,
                success);
    }

    @SimpleFunction(description = "Resize font responsively in an arrangement")
    public void ResizeGroup(Component arrangement, float minSp, float maxSp) {
        List<Float> oldSizes = new ArrayList<>();
        boolean success = false;

        View v = getView(arrangement);
        if (v instanceof ViewGroup) {
            applyToGroup((ViewGroup) v, minSp, maxSp, oldSizes);
            success = !oldSizes.isEmpty();
        }

        Resized(YailList.makeList(oldSizes),
                success ? calcSize(minSp, maxSp) : 0,
                success);
    }

    @SimpleFunction(description = "Resize font responsively for entire screen")
    public void ResizeAll(float minSp, float maxSp) {
        List<Float> oldSizes = new ArrayList<>();
        boolean success = false;

        View root = form.$context().getWindow().getDecorView().getRootView();
        if (root instanceof ViewGroup) {
            applyToGroup((ViewGroup) root, minSp, maxSp, oldSizes);
            success = !oldSizes.isEmpty();
        }

        Resized(YailList.makeList(oldSizes),
                success ? calcSize(minSp, maxSp) : 0,
                success);
    }

    // ─────────────────────────────────────────────────────────────
    // CORE RESPONSIVE LOGIC (UNCHANGED)
    // ─────────────────────────────────────────────────────────────

    private float calcSize(float minSp, float maxSp) {
        float screenDp = getScreenWidthDp();
        float scale = screenDp / BASE_SCREEN_DP;

        float size = BASE_FONT_SP * scale;
        size = Math.max(minSp, Math.min(maxSp, size));

        return Math.round(size);
    }

    private float getScreenWidthDp() {
        Configuration cfg = form.$context().getResources().getConfiguration();
        return cfg.screenWidthDp;
    }

    // ─────────────────────────────────────────────────────────────
    // HELPERS
    // ─────────────────────────────────────────────────────────────

    private View getView(Component c) {
        return (c instanceof AndroidViewComponent)
                ? ((AndroidViewComponent) c).getView()
                : null;
    }

    private float getFontSp(TextView tv) {
        return tv.getTextSize() / tv.getResources().getDisplayMetrics().scaledDensity;
    }

    private void applyToGroup(ViewGroup group, float minSp, float maxSp, List<Float> oldSizes) {
        float newSp = calcSize(minSp, maxSp);

        for (int i = 0; i < group.getChildCount(); i++) {
            View child = group.getChildAt(i);

            if (child instanceof TextView) {
                TextView tv = (TextView) child;
                oldSizes.add(getFontSp(tv));
                tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, newSp);

            } else if (child instanceof ViewGroup) {
                applyToGroup((ViewGroup) child, minSp, maxSp, oldSizes);
            }
        }
    }
}

Still few more modifications can be done. We are calling thus extension in two places but still we could reduce it. But, how? Let i give it to the users choice. My extensions are free to use. Life is too short. What we learn let we trach to the nearby peoples. Learning and teaching will strengthen your skills.

3 Likes

Extension name is renamed to AutoFontResizer.

Oh!, I am so stupid. I forget to share the aix for testing.

Which function you want just add it in that procedure. thats all work is completed. No worry about fontsize on different devices with different width, Everything this little extention will carry on.

One New function was added. In Ai2 community there is blocks called oneeveryComponet button but in kodula rit doesnot. So i have added such function to change the font.

This InAnyComponent will resize those all specific component alone. Eg., if you give any one label, it will resize only label componets and do not alters other components

Extension V3 :

V3.java.autofontresizer.aix (13.3 KB)

Extension (renamed) : V2:

V2..java.autofontresizer.aix (9.0 KB)

Extension : V1:

jsr.fontresizer.aix (8.6 KB)

Sorry for not adding the extension. :pensive_face:

Version 3 Simple functions, events

2 Likes

You have a point​:hugs::hugs:

Let me punch it in my project :hugs::hugs:

Great work :green_heart::raising_hands:

2 Likes

Updated Version 3

New functions and one event are added for the ease of users.

Now users can autoresize the fonts as wella s can set properties via dictionary mode too..

Extension :

V3.java.autofontresizer.aix (13.3 KB)

If time persists, comment here which version you like and share your love by means of giving heart. If any other service you like to add in this extn pls share it with me as comment..

Forever yours,

@Still-learning

2 Likes