小编Mon*_*sor的帖子

与CoordinatorLayout和CollapsingToolbarLayout结合使用时,共享元素转换不起作用

我的应用程序主屏幕包含图像的网格视图.当用户选择图像时,使用共享元素转换开始细节活动,该共享元素转换将所选择的网格图像动画化为位于细节活动中的CardView中的配对图像.

升级我的详细视图XML布局以包含CoordinatorLayout以及CollapsingToolbarLayout后,共享元素转换将图像视图移动到详细活动中的错误位置("enter"活动).如果在包含目标图像视图的CardView上方没有CollapsingToolBarLayout,框架似乎会将整个AppBarLayout和内部CollapsingToobarLayout的偏移量和动画放大到图像的大致位置.

通过将activityView(带有transitionName)添加到activity_detail.xml中的3个CardView中的任何一个,可以在Chris Banes的cheesesquare示例应用程序中复制该问题:

<ImageView
 android:id="@+id/imageView"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:src="@mipmap/ic_launcher"
 android:transitionName="sharedImage" />
Run Code Online (Sandbox Code Playgroud)

然后在CheeseListFragment.java中的onBindViewHolder中设置共享元素转换,如下所示:

@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.mBoundString = mValues.get(position);
        holder.mTextView.setText(mValues.get(position));

        holder.mView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Context context = v.getContext();
                Intent intent = new Intent(context, CheeseDetailActivity.class);
                intent.putExtra(CheeseDetailActivity.EXTRA_NAME, holder.mBoundString);

                holder.mImageView.setTransitionName("sharedImage");                        
                ActivityOptionsCompat options = ActivityOptionsCompat.
                        makeSceneTransitionAnimation(
                                getActivity(v.getContext()),
                                            holder.mImageView,                     
                                            "sharedImage");
                ActivityCompat.StartActivity((MyActivity) context, intent, options.toBundle());
            }
        });

        Glide.with(holder.mImageView.getContext())
                .load(Cheeses.getRandomCheeseDrawable())
                .fitCenter()
                .into(holder.mImageView);
    }
Run Code Online (Sandbox Code Playgroud)

如果运行应用程序,并单击奶酪列表项,您将了解过渡动画如何将图像移动到目标活动视图中的错误(太高)偏移.动画完成后,图像将"扭曲"到正确的位置.

任何关于可能的解决方法的想法都会非常受欢迎.

animation android shared-element-transition android-coordinatorlayout android-collapsingtoolbarlayout

12
推荐指数
1
解决办法
3072
查看次数

Android共享元素从初始屏幕转换为主要活动

在显示主要活动之前,我的应用程序显示启动画面1秒钟.启动画面和主活动共享一个公共图像,该图像是从启动画面的中心到主活动布局顶部的动画所必需的.

如果<layer-list>在主要活动中将启动画面实现为背景图像(参见启动画面正确的方式如何制作启动画面?),那么如何完成此动画并不明显,我决定实现启动画面作为正常活动,并使用共享元素转换为两个活动之间的图像设置动画.最初,我onCreate()在splash活动中使用了以下实现:

public class SplashActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);

        ImageView imageView = (ImageView)findViewById(R.id.imageView);
        String transitionName = ViewCompat.getTransitionName(imageView);
        Intent intent = new Intent(this, LoginActivity.class);
        ActivityOptionsCompat options =
                ActivityOptionsCompat.makeSceneTransitionAnimation(
                        this, imageView, transitionName);

        imageView.postDelayed(() -> {
            ActivityCompat.startActivity(SplashActivity.this, intent, options.toBundle());
            finish();
        }, 1000);
    }
}
Run Code Online (Sandbox Code Playgroud)

这种方法存在两个问题:

  1. 在调用finish()之后立即调用startActivity()会导致在动画开始之前隐藏/销毁启动活动窗口,这导致主屏幕在动画期间暂时闪烁进入视图.
  2. 从主活动按回来会自动触发共享元素返回转换,导致主活动窗口关闭后图像在主屏幕上显示为500毫秒.返回转换失败,因为splash活动已经调用了finish(),因此不再在后台堆栈上.

为了解决第一个问题,我将finish()调用包装在postDelay()Runnable中,以确保只有在共享元素转换完成后才会调用它.在我的应用程序中有1500毫秒的延迟,但应根据其他用例所需的时间调整该值.

...

imageView.postDelayed(() -> {
    ActivityCompat.startActivity(SplashActivity.this, intent, options.toBundle());
    imageView.postDelayed(this::finish, 1500);
}, 1000);
Run Code Online (Sandbox Code Playgroud)

为了解决第二个问题,我重写了主活动的onBackPressed()方法直接调用, …

android splash-screen android-animation android-transitions shared-element-transition

7
推荐指数
1
解决办法
1642
查看次数