How you do simplify this Kotlin Getter and Settle code? - android

I am new to Kotlin and have been developing with the language. From Java, I am used to coding getters and setters by creating two functions. For example:
public String getName(){
return name;
}
public void setName(name){
this.name = name;
}
However, can this code be simplified in Kotlin? My code right now is:
class ClassName{
private var username: String? = null
private var photoFileName: String? = null
private var userId: String? = null
private var requestSent: Boolean? = null
fun ClassName(username: String?, photoFileName: String?, userId: String?, requestSent: Boolean?) {
this.username = username
this.photoFileName = photoFileName
this.userId = userId
this.requestSent = requestSent
}
fun getUsername(): String? {
return username
}
fun setUsername(string: String){
username = string
}
fun getPhotoFileName(): String? {
return photoFileName
}
fun setPhotoFileName(string: String){
photoFileName = string
}
fun getUserId(): String? {
return userId
}
fun setUserId(string: String){
userId = string
}
fun getRequestSent(): Boolean? {
return requestSent
}
fun setRequestSent(bool: Boolean){
requestSent = bool
}
}

Here's a more enhanced version of your kotlin class
data class YourClass(
var username: String? = null,
var photoFilename: String? = null,
var userId: String? = null,
var requestSent: Boolean? = null
)
You don't have to manually create setter, getter function in Kotlin.

Your class will get converted to this if you use data class in kotlin. All the setters and getters will be replaced by the properties.And yes you can always call them like you used to do like set and get.
data class ClassName(
var username: String,
var photoFileName: String,
var userId: String,
var requestSent: String
)

Related

Observing class parameters in Android using databinding and Kotlin

I have a model
data class RegisterPostDataWithPwdCheck(
var phone_number: String?,
var name: String?,
var password: String?,
var secondPassword: String?)
And a ViewModel
class SignUpViewModel(application: Application) : BaseViewModel(application){
val registerPostData = MutableLiveData<RegisterPostDataWithPwdCheck>...
fun checkPassword(){}...}
I also have a View that has this code inside
viewModel.registerPostData.observe(viewLifecycleOwner, Observer {
viewModel.checkPassword()
})
In the XML there are two fields of interest
<EditText
android:id="#+id/edittext_sign_up_password"
android:text="#={view_model.registerPostData.password}" />
<EditText
android:id="#+id/edittext_sign_up_second_pw"
android:text="#={view_model.registerPostData.secondPassword}" />
What I understood so far is that the .observe will be called only when the entire RegisterPostDataWithPwdCheck object changes and I don't want that. I want it to be triggered when any of the parameters changes so I can call the fun checkPassword(){} in order to see if the two fields match. Is this possible?
Using #mahdi-shahbazi comment I've managed to work this out in Kotlin. My Model is now:
data class RegisterPostDataWithPwdCheck(
#SerializedName(value = "phone_number")
private var phoneNumber: String?,
private var name: String?,
private var password: String?,
private var secondPassword: String?
) : BaseObservable() {
#Bindable
fun getPhoneNumber(): String? {
return phoneNumber
}
fun setPhoneNumber(value: String) {
if (value != phoneNumber) {
phoneNumber = value
notifyPropertyChanged(BR.phoneNumber)
}
}
#Bindable
fun getName(): String? {
return name
}
fun setName(value: String?) {
if (value != name) {
name = value
notifyPropertyChanged(BR.name)
}
}
#Bindable
fun getPassword(): String? {
return password
}
fun setPassword(value: String?) {
if (value != password) {
password = value
notifyPropertyChanged(BR.password)
}
}
#Bindable
fun getSecondPassword(): String? {
return secondPassword
}
fun setSecondPassword(value: String?) {
if (value != secondPassword) {
secondPassword = value
notifyPropertyChanged(BR.secondPassword)
}
}
}
And creating custom LiveData class:
class PropertyAwareMutableLiveData<T : BaseObservable> : MutableLiveData<T>()
{
private val callback = object : Observable.OnPropertyChangedCallback() {
override fun onPropertyChanged(sender: Observable?, propertyId: Int) {
value = value
}
}
override fun setValue(value: T?) {
super.setValue(value)
value?.addOnPropertyChangedCallback(callback)
}
}
What I still don't know if there is a way to automate this #Binding process which is terribly slow and boring and also forces some changes (turning parameters to private).

Automatically generate getters and setters in Android Studio in Kotlin

