Android 如何实现相同的转换?

Android 如何实现相同的转换?,android,material-design,transition,Android,Material Design,Transition,请帮忙,我正在尝试实现相同的转换 (一) (二) 但是我不知道我该怎么做。 左侧gif中的转换将列表元素转换为第二个活动的内容区域(工具栏保持不变)。在右侧的gif中,转换将列表元素转换为第二个活动的完整屏幕。下面的代码在左边的gif中提供了效果。但是,应该可以对解决方案进行一些小的修改,以在正确的gif中实现转换 注意这只对棒棒糖有效。但是,可以在旧设备上模拟不同的效果。此外,提供的代码的唯一目的是展示如何实现。不要直接在应用程序中使用此选项 主要活动: public class MainAc

请帮忙,我正在尝试实现相同的转换

(一)

(二)

但是我不知道我该怎么做。

左侧gif中的转换将列表元素转换为第二个活动的内容区域(工具栏保持不变)。在右侧的gif中,转换将列表元素转换为第二个活动的完整屏幕。下面的代码在左边的gif中提供了效果。但是,应该可以对解决方案进行一些小的修改,以在正确的gif中实现转换

注意这只对棒棒糖有效。但是,可以在旧设备上模拟不同的效果。此外,提供的代码的唯一目的是展示如何实现。不要直接在应用程序中使用此选项

主要活动:

public class MainActivity extends AppCompatActivity {

    MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
        ListView listView = (ListView) findViewById(R.id.list_view);

        myAdapter = new MyAdapter(this, 0, DataSet.get());

        listView.setAdapter(myAdapter);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, final View view, final int position, long id) {
                startTransition(view, myAdapter.getItem(position));
            }
        });
    }

    private void startTransition(View view, Element element) {
        Intent i = new Intent(MainActivity.this, DetailActivity.class);
        i.putExtra("ITEM_ID", element.getId());

        Pair<View, String>[] transitionPairs = new Pair[4];
        transitionPairs[0] = Pair.create(findViewById(R.id.toolbar), "toolbar"); // Transition the Toolbar
        transitionPairs[1] = Pair.create(view, "content_area"); // Transition the content_area (This will be the content area on the detail screen)

        // We also want to transition the status and navigation bar barckground. Otherwise they will flicker
        transitionPairs[2] = Pair.create(findViewById(android.R.id.statusBarBackground), Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME);
        transitionPairs[3] = Pair.create(findViewById(android.R.id.navigationBarBackground), Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME);
        Bundle b = ActivityOptionsCompat.makeSceneTransitionAnimation(MainActivity.this, transitionPairs).toBundle();

        ActivityCompat.startActivity(MainActivity.this, i, b);
    }
}
activity_detail.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:transitionName="toolbar" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#abc"
        android:orientation="vertical"
        android:paddingBottom="200dp"
        android:transitionName="content_area"
        android:elevation="10dp">

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>
TransitionHelper:

public class TransitionHelper {

    public static void fixSharedElementTransitionForStatusAndNavigationBar(final Activity activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
            return;

        final View decor = activity.getWindow().getDecorView();
        if (decor == null)
            return;
        activity.postponeEnterTransition();
        decor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public boolean onPreDraw() {
                decor.getViewTreeObserver().removeOnPreDrawListener(this);
                activity.startPostponedEnterTransition();
                return true;
            }
        });
    }

    public static void setSharedElementEnterTransition(final Activity activity, int transition) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
            return;
        activity.getWindow().setSharedElementEnterTransition(TransitionInflater.from(activity).inflateTransition(transition));
    }
}
公共类TransitionHelper{
状态和导航栏的公共静态void FixSharedElementTransition(最终活动){
if(Build.VERSION.SDK\u INT
那么这里的不同部分是什么:我们有两个活动。在转换过程中,四个视图在活动之间转换

工具栏:就像左边的gif一样,工具栏不会随着其他内容一起移动

ListView元素视图->成为DetailActivity的内容视图

状态栏和导航栏背景:如果我们不将这些视图添加到转换视图集中,它们将在转换过程中淡出并返回。但是,这需要延迟enter转换(请参阅:TransitionHelper.FixShareDelementTransitionForStatus和NavigationBar)

在MainActivity中,转换后的视图将添加到用于启动DetailActivity的捆绑包中。此外,在这两个活动中,转换视图都需要命名(transitionName)。这可以在布局xml中完成,也可以通过编程完成

在共享元素转换期间使用的默认转换集会影响视图的不同方面(例如:视图边界-请参见2)。但是,视图的高程差异不会设置动画。这就是为什么提出的解决方案使用自定义ElevationTransition

您也可以从google文档中看到这一点:


您需要将此参数放入第一个活动(xml)的imageview中:

android:transitionName=“您的交易名称”

当您想要打开其他活动时:

ImageView ImageView=findViewById(R.id.your\u image\u id)

Pair Pair=新对(imageView,ViewCompat.getTransitionName(imageView))

ActivityOptionCompat transitionActivityOptions=ActivityOptionCompat.MakeScenetTransitionAnimation(这一对)

Intent Intent=新的Intent(this,YourOtherActivity.class)

ActivityCompat.startActivityForResult(this,intent,0,transitionActivityOptions.toBundle())

在OtherActivity上向imageView添加相同的参数:

android:transitionName=“您的交易名称”


注意:它只适用于android API>21

谢谢回复,但这个逻辑已经实现了,我需要从卡转换到片段,如下所示
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:transitionName="toolbar" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#abc"
        android:orientation="vertical"
        android:paddingBottom="200dp"
        android:transitionName="content_area"
        android:elevation="10dp">

        <TextView
            android:id="@+id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
    android:transitionOrdering="together">
    <changeBounds/>
    <changeTransform/>
    <changeClipBounds/>
    <changeImageTransform/>
    <transition class="my.application.transitions.ElevationTransition"/>
</transitionSet>
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class ElevationTransition extends Transition {

    private static final String PROPNAME_ELEVATION = "my.elevation:transition:elevation";

    public ElevationTransition() {
    }

    public ElevationTransition(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void captureStartValues(TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    @Override
    public void captureEndValues(TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    private void captureValues(TransitionValues transitionValues) {
        Float elevation = transitionValues.view.getElevation();
        transitionValues.values.put(PROPNAME_ELEVATION, elevation);
    }

    @Override
    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
        if (startValues == null || endValues == null) {
            return null;
        }

        Float startVal = (Float) startValues.values.get(PROPNAME_ELEVATION);
        Float endVal = (Float) endValues.values.get(PROPNAME_ELEVATION);
        if (startVal == null || endVal == null || startVal.floatValue() == endVal.floatValue()) {
            return null;
        }

        final View view = endValues.view;
        ValueAnimator a = ValueAnimator.ofFloat(startVal, endVal);
        a.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                view.setElevation((float)animation.getAnimatedValue());
            }
        });

        return a;
    }
}
public class TransitionHelper {

    public static void fixSharedElementTransitionForStatusAndNavigationBar(final Activity activity) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
            return;

        final View decor = activity.getWindow().getDecorView();
        if (decor == null)
            return;
        activity.postponeEnterTransition();
        decor.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @TargetApi(Build.VERSION_CODES.LOLLIPOP)
            @Override
            public boolean onPreDraw() {
                decor.getViewTreeObserver().removeOnPreDrawListener(this);
                activity.startPostponedEnterTransition();
                return true;
            }
        });
    }

    public static void setSharedElementEnterTransition(final Activity activity, int transition) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
            return;
        activity.getWindow().setSharedElementEnterTransition(TransitionInflater.from(activity).inflateTransition(transition));
    }
}