How to do SharedElement Transition with Viewpager between Fragments

1.2k views Asked by At

I have researched a lot on SharedElement Transitions , however I could only find Transitions for onclick event.

I want the animation between Fragments where the speed of animation is controlled by the user's scrolling speed. If the user stops in between while scrolling the objects should be still. Example : enter image description here In this image , the viewpager is in the middle of screen1 and screen2 and the animating objects are in stopped state.

These objects move from one screen to another and also change their positions.

The translation animations part I have figured out but how to achieve this shared element transition with viewpager between fragments. And moreover it should scroll/animate with the speed of finger swipe.

MainActivity.java

package com.karan.onboardanimation;

import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

private static final String TAG = "MainActivity";
private MyFragmentPagerAdapter pagerAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.d(TAG, "onCreate: ");

    ViewPager pager = (ViewPager) findViewById(R.id.pager);

    FragmentManager fm = getSupportFragmentManager();
    pagerAdapter = new MyFragmentPagerAdapter(fm);
    pager.setAdapter(pagerAdapter);
    pager.setCurrentItem(0);

}

}

FirstFragment.java- This fragment has an imageview which has to shared with second fragment when user is swiping on the viewpager.

package com.karan.onboardanimation;

import android.app.ActivityOptions;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;


public class FirstFragment extends Fragment {

private static final String TAG = "FirstFragment";

ImageView imageView;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (Build.VERSION.SDK_INT >= 21){

    }
    Log.d(TAG, "onCreate: ");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.d(TAG, "onCreateView: ");

    View view = inflater.inflate(R.layout.first_fragment, container, false);

    imageView = (ImageView) view.findViewById(R.id.img1);

    ViewPagerTransformer viewPagerTransformer = new ViewPagerTransformer();
    viewPagerTransformer.transformPage(imageView, 1);
    return view;
}


}

MyFragmentPagerAdapter.java

package com.karan.onboardanimation;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.util.Log;

class MyFragmentPagerAdapter extends FragmentPagerAdapter {

private static final String TAG = "MyFragmentPagerAdapter";

final int PAGE_COUNT = 2;

public MyFragmentPagerAdapter(FragmentManager fm) {
    super(fm);
    Log.d(TAG, "MyFragmentPagerAdapter: ");
}

@Override
public Fragment getItem(int position) {
    Log.d(TAG, "getItem: ");
    switch (position) {
        case 0:
            return new FirstFragment();
        case 1:
            return new SecondFragment();
        default:
            return null;
    }
}

@Override
public int getCount() {
    return PAGE_COUNT;
}
}

second_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#d02030"
android:orientation="vertical">

<ImageView
    android:id="@+id/img2"
    android:layout_width="100dp"
    android:layout_centerInParent="true"
    android:src="@drawable/orange_centre"
    android:transitionName="selectedIcon"
    android:layout_height="100dp" />
</RelativeLayout>

first_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<ImageView
    android:id="@+id/img1"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_gravity="center"
    android:src="@drawable/orange_centre" />

</LinearLayout>

Edit1- This question is not a duplicate of link mentioned in comment because that question is a sub part of my question. The difference is that the animation in that question happens on a click with a static speed. However in my question, the speed of animation must be equal to the speed of ViewPager swipe speed.

1

There are 1 answers

0
tompee On

You can try PageTransformer. It is not shared transition but more of view animation that is dependent on page position offset generated by swipe events.