I am working on a proof-of-concept where I have a few custom views in a TableLayout. When one of the Views is clicked I want to animate the view expanding into a new Activity. The effect I want to achieve is similar to what is seen here.
From my research, it seems the way to do this is with shared element Transitions. However, I can't get it to work correctly and I am wondering if it is because I am using my own custom View.
Specifically, the fades are happening, but the scaling and translating motions are not. Check the GIF below to see where I am. In the example I click the upper left circle, which I want to transform to the full circle in the new activity. The issue can also be seen when the back button is pressed.
I believe it is incorrect because the View must be drawn, but is there a way to customize my View further to make this work? All of the examples I have found of this type of transition have consisted of ImageViews, Buttons, and TextViews.
Below is the relevant source. My custom view is large and doesn't contain any special code, just overrides onDraw() and onMeasure().
MainActivity.java
package com.rscottcarson.circleschedulertest;
import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Intent;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Toast;
public class MainActivity extends Activity {
private View view1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view1 = findViewById(R.id.circle1);
view1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
// create the transition animation - the images in the layouts
// of both activities are defined with android:transitionName="profile"
ActivityOptions options = ActivityOptions
.makeSceneTransitionAnimation(MainActivity.this, view1, "profile");
// start the new activity
startActivity(intent, options.toBundle());
}
});
}
}
DetailActivity.java
package com.rscottcarson.circleschedulertest;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
public class DetailActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
}
}
change_image_trans.xml
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeTransform />
</transitionSet>
styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<item name="android:windowActivityTransitions">true</item>
<item name="android:windowContentTransitions">true</item>
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementEnterTransition">
@transition/change_image_trans</item>
<!-- specify shared element transitions -->
<item name="android:windowSharedElementExitTransition">
@transition/change_image_trans</item>
</style>
</resources>
Just try with postponeEnterTransition()
and startPostponedEnterTransition()
in your DetailActivity
postponeEnterTransition()
used to temporarily delay the transition until the shared elements have been properly measured and laid out.
startPostponedEnterTransition()
Schedules the shared element transition to be started immediately after the shared element has been measured and laid out within the activity's view hierarchy.
DetailActivity.java
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
postponeEnterTransition();
}
private void scheduleStartPostponedTransition(final View sharedElement) {
sharedElement.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With