Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SharedElement Activity transitions with a custom View

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.

enter image description here

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>
like image 454
RScottCarson Avatar asked Jan 11 '17 23:01

RScottCarson


1 Answers

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;
            }
        });
}
like image 96
Jaymin Panchal Avatar answered Oct 30 '22 09:10

Jaymin Panchal