qqliu10u / QSkinLoader

一个支持多种场景的Android换肤框架。基本原理是通过代理LayoutInflater的View创建过程解析皮肤相关属性(background/src/textColor等),将皮肤相关属性设置到View的Tag内,在切换皮肤时寻找对应的皮肤来完成实时刷新动作。此方案具有代码及XML侵入性小、功能完善(支持Activity/Dialog/悬浮窗/PopWindow/Fragment等)、无需重启Activity、支持自定义属性换肤、同时支持资源内换肤和独立资源包(下载后换肤)等优点。接口按流式编程设计,个人感觉,比目前几种换肤框架好用一些。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

fragment怎么换皮肤

hujiachen822 opened this issue · comments

fragment怎么换皮肤

Fragment的换肤与其他View相同:

  1. 如果其内布局是XML,则对各View配置skin:enable="true";

  2. 如果是有动态创建的View则对动态创建的View应用皮肤SkinManager.getInstance().applySkin(convertView, true);

  3. 如果Fragment相对于Activity是延迟创建或初始化的,则在onViewCreated内调用SkinManager.getInstance().applySkin(convertView, true);

PS:对于一个Fragment对象,当它添加到View树后,其在View树内是透明的,它只是管理了一部分View的生命周期而已,所以换肤框架无需对Fragment进行特殊处理。

延迟创建的Fragment 使用上面的代码设定后换肤不生效,总是报错:

SkinLoader_SkinInflaterFactoryImpl: createView()| create view failed android.view.InflateException: Binary XML file line #3: Error inflating class <unknown> at android.view.LayoutInflater.createView(LayoutInflater.java:620) at org.qcode.qskinloader.impl.SkinInflaterFactoryImpl.createView(SkinInflaterFactoryImpl.java:84) at org.qcode.qskinloader.impl.SkinInflaterFactoryImpl.onCreateView(SkinInflaterFactoryImpl.java:46) at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:172) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:684) at android.view.LayoutInflater.inflate(LayoutInflater.java:469) at android.view.LayoutInflater.inflate(LayoutInflater.java:397)

追到框架代码里,发现是该处报错:

`
private View createView(Context context,
String name,
AttributeSet attrs) {
View view = null;
try {
LayoutInflater inflater = LayoutInflater.from(context);
if (-1 == name.indexOf('.')) {
if ("View".equals(name)) {
view = inflater.createView(
name, "android.view.", attrs);
}
if (view == null) {
view = inflater.createView(
name, "android.widget.", attrs);
}
if (view == null) {
view = inflater.createView(
name, "android.webkit.", attrs);
}
} else {
view = inflater.createView(name, null, attrs);
}

    } catch (Exception ex) {
        Logging.d(TAG, "createView()| create view failed", ex);
        view = null;
    }

    return view;
}`

该处代码执行时发生异常:
view = inflater.createView( name, "android.widget.", attrs);

@hujiachen822 没看到代码截图,请加我QQ 512174989,最近发现了一个bug,对于ViewStub内的view换肤,系统创建View会崩溃,你的xml里有没有ViewStub?

@gondole 方便贴下xml代码么?或者加我qq 512174989

感觉大大帮我处理问题。fragment换皮肤需要用
inflater.from(getActivity()).inflate(view, null);
而不是
inflater.inflate(view, null);

hujiachen822问题原因:系统里有很多LayoutInflater的实例,inflate布局xml文件时,尽量使用LayoutInflater.from(Context)的实例,避免使用方法内回调出来的inflater,这些回调出来的inflater可能没有注入Factory监听,所以不解析xml内的皮肤属性。

@qqliu10u @hujiachen822 使用LayoutInflater.from(getContext) 后,Fragment内的view可以正常换肤了,感谢。