4

I am using this library which is a CalendarView. https://github.com/kizitonwose/CalendarView

In the sample code there is the following code which attaches a Scroll Listener to the CalendarView

 calendarView.monthScrollListener = { // etc}

I am unsure how to translate this to Java, I try the following but the "MonthScrollListener" class is nowhere to be found, its like it want some other type but I cannot find the type. Everything else has worked so far when translating the Kotlin to Java but I cannot see how this might work

mBinding.calendarView.setMonthScrollListener(new MonthScrollListener(){ // etc});

What should I pass into the setMonthScrollListener() method?

Edit: when I "ctrl click" on the setMonthScrollListener() it takes me into the CalendarView class and there is the following line:

  public final var monthScrollListener: com.kizitonwose.calendarview.ui.MonthScrollListener? /* = ((com.kizitonwose.calendarview.model.CalendarMonth) -> kotlin.Unit)? */ /* compiled code */

So I try explicitly referencing the MonthScrollListener but everything is resolved up to the MonthScrollListener, which isnt available...

enter image description here

brux
  • 3,197
  • 10
  • 44
  • 78
  • I tried this however it "cannot resolve symbol MonthScrollListener". – brux Dec 20 '19 at 14:07
  • 4
    That's because `MonthScrollListener` isn't an actual type, it's an alias, which can be found [here](https://github.com/kizitonwose/CalendarView/blob/e2efbe7da6b890acb97933b982f6d4c8a512ba05/library/src/main/java/com/kizitonwose/calendarview/ui/Types.kt#L19). – Vince Dec 20 '19 at 14:09
  • Yes I came across that whilst digging around, how am I supposed to use that in Java? Is it possible? – brux Dec 20 '19 at 14:12
  • 1
    @brux [Apparently not](https://stackoverflow.com/questions/46552242/is-it-possible-to-access-a-kotlin-typealias-from-java). – Vince Dec 20 '19 at 14:22
  • Aye, what a shame :( – brux Dec 20 '19 at 14:23

1 Answers1

1

typealias is not visible in Java, but given the example you're talking about is:

typealias MonthScrollListener = (CalendarMonth) -> Unit

Then in Java world it should be similar to single method interface like (more about it below):

import kotlin.Unit;
interface MonthScrollListener {
  Unit whatever(CalendarMonth cm);
}

It could be void because this is what Unit means in Kotlin but you know - life.

So passing Lambda in that method which expects listener should look like:

whatever.setMonthScrollListener((CalendarMonth cm) -> {
  // w00t
  return kotlin.Unit.INSTANCE;
});

I've basically ended up writing the same approach as suggested by @MishaAkopov

Edit (after reading about it):

But what type is it actually? It appears that Kotlin standard library has a bunch of interfaces like Function0<R> and Function2<P1,P2,R> that have one method invoke. So if you'd need to use above Kotlin code in previous Java versions it would instead look like:

Function1<CalendarMonth, Unit> listener = new Function1<CalendarMonth, Unit>() {
  @Override
  public Unit invoke(CalendarMonth cm) {
    // Do something with calendar month
    return kotlin.Unit.INSTANCE;
  }
}
whatever.setMonthScrollListener(listener);
Ivar
  • 4,350
  • 2
  • 27
  • 29