Как накачать представление с помощью пользовательских значений атрибутов?

Как мне установить значения в моем View программно, что он может использовать в onCreate()? Атрибуты могут быть установлены только в XML, а значения элементов могут быть установлены только после View раздувается (и onCreate() уже звонил).

Мне нужно позвонить View конструктор и установить значения членов, прежде чем его раздувать? Или есть лучший способ?

1 ответ

Если вы надуете вид с помощью Context.getLayoutInflater().createView()Вы можете передавать пользовательские атрибуты в это представление программно, используя последний параметр

РЕДАКТИРОВАТЬ

Чтобы использовать атрибуты как из XML, так и программно, вам нужно будет реализовать собственный LayoutInflater. Тем не менее, так как

Вы можете увидеть пример пользовательского макета в Android Rec Library.

Вы можете увидеть пример пользовательского AttributeSet в этом ответе SO.

Пользовательский 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(...)
    }

Это может сработать, но, возможно, есть лучший способ добиться того, чего вы хотите.

Добавить пользовательские параметры

Вы можете реализовать собственный макет раскладки, который будет устанавливать некоторые параметры перед возвратом представления, поэтому они будут добавлены до 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(...)
}
Другие вопросы по тегам