Home > OS >  How to set default value for string in attributes at declare-styleable
How to set default value for string in attributes at declare-styleable

Time:07-06

I'm setting some attributes with declare-styleable to make a custom view. One of this attributes is a string. What I want to do, is that if I dont set a value in XML for thiks attribute, give it a default value but I don't know how to do it.

<?xml version="1.0" encoding ="utf-8"?>
<resources>
  <declare-styleable name ="MyCustomView">
     <attr name ="title" format="string"/>
  </declare-styleable>
</resources>

In my custom view Im doing this:

private var title = ""
init{
  val styledAttr = context.obtainStyledAttributes(attrs,R.styleable.MyCustomView)
  title = styledAttr.getString(R.styleable.MyCustomView_title)!! //I cant remove "!!" or I get a type mismatch Required String Found String?

  myTextView.text = title
}

In some XML:

<!--Here I can set title attribute but I want that if I dont set it a value, set a default value-->
<com.example.myproject.MyCustomView
   android:layout_width="0dp"
   android:layout_height = "wrap_content"
/>

CodePudding user response:

//I cant remove "!!" or I get a type mismatch Required String Found String?
title = styledAttr.getString(R.styleable.MyCustomView_title)!!

The type mismatch is because you're doing this:

private var title = ""

You're creating a var without specifying its type, so the compiler needs to infer it from the value you're assigning. Because you're assigning a String, it ends up being this:

private var title: String = ""

which is a non-null type - the compiler can't (and shouldn't!) assume you want it to be nullable just by passing a String, so you have to specify the type explicitly:

private var title: String? = ""
//  note the nullable ? ^^^

Now you're still assigning a non-null String, but you can set title to null if you want. So you don't need the !! (which you should avoid using unless you know there's a very good reason to - you're not fixing the problem you've created, just hiding it until it goes wrong)


That's just a general explanation for that error you're getting, so you know what it's about and how to deal with it - the actual solution to your problem is what DarShan posted in the comments:

title = styledAttr.getString(R.styleable.MyCustomView_title) ?: "Default Title"

styledAttr#getString will return null if the styleable reference you're looking up doesn't exist on that attr - which is good, because it means you get a "nothing there" result you can check for. If the result is null, then provide a default fallback value instead

Which is what the elvis operator (?:) is doing in that line - set title to the result of getString, unless that's null, in which case evaluate the stuff after the elvis and use that value instead. So title either gets assigned a String from getString, or "Default Title" which is also a String. Either way, it's not going to be null, so title can stay as the non-null String type instead of needing to be changed to String? (never use a nullable type unless you need null values)

You could assign the result of getString to a temp variable and do title = if (tempString != null) tempString else "DefaultTitle" but hopefully you can see how Kotlin makes it pretty elegant with its null-handling stuff. That's why nulls show up a lot in Kotlin as a kind of nothing/failure value, so you can easily handle those cases and provide fallbacks

  • Related