我想添加自定义XML在现有的视图属性
将它们添加到自定义视图是不是一个大问题,但我不知道如何访问“基本”查看的属性(如TextView的,LinearLayout中,ImageView的...)
这是比较困难时,有碎片和/或库项目参与
到目前为止,这里是我的代码
海关属性的定义和XML(attrs.xml和布局):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="StarWars">
<attr name="jedi" format="string" />
<attr name="rank" format="string" />
</declare-styleable>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sw="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="28dp"
android:gravity="center_horizontal"
sw:jedi="Obiwan" />
<TextView
android:id="@+id/rank"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="28dp"
android:gravity="center_horizontal"
sw:rank="Master" />
因为我这个膨胀上的片段(!所以没有用的onCreate ATTRS ARG),要尽量拿到2 SW自定义属性的唯一方法是:
设置自定义LayoutInflater.Factory的片段LayoutInflater在onCreateView
@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; }
试图让自定义LayoutInflater.Factory的自定义属性:
public class StarWarsLayoutFactory implements Factory { @Override public View onCreateView(String name, Context context, AttributeSet attrs) { *** What to do here ? *** return null; } }
任何人有过这样的问题?
什么我在这里失踪?
Thx提前!
我终于做到了这一点:)
你必须创建一个新的LayoutInflater.Factory
像我一样在OP但由于工厂用于所有膨胀的布局来看,你必须返回你的空Factory.onCreateView
(允许Android处理通货膨胀),则必须缓存您的自定义XML attibutes某处
所以这里的解决方案:
您的布局XML查看必须和android:ID
创建一个将让您的自定义属性的类:
public class AttributeParser {
private AttributeParserFactory mFactory;
private Map<Integer, HashMap<Integer, String>> 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<Integer, String> libraryViewAttribute = new HashMap<Integer, String>();
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<Integer, HashMap<Integer, String>>();
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<Integer, HashMap<Integer, String>> 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<Integer, HashMap<Integer, String>> attribute : mAttributeList.entrySet())
if(view.findViewById((Integer) attribute.getKey()) != null)
view.findViewById((Integer) attribute.getKey()).setTag(attribute.getValue());
}
public Map<Integer, HashMap<Integer, String>> getAttributeList() {
return mAttributeList;
}
public void setAttributeList(Map<Integer, HashMap<Integer, String>> attributeList) {
this.mAttributeList = attributeList;
}
}
- 您的自定义属性将被存储在每个浏览标签,当你使用AttributeParser:
LayoutInflater layoutInflater = mAttributeParser.getLayoutInflater(inflater);
View view = layoutInflater.inflate(R.layout.jedi, null);
mAttributeParser.setViewAttribute(view);
标准TextView
并且这样将无法访问这些属性。 你虽然可以扩展它提供的功能,包括读取这些自定义属性。
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()
结尾。