Josh Feinberg
Josh Feinberg

Reputation: 153

Varargs Kotlin Java interop not working properly

For the makeSceneTransitionAnimation there are two static functions

public static ActivityOptionsCompat makeSceneTransitionAnimation(Activity activity,
        View sharedElement, String sharedElementName)

and

    public static ActivityOptionsCompat makeSceneTransitionAnimation(Activity activity,
        Pair<View, String>... sharedElements)

The first function call works properly in Kotlin but when calling the second one, both these calls return errors

        val imageTransition = Pair<View, String>(imageView, imageView.getTransitionName());
        val textTransition = Pair<View, String>(textView, textView.getTransitionName());
        val transitionList = Array(2, { imageTransition });
        transitionList[1] = textTransition;
        val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, *transitionList);

and

        val imageTransition = Pair<View, String>(imageView, imageView.getTransitionName());
        val textTransition = Pair<View, String>(textView, textView.getTransitionName());
        val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, imageTransition, textTransition);

Is there a proper way to get this working or is this an issue with the interop?

Edit Added change to ensure that it is using the same classes

val imageView : View = view.findViewById(android.R.id.icon);
val textView : View = view.findViewById(android.R.id.text1);
imageView.setTransitionName("imageTransition");
textView.setTransitionName("textTransition")

val imageTransition : android.support.v4.util.Pair<android.view.View, java.lang.String> = android.support.v4.util.Pair.create(imageView, imageView.getTransitionName() as java.lang.String);
val textTransition : android.support.v4.util.Pair<android.view.View, java.lang.String> = android.support.v4.util.Pair.create(textView, textView.getTransitionName() as java.lang.String);
val transitionList = Array(2, { imageTransition });
transitionList[1] = textTransition;
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, *transitionList);

Current compiler error:

Error:(72, 84) The spread operator (*foo) may only be applied in a vararg position
Error:(72, 99) No value passed for parameter sharedElementName

And another

val imageView : View = view.findViewById(android.R.id.icon);
val textView : View = view.findViewById(android.R.id.text1);
imageView.setTransitionName("imageTransition");
textView.setTransitionName("textTransition")

val imageTransition : android.support.v4.util.Pair<android.view.View, java.lang.String> = android.support.v4.util.Pair.create(imageView, imageView.getTransitionName() as java.lang.String);
val textTransition : android.support.v4.util.Pair<android.view.View, java.lang.String> = android.support.v4.util.Pair.create(textView, textView.getTransitionName() as java.lang.String);
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, imageTransition, textTransition);

Current compiler error:

Error:(72, 84) Type mismatch: inferred type is android.support.v4.util.Pair<android.view.View, java.lang.String> but android.view.View! was expected
Error:(72, 101) Type mismatch: inferred type is android.support.v4.util.Pair<android.view.View, java.lang.String> but kotlin.String! was expected

Upvotes: 10

Views: 3411

Answers (5)

aslamhossin
aslamhossin

Reputation: 1277

This is a whole code snippet I would recommend for :

companion object {
    const val EXTRA_ITEM = "EXTRA_ITEM"
    const val TRANSITION_NAME_IMAGE = "TRANSITION_NAME_IMAGE"
    const val TRANSITION_NAME_TEXT = "TRANSITION_NAME_TEXT"
  }

  override fun onItemClick(pos: Int, item: Item, imageView: ImageView, textView: TextView) {
    val intent = Intent(context, YourActivity::class.java)
    intent.putExtra(EXTRA_ITEM, item)
    intent.putExtra(
      TRANSITION_NAME_IMAGE,
      ViewCompat.getTransitionName(imageView)
    )
    intent.putExtra(
      TRANSITION_NAME_TEXT,
      ViewCompat.getTransitionName(textView)
    )

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      val optionsCompat = ActivityOptionsCompat.makeSceneTransitionAnimation(
        context as Activity,
        androidx.core.util.Pair<View,String>(imageView, imageView.transitionName),
        androidx.core.util.Pair<View,String>(textView, textView.transitionName)
      )
      startActivity(intent, optionsCompat.toBundle())
    } else {
      startActivity(intent)
    }
  }

You have to also implement this method for transaction in your activity for back to Previous screen .

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    val id = item.itemId
    if (id == android.R.id.home) {
      supportFinishAfterTransition()
      return true
    }
    return super.onOptionsItemSelected(item)
  }

Upvotes: 1

Joshua
Joshua

Reputation: 3910

The key is to initiate your Pair like this: Pair<View, String>(view, string) otherwise it complains.

Upvotes: 0

Gnzlt
Gnzlt

Reputation: 4572

This worked for me:

import android.support.v4.util.Pair

// ...    

val options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,
        Pair<View, String>(image, image.transitionName),
        Pair<View, String>(title, title.transitionName))

startActivity(intent, options.toBundle())

Upvotes: 4

Alex Facciorusso
Alex Facciorusso

Reputation: 2408

The answer is the * symbol before array variable:

import android.support.v4.util.Pair as AndroidPair

// ...    

val pair1 = AndroidPair<View, String>(fab, 
    getString(R.string.transition_fab))
val pair2 = AndroidPair<View, String>(findViewById(R.id.app_bar),
    getString(R.string.transition_appbar))

ActivityOptionsCompat.makeSceneTransitionAnimation(this@MyActivity,
    *arrayOf(pair1, pair2)).toBundle();

Upvotes: 11

Alexander Udalov
Alexander Udalov

Reputation: 32776

It may be the case that you're accidentally using kotlin.Pair instead of android.util.Pair. Please add the following import directive to the beginning of your file:

import android.util.Pair

Upvotes: 2

Related Questions