Android共享元素动画对我不起作用

时间:2015-04-14 16:03:49

标签: android android-animation android-5.0-lollipop android-transitions shared-element-transition

我正在关注https://developer.android.com/training/material/animations.html上的指示并尝试在活动之间实现共享元素的动画,但它对我不起作用,我搜索了很多但找不到答案,是否有人可以帮忙看看吗?非常感谢你!

我的步骤:

1,在我的“res”目录下创建一个目录“transition”,然后在那里创建一个list_to_details.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
    <changeImageTransform/>
</transitionSet>

2,在我的“res”目录下创建一个目录“values-v21”,然后在那里创建一个文件styles.xml(设置上面在步骤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,将应用程序主题设置为“新主题文件

中定义的”AppTheme“
<application
        android:name="com.myapp.MyApplication"
        android:allowBackup="false"
        android:icon="@drawable/icon"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

4,将transitionName添加到活动A和B中的共享元素: A:      B:     

5,添加代码以在活动A中启动活动B:

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,尝试应用程序,但它不播放动画,我猜的原因可能是我在活动B中有一个异步任务加载图像,但是在我尝试postponeEnterTransition之后它仍然不起作用,我还尝试了getSharedElementEnterTransition,但是调试器显示它是null,请参阅我的代码:

@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
        }
      });
    }
  }
}

我的步骤有什么不妥或错过了吗? 任何帮助都非常感谢!

1 个答案:

答案 0 :(得分:4)

让它成功。

影响的两个问题:

  1. 我需要使用java代码更改而不是XML更改(不知道为什么,我想我的Android SDK中可能存在解决XML更改的问题)
  2. 我需要添加window.requestFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)以使其正常工作,Android开发人员网站中未提及此功能,但有人在某些有问题的流量问题中提及此功能。