Android:应用程序范围的字体大小首选项

时间:2011-02-02 16:41:28

标签: android preferences font-size

是否可以对显示文本的所有视图使用的font-size进行应用程序范围的设置? 我想为用户提供一个Preference,它应该允许缩放应用程序中的所有文本。

Android明确允许使用"sp" dimension unit来扩展文本,但是没有实际的方法来以全局方式设置“用户的字体大小首选项”。

迭代所有关于Activity实例化的视图实际上不是一个选项; - )

4 个答案:

答案 0 :(得分:48)

这就是我为我的应用程序制作它的方式。 简而言之 - 在Activity.onCreate()中,您可以获得具有特定字体大小的样式的资源ID,并将此样式应用于活动主题。然后使用首选项活动,您可以在这些集之间切换。

首先在values / attrs.xml中声明字体大小集的属性:

<declare-styleable name="FontStyle">
    <attr name="font_small" format="dimension" />
    <attr name="font_medium" format="dimension" />
    <attr name="font_large" format="dimension" />
    <attr name="font_xlarge" format="dimension" />
</declare-styleable>

然后在values / styles.xml中声明几组字体大小:

<style name="FontStyle">
</style>

<style name="FontStyle.Small">
    <item name="font_small">14sp</item>
    <item name="font_medium">16sp</item>
    <item name="font_large">18sp</item>
    <item name="font_xlarge">20sp</item>
</style>

<style name="FontStyle.Medium">
    <item name="font_small">18sp</item>
    <item name="font_medium">20sp</item>
    <item name="font_large">22sp</item>
    <item name="font_xlarge">24sp</item>
</style>

<style name="FontStyle.Large">
    <item name="font_small">26sp</item>
    <item name="font_medium">28sp</item>
    <item name="font_large">30sp</item>
    <item name="font_xlarge">32sp</item>
</style>

然后在每个活动的onCreate()方法中添加:

getTheme().applyStyle(new Preferences(this).getFontStyle().getResId(), true);

其中PreferencesSharedPreferences对象的外观:

public class Preferences {
    private final static String FONT_STYLE = "FONT_STYLE";

    private final Context context;

    public Preferences(Context context) {
        this.context = context;
    }

    protected SharedPreferences open() {
        return context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
    }

    protected Editor edit() {
        return open().edit();
    }

    public FontStyle getFontStyle() {
        return FontStyle.valueOf(open().getString(FONT_STYLE,
            FontStyle.Medium.name()));
    }

    public void setFontStyle(FontStyle style) {
        edit().putString(FONT_STYLE, style.name()).commit();
    }
}

和FontStyle是:

public enum FontStyle {
    Small(R.style.FontStyle_Small, "Small"), 
    Medium(R.style.FontStyle_Medium, "Medium"), 
    Large(R.style.FontStyle_Large, "Large");

    private int resId;
    private String title;

    public int getResId() {
        return resId;
    }

    public String getTitle() {
        return title;
    }

    FontStyle(int resId, String title) {
        this.resId = resId;
        this.title = title;
    }
}

FontStyle.values()用作SpinnerPreferencesActivity的项目。 这就是我的样子:

public class PreferencesActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    getTheme().applyStyle(new Preferences(this).getFontStyle().getResId(), true);
    super.onCreate(savedInstanceState);

    setContentView(R.layout.preferences);

    Preferences prefs = new Preferences(this);

    Spinner fontStylesView = (Spinner) findViewById(R.id.font_styles);
    FontStylesAdapter adapter = new FontStylesAdapter(this,
            R.layout.font_styles_row, FontStyle.values());
    fontStylesView.setAdapter(adapter);

    fontStylesView.setSelection(prefs.getFontStyle().ordinal());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.preferences, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_done:
        onMenuDone();
        finish();
        return true;
    case R.id.menu_cancel:
        finish();
        return true;
    default:
        return false;
    }
}

private void onMenuDone() {
    Preferences prefs = new Preferences(this);

    Spinner fontStylesView = (Spinner) findViewById(R.id.font_styles);
    prefs.setFontStyle((FontStyle) fontStylesView.getSelectedItem());
}
}

最后,您可以使用字体大小首选项:

<TextView android:textSize="?attr/font_large" />

或者我更喜欢使用样式,在values / styles.xml中添加:

<style name="Label" parent="@android:style/Widget.TextView">
    <item name="android:textSize">?attr/font_medium</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
</style>

<style name="Label.XLarge">
    <item name="android:textSize">?attr/font_xlarge</item>
</style>

你可以这样使用它:

<TextView style="@style/Label.XLarge" />

我希望我的回答会对你有帮助。

答案 1 :(得分:5)

是的,这是可能的。要做到这一点,你需要:

  1. 声明您自己的类TextView
  2. 用于所有对话/活动 只有它
  3. 像:

    public class SimpleTextView extends TextView
    {
        private static final float DEFAULT_TEXT_SIZE=12.0;
        private static float textSize=DEFAULT_TEXT_SIZE;
    
        public SimpleTextView(Context context)
        {
            super(context);
            this.setTextSize(textSize);
        }
    
        public SimpleTextView(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            this.setTextSize(textSize);
        }
    
        public SimpleTextView(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
            this.setTextSize(textSize);
        }
    
        public static void setGlobalSize(float size)
        {
            textSize=size;
        }
    
        public static float getGlobalSize()
        {
            return textSize;
        }
    }
    

    现在,无论您是谁,您都可以在所有文字视图中全局将所有文字大小更改为20,只需致电:

    SimpleTextView.setGlobalTextSize(20);
    

答案 2 :(得分:1)

从臀部拍摄这个想法(不需要自定义TextView实现)

  1. 声明类似UNIVERSAL_FONT_SIZE的属性,并认为它可以从设置更改,但会在应用程序调用之间保留
  2. 在每个活动的onCreate方法中获取该属性的值并另存为字段
  3. 使代码对每个可调整文本的组件使用该代码
  4. 实际上没有什么能阻止你创建几个属性,如BUTTONS_TXT_SIZE,TEXT_SIZE,LIST_TXT_SIZE等,然后有逻辑,例如文本的百分比增加,并为每种类型的控件计算适当的大小(因为你可能有不同的大小对于不同的控制)
  5. 同样,你想让它动态地运作吗?创建一个包含内部列表的简单类(比如TextSetter),它有3个方法:add,remove和setSize

    1. Activity#onCreate中标识您要调整的每个控件,并使用TextSetter#set将其添加到列表中
    2. 当用户想要从菜单中增加/减少字体大小时,当你处理它时只需执行TextSetter#setSize,你将遍历控件列表,检测它是什么类型并相应地调整文本大小

答案 3 :(得分:0)

对于那些使用@mixels回答的自定义属性来扩充视图有问题的人。

如果你的观点是片段,你需要在片段的onCreateView()中应用FontStyle或在应用程序的主题中设置这些属性的值。

有关详细信息,请参阅我的aswer here