使用自定义视图与SharedElement Activity转换

12

我正在开发一个概念验证,其中我有几个自定义视图在TableLayout中。当其中一个视图被点击时,我希望将该视图展开成一个新的 Activity,并实现与此处所见类似的效果。

从我的研究来看,似乎使用共享元素转换是实现这一目标的方法。但是,我无法正确地使它工作,并且想知道是否是因为我正在使用自己的自定义视图。

具体而言,淡入淡出效果是发生的,但缩放和平移动作却没有发生。请查看下面的GIF以了解我的情况。在示例中,我点击了左上角的圆圈,我希望将其转换为新活动中的完整圆圈。当按下返回按钮时,问题也可以看到。

enter image description here

我认为这是不正确的,因为视图必须被绘制,但是否有办法进一步自定义我的视图以使其工作?我发现这种类型的转换的所有示例都包括ImageViews、Buttons和TextViews。

下面是相关源代码。我的自定义视图很大,不包含任何特殊代码,只覆盖了onDraw()和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());
            }
        });

    }
}

详情页.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>

样式.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>
2个回答

5

请在您的DetailActivity中尝试使用postponeEnterTransition()startPostponedEnterTransition()

postponeEnterTransition()用于暂时延迟转换,直到共享元素已正确测量和布局。

startPostponedEnterTransition()安排共享元素过渡在活动的视图层次结构中测量和布置共享元素后立即启动。

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

-1

我认为你的问题不在于你有一个自定义视图... 我总是用我的自定义视图进行这些转换,它们都能正常工作。

我可以看到这段代码:

ActivityOptions options = ActivityOptions
                        .makeSceneTransitionAnimation(MainActivity.this, view1, "profile");
                // start the new activity 
                startActivity(intent, options.toBundle());

不能做你想要的事情。

以下是你需要做的:

首先,使用转换创建你的 XML:

第一个活动

<YouCustomView
     android:id="@+id/someId"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:transitionName="@string/someTransition">

第二个活动:

<YouCustomView
         android:id="@+id/someOtherId"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:transitionName="@string/someTransition">

其次,当您启动第二个活动时,请按照以下方式进行:

        ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(
    this, new Pair<>(findViewById(R.id.someId), getString(R.string.someTransition))

startActivity(intent, activityOptions.toBundle());

你忘了添加视图的Pair和转换的名称。加上这个,你的转换就会正常工作。你的View是自定义View并不影响动画。

编码愉快!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接