2015-09-08 1 views
8

Problème principal que mon LayoutInflater.Factory (exemple de code ci-dessous) appelle onCreateView et fonctionne correctement avec 'com.android.support:support-v4:22.0.0'. Mais onCreateView n'est pas appelée lorsque je suis passé à 'com.android.support:support-v4:22.1.0' ou supérieur. Je ne peux pas comprendre pourquoi?LayoutInflater.Factory onCreateView n'est pas appelé avec la bibliothèque de support 22.1+

//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; 
    } 

} 
+0

À quoi sert 'cloneInContext'? que voulez-vous réellement accomplir? – pskink

+0

Pour créer un nouvel objet LayoutInflater avec un LayoutInflater.Factory supplémentaire pour vos propres vues, vous pouvez utiliser cloneInContext (Context) pour cloner un objet ViewFactory existant, puis appeler setFactory (LayoutInflater.Factory) pour y inclure votre Factory. – Ragaisis

+0

utilisez-vous des fragments de la bibliothèque de support? Êtes-vous sûr que Fragment # onCreateView a été appelé? – pskink

Répondre

2

Edité réponse:

Pour résoudre ce problème, nous devrions utiliser LayoutInflaterCompat.setFactory qui aide à LayoutInflater usine en pré/post Lollipop.

C'est par exemple

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); 
0

réponse acceptée est obsolète pour AppCompat v23, s'il vous plaît vérifier les sources de sdk\sources\android-23\android\support\v4\view\LayoutInflaterCompatHC.java pour voir comment est question LayoutInflater.Factory travaillé autour de la méthode forceSetFactory2.