How to use Android Support typedef annotations in kotlin?

前端 未结 4 896
别那么骄傲
别那么骄傲 2020-12-13 18:07

I develop Android applications and often use annotations as compile time parameter checks, mostly android\'s support annotations.

Example in java code:



        
相关标签:
4条回答
  • 2020-12-13 18:39

    Update:

    Forget @IntDef and @StringDef, Now, with ART, you can use enums instead.

    From the official GoogleIO:

    https://www.youtube.com/watch?v=IrMw7MEgADk&feature=youtu.be&t=857

    Plus, if you're still not sure if you should use enums, you can hear a bunch of people yelling at each other in the comments of the first answer over here: https://stackoverflow.com/a/37839539/4036390


    Old answer:

    Just create the @IntDef class as a java class and access it via kotlin code.

    Example:

    1. Create your type class:

      public class mType { @IntDef({typeImpl.type1, typeImpl.type2, typeImpl.type3}) @Retention(RetentionPolicy.SOURCE) public @interface typeImpl { int type1 = 0; int type2 = 1; int type3 = 2; } }

    2. Put this function in any Kotlin object:

      object MyObject{ fun accessType(@mType.typeImpl mType: Int) { ... } }

    3. then access it:

      fun somOtherFunc(){ MyObject.accessType(type1) }

    **Notice: you don't have to put the access method inside an object.

    0 讨论(0)
  • 2020-12-13 18:45

    Edit: In case you miss the comments on the question or this answer, it's worth noting that the following technique compiles, but does not create the compile-time validation you would get in Java (which partially defeats the purpose of doing this). Consider using an enum class instead.


    It is actually possible to use the @IntDef support annotation by defining your values outside of the annotation class as const vals.

    Using your example:

    import android.support.annotation.IntDef
    
    public class Test {
    
        companion object {
    
             @IntDef(SLOW, NORMAL, FAST)
             @Retention(AnnotationRetention.SOURCE)
             annotation class Speed
    
             const val SLOW = 0L
             const val NORMAL = 1L
             const val FAST = 2L
        }
    
        @Speed
        private lateinit var speed: Long
    
        public fun setSpeed(@Speed speed: Long) {
            this.speed = speed
        }
    }
    

    Note that at this point the compiler seems to require the Long type for the @IntDef annotation instead of actual Ints.

    0 讨论(0)
  • 2020-12-13 19:04

    Use this:

    companion object {
        const val FLAG_PAGE_PROCESS = 0L//待处理
        const val FLAG_PAGE_EXCEPTION = 1L//设备异常
        const val FLAG_PAGE_UNCHECKED = 2L//未审核
        const val FLAG_PAGE_AUDIT = 3L//统计
        val FLAG_PAGE = "FLAG_PAGE"
    
        fun newInstance(@FlagPageDef flagPage: Int): RepairFormsListFragment {
            val fragment = RepairFormsListFragment()
            val args = Bundle()
            fragment.arguments = args
            return fragment
        }
    
        @Retention(AnnotationRetention.SOURCE)
        @IntDef(FLAG_PAGE_PROCESS, FLAG_PAGE_EXCEPTION, FLAG_PAGE_UNCHECKED, FLAG_PAGE_AUDIT)
        annotation class FlagPageDef
    }
    
    0 讨论(0)
  • 2020-12-13 19:05

    There's currently no way to achieve exactly this in Kotlin, since an annotation class cannot have a body and thus you cannot declare a constant in it which would be processed by IntDef. I've created an issue in the tracker: https://youtrack.jetbrains.com/issue/KT-11392

    For your problem though, I recommend you use a simple enum.

    0 讨论(0)
提交回复
热议问题