Котлин Аннотация IntDef
У меня есть этот пример кода:
class MeasureTextView: TextView {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
companion object{
val UNIT_NONE = -1
val UNIT_KG = 1
val UNIT_LB = 0
}
fun setMeasureText(number: Float, unitType: Int){
val suffix = when(unitType){
UNIT_NONE -> {
EMPTY_STRING
}
UNIT_KG -> {
KG_SUFIX
}
UNIT_LB -> {
LB_SUFIX
}
else -> throw IllegalArgumentException("Wrong unitType passed to formatter: MeasureTextView.setMeasureText")
}
// set the final text
text = "$number $suffix"
}
}
Я хочу иметь возможность использовать во время компиляции функцию автозаполнения в сочетании с аннотацией IntDef, поэтому при вызове setMeasureText(...)
статические переменные показаны в качестве параметров аргумента этого метода.
Я искал об этом, и я не мог найти, поддерживал ли Kotlin эти аннотации в стиле Java (например, intdef). Итак, я попробовал это и сделал для этого аннотацию, но в автозаполнении она не будет отображаться.
Мой вопрос: - Поддерживается ли аннотация Java IntDef в Kotlin (последняя версия)
Если это так, как я могу включить ON в Android Studio IDE (если он работает, я не могу заставить компилятор предложить это).
Если это не так, существует ли какой-либо Kotlin-способ проверки времени компиляции?
7 ответов
Начиная с Kotlin 1.0.3, @IntDef
аннотация не поддерживается, но поддержка планируется для более поздних версий.
Kotlin способ сделать эти проверки времени компиляции заключается в использовании enum class
вместо серии Int
константы.
Странная вещь, но этот вопрос приходит в поиск раньше того же с правильным ответом
Копирую это здесь:
import android.support.annotation.IntDef
public class Test {
companion object {
@IntDef(SLOW, NORMAL, FAST)
@Retention(AnnotationRetention.SOURCE)
annotation class Speed
const val SLOW = 0
const val NORMAL = 1
const val FAST = 2
}
@Speed
private var speed: Int=SLOW
public fun setSpeed(@Speed speed: Int) {
this.speed = speed
}
}
Мой предпочтительный способ использовать IntDef с Kotlin - использовать объявления верхнего уровня:
package com.example.tips
const val TIP_A = 1
const val TIP_B = 2
const val TIP_C = 3
@IntDef(TIP_A, TIP_B, TIP_C)
@Retention(AnnotationRetention.SOURCE)
annotation class TipId
class TipsDataProvider {
fun markTip(@TipId tipId: Int) {
...
}
}
Никаких дополнительных классов или объектов не требуется! Подробнее о объявлениях верхнего уровня здесь.
Если вы звоните setMeasureText
из Java вы можете заставить его работать, создав свой IntDef в Java тоже
// UnitType.java
@Retention(RetentionPolicy.SOURCE)
@IntDef({MeasureText.UNIT_KG, MeasureText.UNIT_LB, MeasureText.UNIT_NONE})
public @interface UnitType {}
х / т Тоник Артос
Вам также нужно будет обновить объект-компаньон, чтобы сделать ваши значения длинными и общедоступными.
companion object{
const val UNIT_NONE = -1L
const val UNIT_KG = 1L
const val UNIT_LB = 0L
}
Попытайся:
companion object {
const val VALUE_1: Int = 1
const val VALUE_2: Int = 2
const val VALUE_3: Int = 3
}
@IntDef(value = [VALUE_1, VALUE_2, VALUE_3])
@Retention(AnnotationRetention.SOURCE)
annotation class KlssName {
}
Что касается обсуждения
koltin
enum или java-аннотации, я провел простой тест в android, создав проект библиотеки и декомпилировав его, чтобы увидеть размеры файлов.
Kotlin enum класс
TestEnum
:
enum class TestEnum {
ENUM1,
ENUM2,
ENUM3,
ENUM4,
ENUM5,
ENUM6,
ENUM7,
ENUM8,
ENUM9,
ENUM11,
ENUM12,
ENUM13,
ENUM14,
ENUM15,
ENUM16,
ENUM17,
ENUM18,
}
Java интерфейс
TestInterface
@Retention(RetentionPolicy.SOURCE)
@StringDef(
{
ENUM1,
ENUM2,
ENUM3,
ENUM4,
ENUM5,
ENUM6,
ENUM7,
ENUM8,
ENUM9,
ENUM11,
ENUM12,
ENUM13,
ENUM14,
ENUM15,
ENUM16,
ENUM17,
ENUM18,
}
)
public @interface TestInterface {
public static final String ENUM1 = "ENUM1";
public static final String ENUM2 = "ENUM2";
public static final String ENUM3 = "ENUM3";
public static final String ENUM4 = "ENUM4";
public static final String ENUM5 = "ENUM5";
public static final String ENUM6 = "ENUM6";
public static final String ENUM7 = "ENUM7";
public static final String ENUM8 = "ENUM8";
public static final String ENUM9 = "ENUM9";
public static final String ENUM11 = "ENUM11";
public static final String ENUM12 = "ENUM12";
public static final String ENUM13 = "ENUM13";
public static final String ENUM14 = "ENUM14";
public static final String ENUM15 = "ENUM15";
public static final String ENUM16 = "ENUM16";
public static final String ENUM17 = "ENUM17";
public static final String ENUM18 = "ENUM18";
}
И если вы создаете выпуск (я использую новую сборку Gradle проекта Android по умолчанию), это результат размера файла:
Вы сами решаете, какой из них вам больше нравится
Как сказано в принятом ответе, используйте enum class
в котлине.
Я написал конкретный код заданного вопроса, он может помочь некоторым новичкам в kotlin:
class MeasureTextView: TextView {
enum class UnitType(val value : Int){
UNIT_NONE(-1),
UNIT_KG(0),
UNIT_LB(1)
}
fun setMeasureText(number: Float, unitType: UnitType){
val suffix = unitType.value
}
}