SergiBC
SergiBC

Reputation: 533

Lint error with snackbar extension function

I have the following extension function to reduce a bit the code and to avoid forgetting the duration when showing a snackbar:

fun Fragment.showSnackbar(text: String, length: Int = Snackbar.LENGTH_SHORT) {
    view?.run { Snackbar.make(this, text, length).show() }
}

But the lint is giving me the following error:

Error: Must be one of: BaseTransientBottomBar.LENGTH_INDEFINITE, BaseTransientBottomBar.LENGTH_SHORT, BaseTransientBottomBar.LENGTH_LONG or value must be ≥ 1 (was -1) [WrongConstant]
       view?.run { Snackbar.make(this, textResId, length).show() }
                                                  ~~~~~~

It seems that if you pass a custom length param it should be an int >=0 and it is detecting that the default param is a custom one not a system/class one but it is (LENGTH_SHORT, which is -1).

If the length param is of type BaseTransientBottomBar.Duration (which is an interface notation to set the possible values of the length param) it compiles well but I don't know how to assign it as a default value.

There is any way to avoid the lint error or to set a default value of type BaseTransientBottomBar.Duration?

--- EDIT: after apply the @rahat approach:

fun Fragment.showSnackbar(text: String, @BaseTransientBottomBar.Duration length: Int = Snackbar.LENGTH_SHORT) {
    view?.run { Snackbar.make(this, text, length).show() }
}

The error:

   [PATH]/DesignExt.kt:18: Error: Must be one of: BaseTransientBottomBar.LENGTH_INDEFINITE, BaseTransientBottomBar.LENGTH_SHORT, BaseTransientBottomBar.LENGTH_LONG [WrongConstant]
   fun Fragment.showSnackbar(text: String, @BaseTransientBottomBar.Duration length: Int = Snackbar.LENGTH_SHORT) {
                                                                                          ~~~~~~~~~~~~~~~~~~~~~

Upvotes: 1

Views: 815

Answers (2)

SergiBC
SergiBC

Reputation: 533

Finally I avoid the error adding the warning 'WrongConstant' to the lint.xml file. If it was the only thing in the file it will be:

android {     
  lintOptions {          
      warning "WrongConstant"      
  } 
}

Upvotes: 0

rahat
rahat

Reputation: 2056

Since the signature of the called method is as follows

@NonNull
  public static Snackbar make(
      @NonNull View view, @NonNull CharSequence text, @Duration int duration)

and the class Snackbar

public class Snackbar extends BaseTransientBottomBar<Snackbar>

finally the signature of Duration is

@RestrictTo(LIBRARY_GROUP)
  @IntDef({LENGTH_INDEFINITE, LENGTH_SHORT, LENGTH_LONG})
  @IntRange(from = 1)
  @Retention(RetentionPolicy.SOURCE)
  public @interface Duration {}

So the value passed must be one of the values from the Duration, even if it is, the lint is coming because the parameter is not annotated and can accept any Int value, but when you annotate then when you call your method with a value different than those present in Duration it will give you warning at that place, and it may lead to RuntimException if passed value is not one of them.

Try with this,

fun Fragment.showSnackbar(text: String, @BaseTransientBottomBar.Duration length: Int = Snackbar.LENGTH_SHORT) {
    view?.run { Snackbar.make(this, text, length).show() }
}

Upvotes: 1

Related Questions