You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过一个Activity修改另一Activity中TextView的字号

现有实现的核心问题

你当前的写法存在三个明确的不规范问题:

  • 直接通过MainActivity的静态公开变量持有Activity实例,会造成严重内存泄漏,Activity销毁后静态引用仍持有实例会导致GC无法回收内存,极易触发OOM崩溃
  • 跨Activity直接操作另一个页面的View,完全违反Android组件生命周期设计:当MainActivity被系统回收重建、处于后台不可见状态时,直接操作其View会触发空指针、状态错乱等不可预期问题
  • 大量重复的findViewById和setTextSize调用,代码冗余度极高,后续新增控件时需要重复修改代码,维护成本很高
规范实现方案

Android跨页面传值的标准实现是使用页面结果返回机制,将用户输入的字号值回传给MainActivity,由MainActivity在自身生命周期内更新View,完全不需要持有其他Activity的实例。

第一步:修改SecondActivity逻辑

点击按钮时仅做输入校验和结果回传,直接关闭当前页即可,禁止直接操作MainActivity的任何View:

buttonChangeFontSizeOfCalculator.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        String inputContent = editTextInsertSize.getText().toString().trim();
        // 输入合法性校验,避免非法输入触发崩溃
        if (inputContent.isEmpty()) {
            editTextInsertSize.setError("请输入字号数值");
            return;
        }
        float fontSize;
        try {
            fontSize = Float.parseFloat(inputContent);
        } catch (NumberFormatException e) {
            editTextInsertSize.setError("请输入合法数字");
            return;
        }
        // 将字号塞入返回Intent
        Intent resultIntent = new Intent();
        resultIntent.putExtra("key_font_size", fontSize);
        setResult(RESULT_OK, resultIntent);
        // 关闭当前页回到MainActivity
        finish();
    }
});

第二步:修改MainActivity逻辑

首先删除MainActivity中公开的静态mainActivity实例,这个静态变量是造成问题的核心根源。
使用AndroidX提供的Activity Result API监听SecondActivity的返回结果,拿到字号后递归遍历页面根布局下的所有TextView,批量设置字号,不需要逐个编写findViewById代码:

// 在MainActivity中注册页面返回回调
ActivityResultLauncher<Intent> fontSizeSettingLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == RESULT_OK && result.getData() != null) {
                float targetFontSize = result.getData().getFloatExtra("key_font_size", 14f);
                // 传入页面根布局,批量更新所有TextView字号
                ViewGroup pageRoot = findViewById(R.id.main_root_layout);
                applyFontSizeToAllTextViews(pageRoot, targetFontSize);
            }
        }
);

// 跳转SecondActivity时使用注册好的launcher启动,替换原有startActivity调用
// 示例:findViewById(R.id.to_setting_btn).setOnClickListener(v -> {
//     fontSizeSettingLauncher.launch(new Intent(MainActivity.this, SecondActivity.class));
// });

// 递归遍历布局,给所有TextView设置字号的工具方法
private void applyFontSizeToAllTextViews(View currentView, float fontSize) {
    if (currentView instanceof TextView) {
        ((TextView) currentView).setTextSize(fontSize);
    } else if (currentView instanceof ViewGroup) {
        ViewGroup viewGroup = (ViewGroup) currentView;
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            applyFontSizeToAllTextViews(viewGroup.getChildAt(i), fontSize);
        }
    }
}
可选优化
  • 如果需要字号设置在App重启后仍然生效,可以将字号值存储到SharedPreferences中,MainActivity在onCreate生命周期中读取存储值,调用同样的遍历方法设置字号即可
  • 递归遍历设置字号的逻辑会自动覆盖后续新增的所有TextView,不需要因为页面新增控件修改设置字号的代码
  • 所有用户输入的内容必须增加合法性校验,避免空值、非数字输入触发NumberFormatException崩溃

注意:绝对不要通过静态变量持有Activity、View等Context相关对象,这是Android开发中的典型错误写法,除内存泄漏外,当Activity因屏幕旋转、系统内存不足被重建时,静态变量持有的是已销毁的旧Activity实例,操作其上的View必然触发崩溃。

内容的提问来源于stack exchange,提问作者m0ntr3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 16:09:21