android全局替换字体最新方案

来源:互联网 发布:手机桌面特效软件 编辑:程序博客网 时间:2024/05/29 01:52

github上有一个Calligraphy库,这个库可以用来替换字体。核心代码就是CalligraphyLayoutInflater,它继承默认LayoutInflater并且取代默认inflater来渲染整个图层。当你设置好了字体以后自然就会用新字体来渲染文字。但问题是,现在这个库只能实现一开始加载的时候渲染文字,那如果我正在一个Activity里面操作,里面有viewpager,fragment等一大堆组件,然后我切换进设置,在设置里面修改字体再返回这个Activity,此时Activity并没有经历销毁重新生成的过程,所以新字体无法自动应用上去,那怎么办呢?我们可以这么办

(1)配置Calligraphy库

这一步可以解决在新生成的,或者销毁再生成的Activity里面的字体的变化。剩下的就是已经存在的Activity的组件,包括ListView等有缓存机制的
参考:http://www.jianshu.com/p/5d4e6ae8ba4e

(2)遍历修改

对于原生,自定义控件采用遍历修改的方法(还剩下ListView和ViewPager等有缓存机制的组件)

/**     * 遍历修改字体     * @param root 根目录,一般就是最顶层的LinearLayout     */    private void Traversal(ViewGroup root) {        for (int i = 0; i < root.getChildCount(); i++) {            View view = root.getChildAt(i);            if (view instanceof ViewGroup) {                Traversal((ViewGroup) view);            } else {                String componentName = view.getClass().toString();                Log.e("name", componentName);                checkForChange(view);            }        }    }    private void checkForChange(View view) {        if (view instanceof TextView) {            ((TextView) view).setTypeface(mTypeface);        }        if (view instanceof Button) {            ((Button) view).setTypeface(mTypeface);        }        if (view instanceof EditText) {            ((EditText) view).setTypeface(mTypeface);        }        if (view instanceof AutoCompleteTextView) {            ((AutoCompleteTextView) view).setTypeface(mTypeface);        }        if (view instanceof MultiAutoCompleteTextView) {            ((MultiAutoCompleteTextView) view).setTypeface(mTypeface);        }        if (view instanceof CheckBox) {            ((CheckBox) view).setTypeface(mTypeface);        }        if (view instanceof RadioButton) {            ((RadioButton) view).setTypeface(mTypeface);        }        if (view instanceof ToggleButton) {            ((ToggleButton) view).setTypeface(mTypeface);        }        if (view instanceof AppCompatTextView) {            ((AppCompatTextView) view).setTypeface(mTypeface);        }        if (view instanceof AppCompatButton) {            ((AppCompatButton) view).setTypeface(mTypeface);        }        if (view instanceof AppCompatEditText) {            ((AppCompatEditText) view).setTypeface(mTypeface);        }        if (view instanceof AppCompatAutoCompleteTextView) {            ((AppCompatAutoCompleteTextView) view).setTypeface(mTypeface);        }        if (view instanceof AutoCompleteTextView) {            ((AutoCompleteTextView) view).setTypeface(mTypeface);        }        if (view instanceof AppCompatCheckBox) {            ((AppCompatCheckBox) view).setTypeface(mTypeface);        }        if (view instanceof AppCompatRadioButton) {            ((AppCompatRadioButton) view).setTypeface(mTypeface);        }        if (view instanceof AppCompatCheckedTextView) {            ((AppCompatCheckedTextView) view).setTypeface(mTypeface);        }    }

(3)ListView更新字体

在getView函数中调用如下函数,然后在外部调用notifyDataSetChanged刷新

private void updateTypeFace() {        if (mTypeface == null) {            TypeFaceApplication application = (TypeFaceApplication) ((Activity) mContext).getApplication();            path = application.getCurrentAssetsPath();            mTypeface = Typeface.createFromAsset(mContext.getAssets(), path);        } else {            TypeFaceApplication application = (TypeFaceApplication) ((Activity) mContext).getApplication();            String currentPath = application.getCurrentAssetsPath();            if (!currentPath.equals(path)) {                path = currentPath;                mTypeface = Typeface.createFromAsset(mContext.getAssets(), currentPath);            }        }    }

(4)ViewPager

在Fragment的setUserVisibleHint中刷新ListView,一般性的控件已经由之前的遍历Traversal完成

最后贴一下Application的代码

public class TypeFaceApplication extends Application {    private String assetsPath = "fonts/songti.TTF";    @Override    public void onCreate() {        super.onCreate();        CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()                .setDefaultFontPath(assetsPath)                .setFontAttrId(R.attr.fontPath)                .build());    }    public void change(String assetsPath) {        this.assetsPath = assetsPath;        CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()                .setDefaultFontPath(assetsPath)                .setFontAttrId(R.attr.fontPath)                .build());    }    public String getCurrentAssetsPath() {        return assetsPath;    }}
原创粉丝点击