Android 動(dòng)態(tài)調(diào)整應(yīng)用字體大小

Android應(yīng)用字體大小默認(rèn)隨系統(tǒng)設(shè)置的字體大小而變化,但您可能不希望您的應(yīng)用字體大小隨系統(tǒng)設(shè)置變化,想要自己控制,例如微信。本文簡(jiǎn)單介紹一下如何實(shí)現(xiàn)應(yīng)用字體大小動(dòng)態(tài)調(diào)整而不是依賴系統(tǒng)設(shè)置

字體大小變化是由android.content.res.Configuration.class類中的fontScale控制的,因此,若想我們的應(yīng)用字體大小變化不隨系統(tǒng)變化而是由我們自主控制,就需要我們修改fontScale為我們自己設(shè)置的數(shù)值。由于Android系統(tǒng)更新的問(wèn)題,可能您無(wú)法通過(guò)網(wǎng)上的答案來(lái)實(shí)現(xiàn)您的目的。根據(jù)目前筆者的測(cè)試情況,我們需要從Activity層面進(jìn)行處理才能自主控制字體大小變化,為了方便統(tǒng)一處理,將控制邏輯放在了Application中,下面貼出實(shí)例圖片及代碼(由于筆者水平實(shí)在是low,不會(huì)做滑動(dòng)條來(lái)控制字體大小,因此,示例中使用了兩個(gè)TextView來(lái)點(diǎn)擊控制字體大小變化,哈哈哈~)


public class MainApplication extends Application implements Application.ActivityLifecycleCallbacks {

    private List<Activity> activityList;
    private float fontScale;
    private SharedPreferences preferences;
    private static MainApplication mainApplication;

    @Override
    public void onCreate() {
        super.onCreate();
        init();
    }

    private void init() {
        mainApplication = this;
        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        fontScale = getFontScale();
        registerActivityLifecycleCallbacks(this);
    }

    public static float getFontScale() {
        float fontScale = 1.0f;
        if (mainApplication != null) {
            fontScale = mainApplication.preferences.getFloat("fontScale", 1.0f);
        }
        return fontScale;
    }

    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        if (activityList == null) {
            activityList = new ArrayList<>();
        }
        // 禁止字體大小隨系統(tǒng)設(shè)置變化
        Resources resources = activity.getResources();
        if (resources != null && resources.getConfiguration().fontScale != fontScale) {
            android.content.res.Configuration configuration = resources.getConfiguration();
            configuration.fontScale = fontScale;
            resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        }
        activityList.add(activity);
    }

    @Override
    public void onActivityStarted(Activity activity) {

    }

    @Override
    public void onActivityResumed(Activity activity) {

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {

    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {
        if (activityList != null) {
            activityList.remove(activity);
        }
    }

    public static void setAppFontSize(float fontScale) {
        if (mainApplication != null) {
            List<Activity> activityList = mainApplication.activityList;
            if (activityList != null) {
                for (Activity activity : activityList) {
                    if (activity instanceof SettingActivity) {
                        continue;
                    }
                    Resources resources = activity.getResources();
                    if (resources != null) {
                        android.content.res.Configuration configuration = resources.getConfiguration();
                        configuration.fontScale = fontScale;
                        resources.updateConfiguration(configuration, resources.getDisplayMetrics());
                        activity.recreate();
                        if (fontScale != mainApplication.fontScale) {
                            mainApplication.fontScale = fontScale;
                            mainApplication.preferences.edit().putFloat("fontScale", fontScale).apply();
                        }
                    }
                }
            }
        }
    }
}

首先,我們需要讓Application實(shí)現(xiàn)ActivityLifecycleCallbacks接口,并注冊(cè)ActivityLifecycleCallbacks以便監(jiān)控所有Activity,并維護(hù)一個(gè)Activity列表。在onActivityCreated方法中我們可以監(jiān)控每個(gè)Activity的創(chuàng)建,當(dāng)新建一個(gè)Activity時(shí),獲取其Resource資源,進(jìn)而判斷Configuration.fontScale數(shù)值是否與我們自己的fontScale數(shù)值(默認(rèn)1.0,即大小沒(méi)有經(jīng)過(guò)調(diào)整)相等,若數(shù)值不一致時(shí),修改之。其實(shí),只要我們通過(guò)一個(gè)Activity修改了Configuration.fontScale數(shù)值,那么所有其他Activity再獲取Configuration.fontScale數(shù)值時(shí),其值均為我們修改過(guò)之后的數(shù)值。通過(guò)這一波操作,已經(jīng)保證我們的應(yīng)用的字體大小不隨系統(tǒng)設(shè)置變化了。

下面看如何動(dòng)態(tài)調(diào)整應(yīng)用字體大小,看一下setAppFontSize方法。該方法遍歷Activity列表,獲取Resource配置信息并修改其fontScale數(shù)值,需要注意的是,若想及時(shí)生效,需要調(diào)用Activity的recreate()方法。
注意:recreate()方法會(huì)導(dǎo)致Activity重建,但幸運(yùn)的是調(diào)用該方法,系統(tǒng)會(huì)觸發(fā)onSaveInstanceState回調(diào),因此強(qiáng)烈建議您在該回調(diào)方法中做好數(shù)據(jù)保存以便重建時(shí)恢復(fù)數(shù)據(jù)。
另外一個(gè)建議是:不要把字體大小設(shè)置選項(xiàng)層級(jí)埋的太深,最好放在首頁(yè),因?yàn)檫@樣放置,當(dāng)調(diào)整字體大小時(shí)只會(huì)導(dǎo)致首頁(yè)重建,不會(huì)影響其他頁(yè)面,將影響將到最小

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,147評(píng)論 25 708
  • EnglishVersion ->_->:https://github.com/jiang111/awesome-...
    聶順閱讀 1,317評(píng)論 0 4
  • 新請(qǐng)的護(hù)工不早不晚站在他們身后小心謹(jǐn)慎建議道:“鄧先生,十一點(diǎn)半了,你們回去吧!放心,我會(huì)看護(hù)好卓先生的?!?好,...
    小鹿故事集閱讀 377評(píng)論 0 0
  • 清晨起來(lái),天上一朵朵白云夾著在藍(lán)天中,溫度適宜。我們吃完早餐,繼續(xù)坐著旅游車出發(fā)。導(dǎo)游給我們講解臺(tái)灣的珊瑚是這么生...
    清清白白灬閱讀 305評(píng)論 0 0
  • 不要刻意改變自己,也不要想改變他,如果這樣還能一路走下去,這就是最好的答案?!段铱赡懿粫?huì)愛(ài)你》 寬容不是道德,...
    胖球66閱讀 198評(píng)論 0 0

友情鏈接更多精彩內(nèi)容