Reputation: 61
I am following the instruction on https://developer.android.com/training/material/animations.html and trying to implement an animation with shared element between activities, but it doesn't work for me, I searched a lot but could not find an answer, is there anyone who can help to take a look? Thank you so much!
My steps:
1, create a directory "transition" under my "res" directory, and then create a file list_to_details.xml there:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
<changeImageTransform/>
</transitionSet>
2, create a directory "values-v21" under my "res" directory, and then create a file styles.xml there(setting the transition defined above in step 1):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="android:Theme.Material">
<!-- enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
<!-- specify enter and exit transitions -->
<item name="android:windowSharedElementEnterTransition">@transition/list_to_detail</item>
<item name="android:windowSharedElementExitTransition">@transition/list_to_detail</item>
</style>
</resources>
3, set the application theme to "AppTheme" which is defined in the new styles file
<application
android:name="com.myapp.MyApplication"
android:allowBackup="false"
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
4, Add the transitionName to the shared element in Activity A and B: A: B:
5, Add code to start Activity B in Activity A:
expandedImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(DetailDemoActivity.this, v, "todetail");
Intent intent = new Intent(DetailDemoActivity.this, AnotherDetailDemoActivity.class);
intent.putExtra("original_url", originalUrl);
ActivityCompat.startActivity(DetailDemoActivity.this, intent, options.toBundle());
}
});
6, try the app but it doesn't play animation, I am guessing the reason might be that I have an async task in Activity B to load the image, but it still doesn't work after I tried postponeEnterTransition, I also tried getSharedElementEnterTransition, but debugger showed it was a null, see my code:
@Override
protected void onCreate(Bundle savedInstanceState) {
postponeEnterTransition();
Intent intent = this.getIntent();
originalUrl = intent.getStringExtra("original_url");
GetBigImageAsyncTask getBigImageTask = new GetBigImageAsyncTask();
getBigImageTask.execute();
super.onCreate(savedInstanceState);
setContentView(R.layout.another_detail_demo);
// I have also tried setTransitionName() here but it doesn't work too
}
private void scheduleStartPostponedTransition(final View sharedElement) {
sharedElement.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
sharedElement.getViewTreeObserver().removeOnPreDrawListener(this);
startPostponedEnterTransition();
return true;
}
});
}
private class GetBigImageAsyncTask extends AsyncTask<Object, Void, Bitmap> {
@Override
protected Bitmap doInBackground(Object... urls) {
InputStream input = null;
HttpURLConnection connection = null;
try {
URL url = new URL(originalUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (Exception e) {
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
if (input != null) {
try {
input.close();
} catch (Exception e) {
}
}
}
}
@Override
protected void onPostExecute(Bitmap result) {
ImageView expandedImageView =
(ImageView) findViewById(R.id.another_demo_expanded_image);
expandedImageView.setImageDrawable(new BitmapDrawable(result));
scheduleStartPostponedTransition(expandedImageView);
final Transition transition = AnotherDetailDemoActivity.this.getWindow().getSharedElementEnterTransition();
// In fact here the object transition is null
if (transition != null) {
// There is an entering shared element transition so add a listener to it
transition.addListener(new Transition.TransitionListener() {
@Override
public void onTransitionEnd(Transition transition) {
transition.removeListener(this);
}
@Override
public void onTransitionStart(Transition transition) {
}
@Override
public void onTransitionCancel(Transition transition) {
// Make sure we remove ourselves as a listener
transition.removeListener(this);
}
@Override
public void onTransitionPause(Transition transition) {
// No-op
}
@Override
public void onTransitionResume(Transition transition) {
// No-op
}
});
}
}
}
Is there anything wrong or missed in my steps? Any help is highly appreciated!
Upvotes: 2
Views: 2399
Reputation: 61
Just made it work.
Two problems that affect:
Upvotes: 4