android - 22.1+ 支持库不调用 LayoutInflater.Factory onCreateView

标签 android factory layout-inflater

我的 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;
    }

}

最佳答案

编辑后的答案:

要解决这个问题,我们应该使用 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);

关于android - 22.1+ 支持库不调用 LayoutInflater.Factory onCreateView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32450723/

相关文章:

java - 在Android中创建以/结尾的目录

java - Android 更新每个操作的值总和

android - 网页上的图像在 Android 8/9 上的 Chrome 78 上不可见(但在 Chrome 76 和 Android 10 上工作)——可能是什么问题?

c# - 使用Autofac切换一个抽象工厂的具体实现

java - 在 Java 中创建不依赖 if-else 的工厂方法

android - 如何存储 Android 对话框中的编辑文本数据?

java - 在此代码示例中,AssetManager 类成员是否会被 JVM 垃圾回收?

javascript - 使用两个工厂 AngularJS

android - 无法在 editText 上打开键盘

android - 在所有现有 child 之上用新 child inflatedView