简体   繁体   中英

Android Shared Element Animation doesn't work for me

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!

Just made it work.

Two problems that affect:

  1. I need to use java code change instead of the XML changes(not sure why, I guess maybe there's something wrong in my Android SDK to parse the XML changes)
  2. I need to add window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS) to make it work, this feature is NOT mentioned in the Android developer site, but someone mentioned it in some stakeoverflow question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM