如何使用自定义属性值对视图进行充气?

时间:2018-01-18 04:12:47

标签: android android-view android-attributes

如何以编程方式在View中设置可在onCreate()中使用的值?属性只能在XML中设置,成员值只能在View被夸大(并且onCreate()已被调用)之后设置。

在充气之前,是否需要调用View构造函数并设置成员值?或者有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

如果使用Context.getLayoutInflater().createView()使视图膨胀,则可以使用最后一个参数以编程方式将自定义属性传递给此视图

修改

为了以编程方式使用xml中的属性,您必须实现自定义LayoutInflater。但是,因为

您可以看到自定义布局In Android Rec Library的示例。

您可以在此SO answer中看到自定义AttributeSet的示例。

自定义AttriuteSet

如果我结合所有这些答案,你会得到你想要的东西,但它需要一些样板代码,因为AttributeSet不适合动态添加参数。因此,您必须实现AttributeSet(这是一个接口),它在构造函数中获取原始AttributeSet,并包装其所有功能,并以编程方式返回要添加的参数的正确值。

然后你就可以做类似的事情:

private static class MyLayoutInflater implements LayoutInflater.Factory {

        private LayoutInflater other;

        MyLayoutInflater(LayoutInflater other) {
            this.other = other;
        }

        @Override
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            if (name.equals("MyView")) {
                attrs = MyAttributeSet(attrs);
            }
            try {
                return other.createView(name, "", attrs);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();

            }
        }
    }

    private static class MyAttributeSet implements AttributeSet {

        private AttributeSet other;

        MyAttributeSet(AttributeSet other) {
            this.other = other;
        }

        < More implementations ...>
    }

    @Override
    protected void onCreate(Bundle savedInstanceState){
        getLayoutInflater().setFactory(new MyLayoutInflater(getLayoutInflater());
        getLayoutInflater().inflate(...)
    }

它可能有用,但可能有更好的方法来实现你想要的。

添加自定义参数

您可以实现自定义layoutinflater,它将在返回视图之前设置一些参数,因此将在视图上调用onCreate之前添加这些参数。所以它会是这样的:

@Override
protected void onCreate(Bundle savedInstanceState){
    getLayoutInflater().setFactory(new LayoutInflater.Factory() {
        public View onCreateView(String name, Context context, AttributeSet attrs) {
            if (name.equals("MyView")) {
                View myView = myView(context, attrs); // To get properties from attrs
                myView.setCustomParams(SomeCustomParam);
                return myView;
            } else {
                return null;
            }
        }
    });
    getLayoutInflater().inflate(...)
}