Использование enum для пользовательских атрибутов представления в Android - PullRequest
0 голосов
/ 10 мая 2019

Issue

Я хочу добавить следующий атрибут в пользовательское представление, которое я создаю в Android:

        <attr name="sourceType" format="enum">
            <enum name="generic" value="???" />
            <enum name="dash" value="???" />
            <enum name="smooth_streaming" value="???" />
            <enum name="hls" value="???" />
        </attr>

Внутренне в своем коде я хотел бы использовать перечисление для представленияразличные типы источников:

public enum SourceType {
    Generic, DASH, SmoothStreaming, HLS;
}

Однако в моем собственном представлении я не уверен, как преобразовать значение атрибута в перечисление:

    public BFPlayer(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.BFPlayer);

        // Clearly wrong:
        //    1. SourceType.Generic cannot be cast to int
        //    2. int cannot be cast to SourceType
        SourceType sourceType = attributes.getInt(R.styleable.BFPlayer_sourceType, SourceType.Generic);
    }

Что я пробовал

Я подумал сделать что-то вроде следующего:

attrs.xml

        <attr name="sourceType" format="enum">
            <enum name="generic" value="1" />
            <enum name="dash" value="2" />
            <enum name="smooth_streaming" value="3" />
            <enum name="hls" value="4" />
        </attr>

SourceType.java

public enum SourceType {
    Generic (1), DASH (2), SmoothStreaming (3), HLS (4);

    private int value;

    private SourceType(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static SourceType fromInt(int value) {
        switch (value) {
            case 1: return Generic;
            case 2: return DASH;
            case 3: return SmoothStremaing;
            case 4: return HLS;
            default: throw new Error("Invalid SourceType");
        }
    }
}

BFPlayer.java

    public BFPlayer(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.BFPlayer);

        // Clearly wrong:
        //    1. SourceType.Generic cannot be cast to int
        //    2. int cannot be cast to SourceType
        SourceType sourceType = SourceType.fromInt(
            attributes.getInt(R.styleable.BFPlayer_sourceType, SourceType.Generic.getValue())
        );
    }

Однако это похоже на неправильное решение:

  • Это требует использования .fromtInt и .getValue для создания экземпляра нового SourceType
  • Требуется обновить инструкцию switch, если я добавлю новые значения
  • Произвольно назначает целочисленные значения каждомуoption

Есть ли лучшее решение?

Ответы [ 2 ]

1 голос
/ 10 мая 2019

Чтобы устранить проблему, которая гласит: «Требуется обновить инструкцию switch, если я добавлю новые значения», вы можете использовать следующее

public enum SourceType {
    // ...

    private static final List<SourceType> SOURCE_TYPES_ = Arrays.asList(SourceType.values());

    public static Optional<SourceType> find(int value) {
        return SOURCE_TYPES_ 
                        .stream()
                        .filter(type -> value == type.getValue())
                        .findFirst();
    }
}
1 голос
/ 10 мая 2019

У перечислений есть метод values(), который возвращает массив типа этого перечисления, причем каждое значение перечисления присутствует в массиве.Вы можете определить статический массив этого типа перечисления в качестве члена перечисления.это просто индексация в массиве, возвращаемом SourceType.values ​​(), но это менее эффективно, потому что он создает массив для каждого вызова.Я считаю, что это решает все три ваши проблемы: вам не нужно использовать какие-либо дополнительные методы для создания экземпляра SourceType;Вам не нужно вручную обновлять массив при добавлении новых значений;и вы не произвольно назначаете целочисленные значения опциям перечисления.

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