Стиль в пользовательском представлении не влияет на вызов конструктора - PullRequest
1 голос
/ 07 апреля 2020

Я пытаюсь создать собственный вид и установить его стиль программно. Я создал пользовательское представление на основе AppCompatButton:

public class RangeSelectorButton extends androidx.appcompat.widget.AppCompatButton {
    public int onClickKey = -1;

    public RangeSelectorButton(Context context) {
        this(context, null);
    }

    public RangeSelectorButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public RangeSelectorButton(Context context, AttributeSet attrs) {
        this(context, attrs, R.style.RangeSelectorButton);
    }
}

, и теперь я застреваю в странном поведении:

<ru.SomeDomain.CustomViews.RangeSelector
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:clickable="true" android:focusable="true">

                <!-- In this case all works fine -->
                <ru.SomeDomain.RangeSelectorButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:minHeight="10dp"
                    android:minWidth="40dp"
                    style="@style/RangeSelectorButton"
                    />

                <!-- Style not applies -->
                <ru.SomeDomain.CustomViews.RangeSelectorButton
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:minHeight="10dp"
                    android:minWidth="40dp"
                    />
</ru.SomeDomain.CustomViews.RangeSelector>

Что мне следует делать, если я не хочу использовать атрибут style в xml каждый раз, когда я создаю свой собственный вид?

Если необходимо, мой стиль. xml содержит:

<style name="RangeSelectorButton" parent="@android:style/Widget.Button">
    <item name="android:background">@drawable/range_toggle_button_selector</item>
</style>

range_toggle_button_selector. xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/range_unselected" android:state_pressed="false" />
    <item android:drawable="@drawable/range_selected" android:state_pressed="true" />
</selector>

1 Ответ

3 голосов
/ 07 апреля 2020

Проблема здесь в том, что вы передаете стиль вместо параметра defStyleAttr, который ожидает атрибут, а не стиль. Здесь есть два решения:

  1. Использовать атрибут. В attrs.xml объявите:

    <attr name="rangeSelectorButtonStyle" format="reference"/>
    

    и в теме своего приложения:

    <item name="rangeSelectorButtonStyle">@style/RangeSelectorButton</style>
    

    и измените конструктор на:

    public RangeSelectorButton(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.rangeSelectorButtonStyle);
    }
    

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

  2. Если вы не хотите использовать атрибут, вы можете вызвать Четвертый конструктор View, который имеет параметр, который принимает стиль по умолчанию, а не атрибут:

    View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
    

    Добавьте этот конструктор к вашему представлению, а во втором конструкторе вызовите четвертый как:

    public RangeSelectorButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0, R.style.RangeSelectorButton);
    }
    

    Обратите внимание, что четвертому конструктору требуется API 21.

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