2015-09-08 8 views
8

Hauptproblem, dass meine LayoutInflater.Factory (Codebeispiel unten) ruft onCreateView und funktioniert gut mit "com.android.support:support-v4:22.0.0". Aber onCreateView wird nicht aufgerufen, wenn ich zu "com.android.support:support-v4:22.1.0" oder höher wechselte. Ich kann nicht verstehen warum?LayoutInflater.Factory onCreateView wird nicht mit 22.1+ Support-Bibliothek aufgerufen

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

Wofür wird 'cloneInContext' benötigt? was willst du eigentlich erreichen? – pskink

+0

Um einen neuen LayoutInflater mit einer zusätzlichen LayoutInflater.Factory für Ihre eigenen Ansichten zu erstellen, können Sie mit cloneInContext (Context) eine vorhandene ViewFactory klonen und dann setFactory (LayoutInflater.Factory) aufrufen, um Ihre Factory einzuschließen. – Ragaisis

+0

verwenden Sie Fragmente aus der Support-Bibliothek? Bist du sicher, dass Fragment # onCreateView aufgerufen wurde? – pskink

Antwort

2

Edited Antwort:

Um dieses Problem zu lösen wir LayoutInflaterCompat.setFactory verwenden sollten, die in Pre/Post-Lutscher mit LayoutInflater Fabrik hilft.

Dies ist Beispiel

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

akzeptierte Antwort für AppCompat v23, überprüfen Sie bitte Quellen sdk\sources\android-23\android\support\v4\view\LayoutInflaterCompatHC.java zu sehen, wie LayoutInflater.Factory Problem um in forceSetFactory2 Methode gearbeitet veraltet ist.