Почему так сложно установить стиль из кода на Android?

Если вы хотите установить стиль кнопки, которую вы создаете из кода, вам нужно сделать что-то вроде этого;

Button btn = new Button (mActivity, null, R.attr.someattribute); 

в attrs.xml вы создали ссылку

  

В styles.xml вы определяете тему

   @style/someStyle   

То, что укладывается в styles.xml, определяется как, например

  2px fill_parent @drawable/actionbar_compat_separator  

Это работает, и это, по моему мнению, способ установить стиль в режиме просмотра с кода на Android. Это кажется слишком сложным. Третий конструктор кнопки Argument мог легко принять идентификатор стиля R.style.XXX

Может ли кто-нибудь объяснить, зачем нужна эта дополнительная сложность?

Это связано с поощрением шаблонов в Android вокруг использования Views. Это не предполагаемый подход к тому, как он выглядит, как вы пытаетесь сделать. Сначала я объясню, для чего этот механизм, а затем предложим подход для вашего приложения.

Третий аргумент конструктора View, который принимает ресурс attr, обычно используется при реализации подclassов вида и, как вы показали, позволяет указать атрибут темы для использования в качестве ссылки на стиль по умолчанию для представления. Если у вас была специальная кнопка AwesomeButton, вы можете реализовать ее конструкторы следующим образом:

 public class AwesomeButton extends Button { public AwesomeButton(Context context) { this(context, null); } public AwesomeButton(Context context, AttributeSet attrs) { this(context, attrs, R.attr.awesomeButtonStyle); } public AwesomeButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr) { final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AwesomeButton, defStyleAttr, 0); // Read AwesomeButton-specific style attributes from a a.recycle(); } // More code } 

Когда LayoutInflater Android раздувает представления, он использует конструктор с двумя аргументами с аргументами (Context, AttributeSet) . Константа R.attr передается в 3-аргументную версию, а затем до 3-аргументного конструктора Button супервызове. Это означает, что Button будет читать информацию о стилизации по умолчанию для вещей, которые она инкапсулирует из AwesomeButton умолчанию AwesomeButton как указано в вашей теме. Некоторые представления в Android отличаются от их суперclassа только в стиле по умолчанию, который они используют. ( Button на самом деле одна из них.)

Вы указываете android:layout_width и android:layout_height в своем стиле, но это может быть проблематично. LayoutParams (любой атрибут, начинающийся с layout_ ) специфичны для родительского представления, а не для вида, в котором они отображаются. Вот почему вы всегда передаете предполагаемое родительское представление в качестве второго параметра в LayoutInflater#inflate – он сообщает надувателю, какой class должен отвечать за интерпретацию LayoutParams . Если вы пропустите это, вы часто обнаружите, что ваши LayoutParams не ведут себя так, как вы ожидаете, и часто игнорируются напрямую. По соглашению мы не ставим LayoutParams в стили, хотя в некоторых особых случаях он работает.

Похоже, вы пытаетесь использовать стиль как своего рода шаблон. Есть ли причина не использовать ресурс макета для этого и указать стиль там?

 final LayoutInflater inflater = LayoutInflater.from(mActivity); Button btn = (Button) inflater.inflate(R.layout.styled_button, parentView, false); 

Рез / макет / styled_button.xml:

  
Interesting Posts
Давайте будем гением компьютера.