10

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
Josh Feinberg
  • 133
  • 1
  • 8
  • What are the errors the compiler is reporting on these examples? – Andrey Breslav Sep 16 '15 at 06:31
  • Error:(70, 84) The spread operator (*foo) may only be applied in a vararg position and Error:(70, 84) Type mismatch: inferred type is kotlin.Pair but android.view.View! was expected Error:(70, 101) Type mismatch: inferred type is kotlin.Pair but kotlin.String! was expected – Josh Feinberg Sep 16 '15 at 13:02

5 Answers5

11

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();
Alex Facciorusso
  • 2,290
  • 3
  • 21
  • 34
4

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())
Gnzlt
  • 4,383
  • 2
  • 22
  • 24
2

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
Alexander Udalov
  • 31,429
  • 6
  • 80
  • 66
  • Nope, even tried doing `android.util.Pair.create(imageView, imageView.getTransitionName());` – Josh Feinberg Sep 17 '15 at 00:09
  • Does the compilation error message change after you do that? – Alexander Udalov Sep 18 '15 at 00:18
  • Well, the error message mentions kotlin.Pair so it must be used somehow in your code, unless there's something weird going on. Please try to create a [minimal reproducible sample](http://stackoverflow.com/help/mcve) and post the Kotlin code here so that we can investigate and help you. Thanks! – Alexander Udalov Sep 19 '15 at 01:46
  • I have updated my answer with what I believe to be a minimal reproducible sample. thank you for the help – Josh Feinberg Sep 19 '15 at 05:35
1

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)
  }
aslamhossin
  • 1,217
  • 12
  • 22
0

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

Joshua King
  • 3,450
  • 1
  • 17
  • 19