oligazar
6/11/2017 - 3:52 AM

Activity Shared Element Transitions Delegates

Activity Shared Element Transitions Delegates

/**
 * Created by Admin on 6/11/17.
 * Delegate for Details Activity that handles Shared Element Transition
 */

abstract class ActivitySharedElementTransitionDetailDelegate(val activity: AppCompatActivity, val getSharedElement: () -> View) {

    abstract var mStartingPosition: Int  // position we get from Activity A
    abstract var mCurrentPosition: Int   // current position of ViewPager
    private var mIsReturning = false
    
    val mCallback = object: SharedElementCallback() {
        override fun onMapSharedElements(names: MutableList<String>?, sharedElements: MutableMap<String, View>?) {
            if (mIsReturning) {
                val sharedElement = getSharedElement().findViewById(R.id.imagePreview)
                if (sharedElement == null) {
                    // If shared element is null, then it has been scrolled off screen and
                    // no longer visible. In this case we cancel the shared element transition by
                    // removing the shared element from the shared elements map.
                    names?.clear()
                    sharedElements?.clear()
                } else if (mStartingPosition != mCurrentPosition) {
                    // If the user has swiped to a different ViewPager page, then we need to
                    // remove the old shared element and replace it with the new shared element
                    // that should be transitioned instead.
                    names?.clear()
                    names?.add(ViewCompat.getTransitionName(sharedElement))
                    sharedElements?.clear()
                    sharedElements?.put(ViewCompat.getTransitionName(sharedElement), sharedElement)
                }
            }
        }
    }
    
    fun onCreate() {
        ActivityCompat.postponeEnterTransition(activity)
        ActivityCompat.setEnterSharedElementCallback(activity, mCallback)
    }

    fun finishAfterTransition() {
        mIsReturning = true
        val data = Intent()
        data.putExtra(SlideShowActivity.EXTRA_STARTING_POSITION, mStartingPosition)
        data.putExtra(SlideShowActivity.EXTRA_CURRENT_POSITION, mCurrentPosition)
        activity.setResult(Activity.RESULT_OK, data)
    }

    // To be called in adapter or inside fragment
    fun mStartPostponedEnterTransition(view: View?) {
        view?.viewTreeObserver?.addOnPreDrawListener(object: ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                view.viewTreeObserver.removeOnPreDrawListener(this)
                ActivityCompat.startPostponedEnterTransition(activity)
                return true
            }
        })
    }
}

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_slide_show)

        mTransitionDelegate = object: ActivitySharedElementTransitionDetailDelegate(this, { mCurrentView }) {
            override var mStartingPosition: Int = 0
            override var mCurrentPosition: Int = 0
        }

        mTransitionDelegate.onCreate()

        paths = intent.extras.getStringArrayList(PATHS)
        mTransitionDelegate.mStartingPosition = intent.extras.getInt(EXTRA_STARTING_POSITION)
        mTransitionDelegate.mCurrentPosition = savedInstanceState?.getInt(STATE_CURRENT_PAGE_POSITION) ?: mTransitionDelegate.mStartingPosition

        myViewPagerAdapter = FullScreenPagerAdapter(paths, mTransitionDelegate, { obj: Any? ->
            mCurrentView = obj as View
        }, { toggle() })

        viewPager.adapter = myViewPagerAdapter
        viewPager.addOnPageChangeListener(object: ViewPager.SimpleOnPageChangeListener() {
            override fun onPageSelected(position: Int) {
                displayMetaInfo(position)
                mTransitionDelegate.mCurrentPosition = position
            }
        })
        mContentView = viewPager

        setCurrentItem(mTransitionDelegate.mCurrentPosition)
    }

    override fun finishAfterTransition() {
        mTransitionDelegate.finishAfterTransition()
        super.finishAfterTransition()
    }