问询:通过Spinner选项从Asset文件夹设置自定义字体的实现方法
实现Spinner字体切换(含自定义Asset字体)
嘿,我来帮你搞定这个Spinner切换字体的需求!结合你的代码片段,我们可以分几步来实现:
1. 准备工作:确认字体文件位置
确保你的Comic_Sans_Reg.ttf放在assets/fonts/目录下(如果没有fonts文件夹就新建一个),这样加载路径会是"fonts/Comic_Sans_Reg.ttf"。
2. 自定义Spinner适配器,让下拉选项显示对应字体样式
默认的ArrayAdapter没法直接修改字体,所以我们需要自定义一个Adapter,重写getView和getDropDownView方法,让每个选项显示对应的字体效果:
public class FontSpinnerAdapter extends ArrayAdapter<String> { private Context mContext; private List<String> mFontNames; // 缓存Typeface避免重复加载,减少内存占用 private HashMap<String, Typeface> mTypefaceCache = new HashMap<>(); public FontSpinnerAdapter(Context context, int resource, List<String> objects) { super(context, resource, objects); mContext = context; mFontNames = objects; // 提前加载所有需要的字体到缓存 initTypefaceCache(); } private void initTypefaceCache() { mTypefaceCache.put("Monospace", Typeface.MONOSPACE); mTypefaceCache.put("Sans Serif", Typeface.SANS_SERIF); mTypefaceCache.put("Serif", Typeface.SERIF); mTypefaceCache.put("Bold", Typeface.DEFAULT_BOLD); mTypefaceCache.put("Italic", Typeface.create(Typeface.DEFAULT, Typeface.ITALIC)); // 加载Asset中的Comic字体,捕获异常避免崩溃 try { Typeface comicFont = Typeface.createFromAsset(mContext.getAssets(), "fonts/Comic_Sans_Reg.ttf"); mTypefaceCache.put("Comic", comicFont); } catch (Exception e) { e.printStackTrace(); // 加载失败时 fallback 到默认字体 mTypefaceCache.put("Comic", Typeface.DEFAULT); } } @Override public View getView(int position, View convertView, ViewGroup parent) { return getStyledTextView(position, convertView, parent); } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { return getStyledTextView(position, convertView, parent); } private View getStyledTextView(int position, View convertView, ViewGroup parent) { TextView textView; // 复用View优化性能 if (convertView == null) { LayoutInflater inflater = LayoutInflater.from(mContext); textView = (TextView) inflater.inflate(android.R.layout.simple_spinner_item, parent, false); } else { textView = (TextView) convertView; } String fontName = mFontNames.get(position); textView.setText(fontName); // 设置对应的字体样式 Typeface typeface = mTypefaceCache.get(fontName); if (typeface != null) { textView.setTypeface(typeface); } return textView; } }
3. 替换原Spinner适配器,设置选中监听切换字体
在你的Activity/Fragment里,把原来的ArrayAdapter替换成我们自定义的FontSpinnerAdapter,然后通过选中监听切换目标文本的字体:
// 你的原有代码 Typeface currentFontStyle = Typeface.DEFAULT; Spinner spinner = (Spinner) findViewById(R.id.fontSpinner); List<String> categories = new ArrayList<String>(); categories.add("Monospace"); categories.add("Sans Serif"); categories.add("Serif"); categories.add("Bold"); categories.add("Italic"); categories.add("Comic"); // 替换为自定义适配器 FontSpinnerAdapter adapter = new FontSpinnerAdapter(this, android.R.layout.simple_spinner_item, categories); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); // 假设你要切换字体的目标TextView TextView targetTextView = findViewById(R.id.target_text); // 设置Spinner选中监听 spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { String selectedFont = categories.get(position); // 从适配器的缓存中获取字体 Typeface selectedTypeface = ((FontSpinnerAdapter) parent.getAdapter()).mTypefaceCache.get(selectedFont); if (selectedTypeface != null) { currentFontStyle = selectedTypeface; targetTextView.setTypeface(currentFontStyle); } } @Override public void onNothingSelected(AdapterView<?> parent) { // 未选中时恢复默认字体 targetTextView.setTypeface(Typeface.DEFAULT); } });
小提示
- 缓存Typeface很重要,重复调用
createFromAsset会浪费内存; - 一定要捕获字体加载异常,避免因为字体文件损坏或路径错误导致崩溃;
- 如果你的Spinner使用了自定义布局,只需要修改
getStyledTextView里的布局加载代码即可。
内容的提问来源于stack exchange,提问作者Robby Ali Darmawan
相关产品推荐
相关产品推荐

