Hi I am making a app with Kotlin and I found that I can both use
textView.setText(str)
and
textView.text = $str
I wanna know what I should use and the differences between them.
Thank you.
They're the same in most cases, basically Kotlin generates a synthetic property for the class attributes based on their getter, which you can use to assign values to and get values from.
//So, for most cases
textView.setText("some value");
//Is the same as
textView.text = "some value"
//The second is simply shorter and is the 'kotlin way' of assigning values
Now, here's the catch -
In most cases, this works fine. But, as mentioned, the synthetic property is generated from the getter, if there is a setter as well, then issues arise. The reason is that the getter and the setter may have different types. For example, EditText has Editable getter, now, kotlin creates a synthetic property text of the type Editable.
editText.setText("some value"); //Works
editText.text = "some value" //Won't work, will show an error stating that expected type is Editable
textView.setText(str) and textView.text = $str, does the same job of setting the specified str to TextView. The only difference I can come up with is,
textView.setText(str) // old Java way of setting Text where method setText(str) was being called.
textView.text = $str //new Kotlin way of setting Text where instead of a method, a synthetic property is being called.
As in the Kotlin, you are not using findViewById
so to access your textView, import statement must be like this
import kotlinx.android.synthetic.main.<layout>.*
And textView.text = $str is the Synthetic Property access provided by Kotlin Plugin for android
You can use both, not much difference in the usability, but for the easier code writing
this would be better
For more information, read this https://kotlinlang.org/docs/tutorials/android-plugin.html
Both works the same way.
Java Convention
textView.setText(“…”)
Kotlin Convention
textView.text=”…”
“Methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set) are represented as properties in Kotlin.”- documentation
thus textView.text=”…” instead of textView.setText(“…”) if you are using Kotlin to follow Kotlin Conventions.
Ref - Begin Kotlin; from an Activity, a Button and a TextView
The method setText() and getText() are called setters and getters, they are automatically generated in kotlin.
class ClassName{
var name: String= "some_value"
}
You can use the name property directly with the object of the class or you can also use the auto-generated setter method.
class Another{
var c = ClassName()
c.name = "value"
c.setName("value")
}
But if a property starts with a val instead of var then it is immutable and does not allow a setter.
In case you want to read further:-
Setters and getters in kotlin
Related
I'm learning Compose and wondering what's the difference between these two lines of code:
val stateValue = remember { mutableStateOf("value") }
And:
var stateValue by remember { mutableStateOf("value") }
In the first method, the way we update the state is by changing the value like so:
stateValue.value = "new value"
But when using delegation wer'e just changing the variable's value directly:
stateValue = "new value"
How then after re-composition the state is still "remembered" after we just overridden the existing value that had the remember function?
Delegation -as the name says- allows to delegate the getter and setter to a separate object.
So when you do stateValue = "new value" on the delegated property, you are not "overriding the existing value that had the remember function".
What happens is that the assignment syntax actually calls the setValue() operator on the property delegate (the instance returned by the call to remember that was done during initialization of the property).
Take a look at the documentation to learn more about delegated properties:
https://kotlinlang.org/docs/delegated-properties.html
Was just wondering, why is it better to use backing property for MutableLiveData, instead of just exposing getter function that returns the MutableLiveData property as live data. For example:
Why this code
private val _registeredDevicesObservable: MediatorLiveData<List<Data>> = MediatorLiveData()
val registeredDevicesObservable: LiveData<List<Data>> = _registeredDevicesObservable
is better or more acceptable than this one
private val _registeredDevicesObservable: MediatorLiveData<List<Data>> = MediatorLiveData()
fun registeredDevicesObservable(): LiveData<List<Data>> = _registeredDevicesObservable
As also when this getter function is keeping the LiveData immutability and keeps me from having that little annoying underscore syntax when accessing the property inside the view model.
It's just less idiomatic in the language to use a function that simply returns an already-available object. You're free to do it any way you like, but if others have to work with your code, it will be easier to understand and work with if you follow general conventions.
There isn't as strong a convention about whether the backing property should have a leading underscore in the name, so if you don't like it, don't use it.
One reason to stick with these conventions is there is a proposed upcoming language feature to allow you to do this without a backing property, and so if you're following the conventions, it will be very easy to update your code to eliminate the backing property.
Hi I am making a app with Kotlin and I found that I can both use
textView.setText(str)
and
textView.text = $str
I wanna know what I should use and the differences between them.
Thank you.
They're the same in most cases, basically Kotlin generates a synthetic property for the class attributes based on their getter, which you can use to assign values to and get values from.
//So, for most cases
textView.setText("some value");
//Is the same as
textView.text = "some value"
//The second is simply shorter and is the 'kotlin way' of assigning values
Now, here's the catch -
In most cases, this works fine. But, as mentioned, the synthetic property is generated from the getter, if there is a setter as well, then issues arise. The reason is that the getter and the setter may have different types. For example, EditText has Editable getter, now, kotlin creates a synthetic property text of the type Editable.
editText.setText("some value"); //Works
editText.text = "some value" //Won't work, will show an error stating that expected type is Editable
textView.setText(str) and textView.text = $str, does the same job of setting the specified str to TextView. The only difference I can come up with is,
textView.setText(str) // old Java way of setting Text where method setText(str) was being called.
textView.text = $str //new Kotlin way of setting Text where instead of a method, a synthetic property is being called.
As in the Kotlin, you are not using findViewById
so to access your textView, import statement must be like this
import kotlinx.android.synthetic.main.<layout>.*
And textView.text = $str is the Synthetic Property access provided by Kotlin Plugin for android
You can use both, not much difference in the usability, but for the easier code writing
this would be better
For more information, read this https://kotlinlang.org/docs/tutorials/android-plugin.html
Both works the same way.
Java Convention
textView.setText(“…”)
Kotlin Convention
textView.text=”…”
“Methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set) are represented as properties in Kotlin.”- documentation
thus textView.text=”…” instead of textView.setText(“…”) if you are using Kotlin to follow Kotlin Conventions.
Ref - Begin Kotlin; from an Activity, a Button and a TextView
The method setText() and getText() are called setters and getters, they are automatically generated in kotlin.
class ClassName{
var name: String= "some_value"
}
You can use the name property directly with the object of the class or you can also use the auto-generated setter method.
class Another{
var c = ClassName()
c.name = "value"
c.setName("value")
}
But if a property starts with a val instead of var then it is immutable and does not allow a setter.
In case you want to read further:-
Setters and getters in kotlin
Well I have a WebView, and the following property setting works:
webview.settings.cacheMode = WebSettings.LOAD_NO_CACHE
but not this one:
webview.settings.appCacheEnabled = false
Instead, I have to use the old way:
webview.settings.setAppCacheEnabled(false)
Can you tell me why? Thanks.
According to the official documentation:
Note that, if the Java class only has a setter, it will not be visible as a property in Kotlin, because Kotlin does not support set-only properties at this time.
If you look at the WebSettings abstract class, you'll see it only has public abstract void setAppCacheEnabled(boolean flag); method and no getters for this property, hence Kotlin doesn't allow using a property access syntax here.
Actually, it's worth noting that while creating synthetic property, not only Kotlin looks for setter and getter methods that follow Java conventions, but it also infers property's type from the getter which comes in play in case of subclasses overriding getter methods that return more specific type than their superclasses.
I am trying to set text in a EditText but it says:
Type mismatch.
Required: Editable
Found: String
My code is as follow:
String name = "Paramjeet"
val nametxt = findViewById (R.id.nametxt) as EditText
nametxt.text = name
Don't say to use setText because I am using kotlin, not Java.
Use setText(String), since editText.text expects an Editable, not a String.
Use setText(String) as EditText.text requires an editable at firstplace not String
WHY ?
Nice explanation by Michael given under this link. Do visit this link for more detail
When generating a synthetic property for a Java getter/setter pair Kotlin first looks for a getter. The getter is enough to create a synthetic property with a type of the getter. On the other hand the property will not be created if only a setter presents.
When a setter comes into play property creation becomes more difficult. The reason is that the getter and the setter may have different type. Moreover, the getter and/or the setter may be overridden in a subclass.
There are several working answers here, but if you still want to use the property format and have your code look clean, you could write an extension:
fun String.toEditable(): Editable = Editable.Factory.getInstance().newEditable(this)
You can then use it as such:
mEditText.text = myString.toEditable()
If you want to use getter .text from principle, use:
nametxt.text = Editable.Factory.getInstance().newEditable(name)
Simple Solution
Just use edittext.setText(yourdata) instead of edittext.text because the EditText is editable, the edittext.text is used for TextView
For Example:
var name:String = "Muzammil"
edittext.setText(name)
That's it its work for me.
Or you can use an extension property:
var EditText.value
get() = this.text.toString()
set(value) {
this.setText(value)
}
and use .value= instead of .text=
Or cast to TextView but I believe this should be fixed on kotlin side for sure for convenience of developers !
(someEditText as TextView).text = "someTextValue"
Or with some extensions:
val EditText.asTextView: TextView get() = this as TextView
var EditText.value: CharSequence?
get() = asTextView.text
set(value) {
asTextView.text = value
}
You can write:
someEditText.asTextView.text = "someTextValue"
or
someEditText.value = "someTextValue"
But sadly you just cannot write simple someEditText.text = "someTextValue"
Methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set) are represented as properties in Kotlin.
But, While generating a property for a Java getter/setter pair Kotlin at first looks for a getter. The getter is enough to infer the type of property from the type of the getter. On the other hand, the property will not be created if only a setter is present( because Kotlin does not support set-only properties at this time ) .
When a setter comes into play, property generation process becomes a bit ambiguous. The reason is that the getter and the setter may have different type. Moreover, the getter and/or the setter may be overridden in a subclass ,
which exactly is the case of EditText in android.
In above case the Android TextView class contains a getter
CharSequence getText()
and a setter void
setText(CharSequence)
If I had a variable of type TextView my code would have worked fine.
But I used EditText class which contains an overridden getter
Editable getText()
which means that you can get an Editable for an EditText and set an Editable to an EditText. Therefore, Kotlin reasonably creates a synthetic property text of type Editable. As String class is not Editable, that’s why I cannot assign a String instance to the text property of the EditText class.
It Seems like JetBrains forgot to specify the dominant role of getter methods while generating kotlin properties for Java getter and setter methods. Anyways, I have submitted pull request to Jet brains kotlin website through github.
I have detailed above problem in this medium post too How Does Kotlin Generate Property from Java Getters and Setters (Undocumented by Jetbrains)
Use like this:
edtTitle.setText(intent.getStringExtra(EXTRA_TITLE))
edtDesc.setText(intent.getStringExtra(EXTRA_DESC))
I had the same issue in my projects, I give you an example that shows how to retrieve and set data in the layouts using Kotlin:
there is one button save_button and two text edit field edit_name and edit_password.
//when cliquing on the button 'save_button'
save_button.setOnClickListener {
// geting the value from the two fields by using .text.toString()
val email = edit_name.text.toString()
val password = edit_password.text.toString()
// showing the result on the systeme's log
Log.d("Main activity","your email is " + email )
Log.d("Main activity", "your password is $password" )
// Then shows these values into the text view palete using .setText()
text_view.setText("$email " + "$password")
}
val editable = Editable.Factory.getInstance().newEditable(savedString)
editText.text = editable
setText(String), so you must setText your string to editText, so in your case is : nametxt.setText(name)
var name:String = "hello world"
textview.text = name
(or)
var editText:String = "hello world"
textview.setText(name)
Look at the API of EditText:
void setText (CharSequence text, TextView.BufferType type)
Editable getText ()
Link: https://developer.android.com/reference/android/widget/EditText.html
Try using nametxt.post: nametxt.post({nametxt.setText("your text")})