自定义XML属性,没有自定义View in Fragment

我正在尝试在现有View中添加自定义XML属性

将它们添加到自定义视图并不是一件大事,但我不知道如何在“基本”视图中访问这些属性(例如TextView,LinearLayout,ImageView ……)

当涉及片段和/或图书馆项目时,这将更加困难

到目前为止,这是我的代码

海关属性定义和XML(attrs.xml和布局):

      

    

由于我在片段上对此进行了充气(因此没有onCreate与attrs arg!),尝试获取2个sw自定义属性的唯一方法是:

  1. 将自定义LayoutInflater.Factory设置为onCreateView中的Fragment LayoutInflater

     @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); LayoutInflater layoutInflater = inflater.cloneInContext(inflater.getContext()); layoutInflater.setFactory(new StarWarsLayoutFactory()); View fragmentView = layoutInflater.inflate(R.layout.jedi, container, false); ((TextView) fragmentView.findViewById(android.R.id.jedi)).setText("Yep"); return fragmentView; } 
  2. 尝试在自定义LayoutInflater.Factory上获取自定义属性:

     public class StarWarsLayoutFactory implements Factory { @Override public View onCreateView(String name, Context context, AttributeSet attrs) { *** What to do here ? *** return null; } } 

有人有过这样的问题吗?

我在这里缺少什么?

Thx提前!

我终于完成了这个:)

你必须像在OP上那样创建一个新的LayoutInflater.Factory ,但由于Factory用于所有膨胀的布局View,你必须在Factory.onCreateView上返回null(让Android处理通货膨胀)你必须缓存您的自定义XML属性

所以这里解决方案:

  • 您的布局XML View必须具有和android:id

  • 创建将保留自定义属性的类:

  public class AttributeParser { private AttributeParserFactory mFactory; private Map> mAttributeList; 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.NewsHubLibrary); HashMap libraryViewAttribute = new HashMap(); int i = 0; for(int attribute : R.styleable.NewsHubLibrary){ String attributeValue = libraryStyledAttributeList.getString(i); if(attributeValue != null) libraryViewAttribute.put(attribute, attributeValue); i++; } if(!libraryViewAttribute.isEmpty()) mAttributeList.put(Integer.valueOf(id), libraryViewAttribute); libraryStyledAttributeList.recycle(); } return null; } } public AttributeParser(){ mAttributeList = new HashMap>(); mFactory = new AttributeParserFactory(); } public void clear() { mAttributeList.clear(); } public LayoutInflater getLayoutInflater(LayoutInflater inflater) { clear(); 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(Entry> attribute : mAttributeList.entrySet()) if(activity.findViewById((Integer) attribute.getKey()) != null) activity.findViewById((Integer) attribute.getKey()).setTag(attribute.getValue()); } public void setViewAttribute(View view) { for(Entry> attribute : mAttributeList.entrySet()) if(view.findViewById((Integer) attribute.getKey()) != null) view.findViewById((Integer) attribute.getKey()).setTag(attribute.getValue()); } public Map> getAttributeList() { return mAttributeList; } public void setAttributeList(Map> attributeList) { this.mAttributeList = attributeList; } } 
  • 使用AttributeParser时,您的自定义属性将存储在每个View标记中:

  LayoutInflater layoutInflater = mAttributeParser.getLayoutInflater(inflater); View view = layoutInflater.inflate(R.layout.jedi, null); mAttributeParser.setViewAttribute(view); 

标准TextView等不会访问这些属性。 您可以扩展它并提供包括读取这些自定义属性的function。

 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.StarWars, 0, 0); String jedi = a.getText(R.styleable.StarWars_jedi); String rank = a.getText(R.styleable.StarWars_rank); a.recycle(); 

记得总是在最后调用recycle()