I would like to find a way to generate getters and setters of some Kotlin property automatically. In java there is no problem to do it.
I am working with data binding and I have many classes which looks like so:
class AnimalListItemPresenter(private var _animal: String) : BaseObservable() {
var animal: String
#Bindable get() = _animal
set(value) {
_animal = value
notifyPropertyChanged(BR.item)
}
}
I know that it is not possible not possible to generate the logic in setter but can I at leat somehow generate the standard getter and setter?
Standard getters and setters are built into Kotlin.
example:
class Customer {
var id = "",
var name = ""
}
and you can use it like:
fun copyCustomer(customer: Customer) : Customer {
val result = Customer()
result.name = customer.name
.
.
return result
}
You can also override the default getter and setter in the manner you have done in the code snippet. Good Resource: https://kotlinlang.org/docs/reference/properties.html
If you want a quick way of generating boilerplate code in Android Studio -> Alt + Enteron the property and you canAdd GetterorAdd Setter` among different options
class BannerBean {
private var id: String? = null
private var image: String? = null
private var link: String? = null
fun getId(): String? {
return id
}
fun setId(id: String?) {
this.id = id
}
fun getImage(): String? {
return image
}
fun setImage(image: String?) {
this.image = image
}
fun getLink(): String? {
return link
}
fun setLink(link: String?) {
this.link = link
}
}

Order firestore documents

I have a chat done in firestore and obviously I need to get the messages from each chat room but the messages never come sorted by the date always by the id of the user.
In the beginning I did without using #ServerTimestamp and was generating the date on the Android device itself but at the suggestion right here in Stackoverflow I changed to the firestore itself to generate the date, according to the suggestion that would solve but it does not work. It's coming in an order I did not order, it's coming in the order of the user id, lateinit var from_id: String
class Message {
lateinit var content: String
#ServerTimestamp
var timestamp: Timestamp ?= null
lateinit var from_id: String
lateinit var type: String
constructor(content: String, timestamp : Timestamp, from_id: String, type: String) {
this.content = content
this.from_id = from_id
this.timestamp = timestamp
this.type = type
}
constructor(content: String, from_id: String, type: String) {
this.content = content
this.from_id = from_id
this.type = type
}
constructor()
}
ControllerChat
...
override fun sendMessageText(idChatRoom: String, from_id: String, text: String, listenerSendMessage: ListenerSendChatMessage) {
var message = Message(text, from_id, Message.TEXT)
chatChannelsCollectionRef
.document(idChatRoom)
.collection(MESSAGES)
.add(message).addOnSuccessListener {
listenerSendMessage.onSendChatMessageSucess()
}.addOnFailureListener {
listenerSendMessage.errorSendChatMessage(it)
}
}
...
override fun getAllMessageFromChatRoom(idChatRoom: String, listenerGetAllChatMessage: ListenerGetAllChatMessage) {
Log.d(TAG, "ChatController - getAllMessageFromChatRoom")
listenerSnapshotAllMessageFromChatRoom = chatChannelsCollectionRef
.document(idChatRoom)
.collection(MESSAGES)
.orderBy("timestamp", Query.Direction.ASCENDING)
.addSnapshotListener(object : EventListener<QuerySnapshot> {
override fun onEvent(querySnapshot: QuerySnapshot?, p1: FirebaseFirestoreException?) {
querySnapshot?.let { qSnap ->
if (!qSnap.isEmpty) {
var documentChange = qSnap.documentChanges
for (doc in documentChange) {
var message = doc.document.toObject(Message::class.java)
Log.i(TAG, "Document Change: " + message.content)
listenerGetAllChatMessage.onChatMessage(message)
}
}
}
}
})
}

You can have an empty constructor or a constructor whose parameters match the fields

#Entity(tableName = AppConstant.Companion.CALENDAR_EVENT_TABLE_NAME)
class CalendarEvent : Serializable {
#PrimaryKey(autoGenerate = true)
var id: Int? = null
#ColumnInfo(name = "calendarId")
var calendarId: Int? = null
#ColumnInfo(name = "title")
var title: String? = null
#ColumnInfo(name = "organizer")
var organizer: String? = null
#ColumnInfo(name = "location")
var location: String? = null
#ColumnInfo(name = "description")
var description: String? = null
#ColumnInfo(name = "startDate")
var startDate: String? = null
#ColumnInfo(name = "endDate")
var endDate: String? = null
#Embedded
var attendees: List<Attendees>? = null
constructor(id: Int,calendarId: Int, title: String, organizer: String, location: String, description: String,startDate: String,endDate: String,attendees: List<Attendees>) {
this.id = id
this.calendarId=calendarId
this.title = title
this.organizer = organizer
this.location = location
this.description = description
this.startDate=startDate
this.endDate=endDate
this.attendees=attendees
}
companion object {
private const val serialVersionUID = -3245196282912380133L
val TAG = CalendarEvent::class.java.name
}
}
#Entity(tableName = AppConstant.Companion.ATTENDEES_TABLE_NAME)
class Attendees: Serializable
{
#PrimaryKey(autoGenerate = true)
var id: Int? = null
#ColumnInfo(name = "name")
var name: String= ""
#ColumnInfo(name = "email")
var email: String= ""
#ColumnInfo(name = "status")
var status: Int? = null
constructor(id: Int,name: String,email: String,status: Int)
{
this.id=id
this.name=name
this.email=email
this.status=status
}
companion object {
private const val serialVersionUID = -3245196282912380133L
val TAG = Attendees::class.java.name
}
}
#Database(entities = arrayOf(Contact::class, CalendarEvent::class,Attendees::class), version = AppConstant.Companion.DATA_BASE_VERSION)
abstract class AppDatabase : RoomDatabase() {
abstract fun contactDao(): ContactDAO
companion object {
var INSTANCE: AppDatabase? = null
fun getAppDatabase(context: Context): AppDatabase {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, AppConstant.DATABASE_NAME)
// allow queries on the main thread.
.addMigrations()
// Don't do tfallbackToDestructiveMigrationhis on a real app! See PersistenceBasicSample for an example.
.build()
}
return INSTANCE!!
}
}
fun destroyInstance() {
INSTANCE = null
}
}
there are two model class i have to create two table one parent as Calendar Event and its chile table as Attendess i have written AppDatabase for entities but when i compile then i am getting this exception
e: error: Entities and Pojos must have a usable public constructor. You can have an empty constructor or a constructor whose parameters match the fields (by name and type).
e:
please suggest me what i am ding wrong i am new in room databse i never use much i am able to create single table but not child parent relationship table so please check suggest where am doing mistake

No args error retrofit request body

I am facing problem while sending json object body using retrofit to the server. Below is the error.
Failed to invoke public
com.nitesh.brill.saleslines._User_Classes.User_PojoClass.UpdatePreviousDetails()
with no args
code snippet
// Api endpoint
#Headers("Content-Type: application/json")
#POST("UpdatePreviousDetails/{Id}")
fun updatePreviousDetails(#Path("Id") Id: Int, #Body updateDetails :UpdatePreviousDetails): Call<UpdatePreviousDetails>
//pojo class
package com.nitesh.brill.saleslines._User_Classes.User_PojoClass
import java.util.*
/**
* Created by Nitesh Android on 16-08-2017.
*/
class UpdatePreviousDetails(
var CompanyName: String? = null!!,
var Designation: String? = null!!,
var DateOfJoin: Date? = null!!,
var DateOfLeaving: Date? = null!!,
var SectorPreviouslyWorked: String? = null!!,
var Id: Int? = null!!
) {
}
//sending data
val details = UpdatePreviousDetails("rr", "asm", date, date, "Pharmaceuticals",3)
val call = apiEndpointInterface!!.updatePreviousDetails(5, details)
call.enqueue(object :Callback<UpdatePreviousDetails> {
override fun onResponse(call: Call<UpdatePreviousDetails>?, response: Response<UpdatePreviousDetails>?) {
objUsefullData.showSnackBar("success")
UsefullData.Log("============="+response!!.body().toString())
}
override fun onFailure(call: Call<UpdatePreviousDetails>?, t: Throwable?) {
objUsefullData.showSnackBar("fail")
UsefullData.Log("============="+t)
}
})
I am using kotlin language
Your UpdatePreviousDetails class has to have a constructor with no params to enable Gson (inside Retrofit) to convert your object into JSON.
EDIT
class UpdatePreviousDetails() {
var CompanyName: String? = null
var Designation: String? = null
var DateOfJoin: Date? = null
var DateOfLeaving: Date? = null
var SectorPreviouslyWorked: String? = null
var Id: Int? = null
constructor(
CompanyName: String?,
Designation: String?,
DateOfJoin: Date?,
DateOfLeaving: Date?,
SectorPreviouslyWorked: String?,
Id: Int?
) : this() {
this.CompanyName = CompanyName
this.Designation = Designation
this.DateOfJoin = DateOfJoin
this.DateOfLeaving = DateOfLeaving
this.SectorPreviouslyWorked = SectorPreviouslyWorked
this.Id = Id
}
}

Categories

Resources