无碎片定制查看自定义XML属性 [英] Custom XML attributes without custom View in Fragment

查看:211
本文介绍了无碎片定制查看自定义XML属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想添加自定义XML属性

I'm trying to add custom XML attributes in existing View

将它们添加到自定义视图不是什么大不了的事,但我不知道如何访问这些属性中的基本视图(如TextView的,LinearLayout中,ImageView的...)

Adding them to a custom View is not a big deal but I don't know how to access those attributes in a "basic" View (e.g. TextView, LinearLayout, ImageView ...)

这是比较困难时,有碎片和/或参与图书馆项目

And this is more difficult when there are Fragment and / or Library project involved

到目前为止,这是我的code

So far here is my code

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

Customs attributes definitions and XML (attrs.xml and the layout):

<?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自定义属性的唯一方法是:

Since I inflate this on an Fragment (so no onCreate with attrs arg !), the only way to try to get the 2 sw custom attributes is to :

  1. 设置自定义LayoutInflater.Factory的片段LayoutInflater在onCreateView

  1. Set a custom LayoutInflater.Factory to the Fragment LayoutInflater in 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:

  • Trying to get the custom attributes on the custom LayoutInflater.Factory :

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

  • 任何人有过这样的问题?

    Anyone have had this kind of question ?

    什么,我在这里失踪?

    THX提前!

    推荐答案

    我终于做到了这一点:)

    I have finally done this :)

    您必须创建一个新的 LayoutInflater.Factory 像我一样在OP但由于工厂被用于所有的充气布局来看,你必须返回null在 Factory.onCreateView (让机器人处理通货膨胀),则必须在某处缓存您的自定义XML attibutes

    You have to create a new LayoutInflater.Factory as I did on the OP but since the Factory is used for all the inflated layout View, and you have to return null on your Factory.onCreateView (to let Android handle the inflation) you must cache your custom XML attibutes somewhere

    因此​​,这里的解决方案:

    So here the solution :

    • 您的布局XML视图必须和android:ID

    • Your layout XML View must have and android:id

    创建,这将使您的自定义类的属性:

    Create the class which will keep your custom attributes :

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

      这篇关于无碎片定制查看自定义XML属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