Kotlin syntax for LiveData observer?

2020-03-01 03:32发布

问题:

I have the following bit of code in my HomeActivity to use LiveData.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // Show the launch splash screen.
    //
    this.setContentView(R.layout.activity_home)

    this.viewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)

    this.viewModel.getUser().observe(this, Observer { user: User? ->

    });

}

While this seems to work, what does the following part mean?

Observer { user: User? ->

}

This must result in an object that conforms to the Observer interface which has

void onChanged (T t)

https://developer.android.com/reference/android/arch/lifecycle/Observer.html

How does

Observer { user: User? ->

}

result in an object with an onChanged method?

I don't know what putting the name of an interface in front of a lambda expression means.

Thanks!

回答1:

This is called SAM Conversion, a concept that helps interacting with Java Single Abstract Method Interfaces like in your example.

The following creates an implementation of Runnable, where the single abstract method is run():

val runnable = Runnable { println("This runs in a runnable") }

It’s described in the docs: https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions

Alternatively, but more verbose, would be to use an object:

val runnable2 = object : Runnable {
        override fun run() {
            println("This runs in a runnable")
        }
}

Both are examples of anonymous implementations of that interface. It's of course also possible to create a concrete subclass and instantiate it then.

class MyRunnable : Runnable {
    override fun run() {
        println("This runs in a runnable")
    }
}

val runnable3 = MyRunnable()


回答2:

in Kotlin the Observer { } lambda gives you param it, you can rename it as you want and use. by default data will be available with it.something() etc...

JAVA:

... new Observer {
  void onChanged(User user){
     user.something()
  }
}

KOTLIN

... object : Observer<User> {
   fun onChanged(user: User?){
        user.something()
   }
}

OR

... Observer {
   it.something()
}

you can rename it to whatever you want like

... Observer { myUser ->
   myUser.something()
}