Android中setTextSize方法无效,RecyclerView文本大小修改失败
问题根源:你修改的是“假”的TextView!
嘿,我一眼就看出问题出在哪了——你当前的代码之所以完全没效果,是因为在changeTextSize1方法里,你做了这个操作:
View view = (View) getLayoutInflater().inflate(R.layout.recycler_todo, null); TextView finalT = (TextView) view.findViewById(R.id.finalText); finalT.setTextSize(22);
你重新创建了一个全新的recycler_todo布局实例,这个View从来没有被添加到你的界面上,你修改的只是这个“孤立”的TextView,RecyclerView里正在显示的那些列表项根本没被碰过!
解决方案:通过Adapter统一更新RecyclerView的列表项
要实现点击设置后更新RecyclerView里的文本字号,得走这几步:
1. 保存字号设置(用SharedPreferences持久化)
在SettingActivity的changeTextSize1方法里,把选中的字号存起来,同时通知MainActivity去更新UI:
public void changeTextSize1(View v) { // 保留你原来的字体加粗逻辑 TextView ts1 = (TextView) findViewById(R.id.textsize1); TextView ts2 = (TextView) findViewById(R.id.textsize2); TextView ts3 = (TextView) findViewById(R.id.textsize3); ts1.setTypeface(ts1.getTypeface(), Typeface.BOLD); ts2.setTypeface(ts2.getTypeface(), Typeface.NORMAL); ts3.setTypeface(ts3.getTypeface(), Typeface.NORMAL); // 把字号保存到SharedPreferences,重启APP也能保留设置 SharedPreferences sp = getSharedPreferences("TextSizeSettings", MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putFloat("finalTextSize", 22f); // 这里设置你要的字号 editor.apply(); // 发送广播,通知MainActivity更新RecyclerView Intent updateIntent = new Intent("com.yourpackage.UPDATE_TEXT_SIZE"); sendBroadcast(updateIntent); }
注意把
com.yourpackage.UPDATE_TEXT_SIZE换成你自己APP的包名前缀,避免和其他APP的广播冲突。
2. 修改Adapter,让它支持动态更新字号
RecyclerView的所有列表项都是由Adapter管理的,所以要让Adapter能读取字号设置,并在绑定View时应用:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private ArrayList<TodoList> mDataset; private Context mContext; private float mCurrentTextSize; // 构造方法传入Context和数据 public MyAdapter(ArrayList<TodoList> myDataset, Context context) { mDataset = myDataset; mContext = context; // 初始化时读取保存的字号,默认16sp SharedPreferences sp = mContext.getSharedPreferences("TextSizeSettings", Context.MODE_PRIVATE); mCurrentTextSize = sp.getFloat("finalTextSize", 16f); } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { LinearLayout v = (LinearLayout) LayoutInflater.from(parent.getContext()) .inflate(R.layout.recycler_todo, parent, false); return new MyViewHolder(v); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { // 这里设置你的列表项文本内容,比如: // holder.finalText.setText(mDataset.get(position).getContent()); // 应用当前的字号设置 holder.finalText.setTextSize(TypedValue.COMPLEX_UNIT_SP, mCurrentTextSize); } // 提供一个方法,让外部通知Adapter更新字号并刷新列表 public void updateTextSize(float newSize) { mCurrentTextSize = newSize; notifyDataSetChanged(); // 刷新所有列表项 } @Override public int getItemCount() { return mDataset.size(); } // ViewHolder类,缓存列表项的View public static class MyViewHolder extends RecyclerView.ViewHolder { public TextView finalText; public MyViewHolder(LinearLayout v) { super(v); finalText = v.findViewById(R.id.finalText); } } }
3. 在MainActivity里接收广播,触发Adapter更新
MainActivity需要监听SettingActivity发来的广播,然后通知Adapter更新字号:
public class MainActivity extends AppCompatActivity { private MyAdapter mAdapter; private BroadcastReceiver mTextSizeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); RecyclerView recyclerView = findViewById(R.id.my_recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); // 初始化你的数据集 ArrayList<TodoList> dataset = new ArrayList<>(); // 这里填充你的数据,比如dataset.add(new TodoList("测试文本")); // 初始化Adapter mAdapter = new MyAdapter(dataset, this); recyclerView.setAdapter(mAdapter); // 注册广播接收器 IntentFilter filter = new IntentFilter("com.yourpackage.UPDATE_TEXT_SIZE"); mTextSizeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // 读取最新的字号设置,通知Adapter更新 SharedPreferences sp = getSharedPreferences("TextSizeSettings", MODE_PRIVATE); float newSize = sp.getFloat("finalTextSize", 16f); mAdapter.updateTextSize(newSize); } }; registerReceiver(mTextSizeReceiver, filter); } @Override protected void onDestroy() { super.onDestroy(); // 记得注销广播接收器,避免内存泄漏 unregisterReceiver(mTextSizeReceiver); } }
为什么要这么做?
- RecyclerView的列表项是Adapter动态生成的,你无法直接从另一个Activity去修改已经显示的列表项View。
- SharedPreferences用来持久化设置,确保用户下次打开APP时字号还是他们设置的大小。
- 广播是跨Activity传递更新通知的简单方式,你也可以用EventBus之类的库替代,但广播足够满足这个场景。
内容的提问来源于stack exchange,提问作者DongDong
相关产品推荐
相关产品推荐

