LayoutInflater.Factory onCreateView 不使用 22.1+ 支持库调用
Posted
技术标签:
【中文标题】LayoutInflater.Factory onCreateView 不使用 22.1+ 支持库调用【英文标题】:LayoutInflater.Factory onCreateView is not called with 22.1+ support library 【发布时间】:2015-12-03 17:18:15 【问题描述】:我的LayoutInflater.Factory
(下面的代码示例)调用onCreateView
并与“com.android.support:support-v4:22.0.0”一起正常工作的主要问题。但是当我移动到 'com.android.support:support-v4:22.1.0' 或更高版本时,不会调用 onCreateView
。我不明白为什么?
//From many fragments i Call hintManager.inflate
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup viewGroup, Bundle savedInstanceState)
layout = hintManager.inflate(inflater, R.layout.generate_code);
...
//here is HintManager method called from various fragments.
public View inflate(LayoutInflater inflater, int layoutResourceId)
AttributeParser attributeParser = new AttributeParser();
LayoutInflater layoutInflater = attributeParser.getLayoutInflater(inflater);
final View v = layoutInflater.inflate(layoutResourceId, null);
//here AttributeParserFactory#onCreateView should be called, but it fails with 22.1+ support lib, but works with 22.0
attributeParser.setViewAttribute(v);
return v;
...
//example of factory, that works fine with 22.0 support lib
private Map<Integer, HashMap<Integer, String>> helpViewList;
private class AttributeParser
private AttributeParserFactory mFactory;
private class AttributeParserFactory implements LayoutInflater.Factory
@Override
public View onCreateView(String name, Context context, AttributeSet attrs)
String id = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "id");
if(id != null)
// String with the reference character "@", so we strip it to keep only the reference
id = id.replace("@", "");
TypedArray libraryStyledAttributeList = context.obtainStyledAttributes(attrs, R.styleable.Help);
HashMap<Integer, String> libraryViewAttribute = new HashMap<Integer, String>();
int i = 0;
for(int attribute : R.styleable.Help)
String attributeValue = null;
if (attribute == R.styleable.Help_arrow || attribute == R.styleable.Help_padding)
attributeValue = String.valueOf(libraryStyledAttributeList.getInteger(i, 0));
else
attributeValue = libraryStyledAttributeList.getString(i);
if(attributeValue != null)
libraryViewAttribute.put(attribute, attributeValue);
i++;
if(!libraryViewAttribute.isEmpty())
helpViewList.put(Integer.valueOf(id), libraryViewAttribute);
libraryStyledAttributeList.recycle();
return null;
public AttributeParser()
mFactory = new AttributeParserFactory();
public void clear()
helpViewList.clear();
public LayoutInflater getLayoutInflater(LayoutInflater inflater)
LayoutInflater layoutInflater = inflater.cloneInContext(inflater.getContext());
layoutInflater.setFactory(mFactory);
return layoutInflater;
public void setFactory(LayoutInflater inflater)
inflater.cloneInContext(inflater.getContext()).setFactory(mFactory);
public void setViewAttribute(Activity activity)
for(Map.Entry<Integer, HashMap<Integer, String>> attribute : helpViewList.entrySet())
if(activity.findViewById((Integer) attribute.getKey()) != null)
activity.findViewById((Integer) attribute.getKey()).setTag(attribute.getValue());
public void setViewAttribute(View view)
for(Map.Entry<Integer, HashMap<Integer, String>> attribute : helpViewList.entrySet())
if(view.findViewById((Integer) attribute.getKey()) != null)
view.findViewById((Integer) attribute.getKey()).setTag(attribute.getValue());
public Map<Integer, HashMap<Integer, String>> getAttributeList()
return helpViewList;
public void setAttributeList(Map<Integer, HashMap<Integer, String>> attributeList)
helpViewList = attributeList;
【问题讨论】:
cloneInContext
要求什么?你到底想达到什么目标?
要为您自己的视图创建一个带有附加 LayoutInflater.Factory 的新 LayoutInflater,您可以使用 cloneInContext(Context) 克隆现有的 ViewFactory,然后在其上调用 setFactory(LayoutInflater.Factory) 以包含你的工厂。
您是否使用支持库中的片段?你确定 Fragment#onCreateView 被调用了吗?
你必须有适当的来源(与 buildToolsVersion 相同的版本)
如果您尝试使用支持库,为什么不使用LayoutInflaterCompat
和LayoutInflaterFactory
而不是LayoutInflater.Factory
?
【参考方案1】:
修改后的答案:
为了解决这个问题,我们应该使用 LayoutInflaterCompat.setFactory,它有助于在 Lollipop 前后使用 LayoutInflater Factory。
这是一个例子
LayoutInflater layoutInflaterCopy = inflater.cloneInContext(inflater.getContext());
LayoutInflaterCompat.setFactory(layoutInflaterCopy, new LayoutInflaterFactory()
@Override
public View onCreateView(View parent, String name, Context context, AttributeSet attrs)
String id = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "id");
if(id != null)
// String with the reference character "@", so we strip it to keep only the reference
id = id.replace("@", "");
TypedArray libraryStyledAttributeList = context.obtainStyledAttributes(attrs, R.styleable.Help);
HashMap<Integer, String> libraryViewAttribute = new HashMap<Integer, String>();
int i = 0;
for(int attribute : R.styleable.Help)
String attributeValue = null;
if (attribute == R.styleable.Help_arrow || attribute == R.styleable.Help_padding)
attributeValue = String.valueOf(libraryStyledAttributeList.getInteger(i, 0));
else
attributeValue = libraryStyledAttributeList.getString(i);
if(attributeValue != null)
libraryViewAttribute.put(attribute, attributeValue);
i++;
if(!libraryViewAttribute.isEmpty())
helpViewList.put(Integer.valueOf(id), libraryViewAttribute);
libraryStyledAttributeList.recycle();
return null;
);
final View v = layoutInflaterCopy.inflate(layoutResourceId, null);
【讨论】:
【参考方案2】:AppCompat v23 已接受的答案已过时,请查看sdk\sources\android-23\android\support\v4\view\LayoutInflaterCompatHC.java
的来源,了解LayoutInflater.Factory
问题在forceSetFactory2
方法中是如何解决的。
【讨论】:
以上是关于LayoutInflater.Factory onCreateView 不使用 22.1+ 支持库调用的主要内容,如果未能解决你的问题,请参考以下文章
[_], ... .?- length(X,N), path( state(on(c,on(b,on(a,void))), void, void), state(void, void, on(c,on