5

I have been trying to translate this Kotlin code to Java since the project is in Java. I am translating by looking into Kotlin syntax. However, there are still others that I am having a hard time understanding.

https://github.com/airbnb/lottie-android/blob/master/LottieSample/src/main/kotlin/com/airbnb/lottie/samples/AppIntroActivity.kt

Specifically:

private val animationView: LottieAnimationView by lazy {
    rootView.inflate(R.layout.app_intro_animation_view, false) as LottieAnimationView
}

private val viewPager: LockableViewPager by lazy {
    findViewById<LockableViewPager>(R.id.intro_activity_viewPager)
}

override fun generateFinalButtonBehaviour(): IntroButton.Behaviour {
    return object : IntroButton.Behaviour {
        override fun setActivity(activity: IntroActivity) { finish() }
        override fun getActivity(): IntroActivity? = null
        override fun run() {}
    }
}

private fun setViewPagerScroller() {
    try {
        val scrollerField = ViewPager::class.java.getDeclaredField("mScroller")
        scrollerField.isAccessible = true
        val interpolator = ViewPager::class.java.getDeclaredField("sInterpolator")
        interpolator.isAccessible = true

        val scroller = object : Scroller(this, interpolator.get(null) as Interpolator) {
            override fun startScroll(startX: Int, startY: Int, dx: Int, dy: Int, duration: Int) {
                super.startScroll(startX, startY, dx, dy, duration * 7)
            }
        }
        scrollerField.set(viewPager, scroller)
    } catch (e: NoSuchFieldException) {
        // Do nothing.
    } catch (e: IllegalAccessException) {
        // Do nothing.
    }
}

For the setViewPagerScroller, I was able to translate the first part.

Field scrollerField = ViewPager.class.getDeclaredField("mScroller");
scrollerField.setAccessible(true);

Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
interpolator.setAccessible(true);
Woppi
  • 4,468
  • 8
  • 40
  • 74

1 Answers1

3

The method setViewPagerScroller uses kotlin anonymous inner class syntax. That is the 'object' part which has no real counterpart in java syntax.

private void setViewPagerScroller() {
    try {
        Field scrollerField = ViewPager.class.getDeclaredField("mScroller");
        scrollerField.setAccessible(true);

        Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
        interpolator.setAccessible(true);

        Scroller scroller = new Scroller(this, (android.view.animation.Interpolator) interpolator.get(null)){

            @Override
            public void startScroll(int startX, int startY, int dx, int dy, int duration) {
                super.startScroll(startX, startY, dx, dy, duration * 7);
            }
        }

        scrollerField.set(viewPager, scroller);
    } catch (NoSuchFieldException error) {
        // Do nothing.
    } catch (IllegalAccessException error) {
        // Do nothing.
    }
}

And the as keyword is like a casting in java. Hopefully you can use this to translate fun generateFinalButtonBehaviour(), it contains more of the same.

The Lazy construct unsurprisingly gets more verbose in java. You have to employ discipline to not access the viewpager wrongly if you choose to follow the structure below.

private LockableViewPager viewPager;

private LockableViewPager getViewPager(){
    if(viewPager == null){
        // produce viewpager and store in field
    }
    return viewPager;
}  

You can also use a class to more accurately represent a lazy initialization of your fields. (So that you cannot by mistake access a field which you meant to be lazily initialized) This gets even more verbose but could be worth it.

Adam
  • 2,329
  • 2
  • 20
  • 37
  • Thanks for the help, so that is why I can't google the equivalent of "object : " in java. How about the LottieAnimationView? I can't seem to translate it... private LottieAnimationView animationView; public LottieAnimationView getAnimationView() { (ViewGroup)IntroWalkthroughActivity.this.getRootView().inflate(R.layout.activity_intro_app_walkthrough, false); } – Woppi Oct 20 '17 at 09:30
  • Make sure you cast the right objects to the correct classes when needed and that in the end you cast to `LottieAnimationView` and then store it in your field – Adam Oct 20 '17 at 09:41
  • okies will try to figure it out and post once I do :) Thanks a lot. – Woppi Oct 20 '17 at 09:51