Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create Shared Elements Transition from All/RoomSessionsFragment to SessionDetailFragment #564

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ class NavigationController @Inject constructor(private val activity: AppCompatAc
SessionDetailActivity.start(activity, session)
}

fun navigateToSessionDetailActivity(session: Session, sharedElement: Pair<View, String>) {
SessionDetailActivity.start(activity, session, sharedElement)
}

fun navigateToSessionsFeedbackActivity(session: Session.SpeechSession) {
SessionsFeedbackActivity.start(activity, session)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package io.github.droidkaigi.confsched2018.presentation.detail

import android.annotation.TargetApi
import android.app.Activity
import android.app.SharedElementCallback
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.content.Intent
import android.databinding.DataBindingUtil
import android.os.Build
import android.os.Bundle
import android.support.v4.app.ActivityOptionsCompat
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentStatePagerAdapter
import android.support.v4.util.Pair
import android.support.v4.view.ViewPager
import android.view.View
import dagger.android.AndroidInjector
import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector
Expand Down Expand Up @@ -46,17 +54,28 @@ class SessionDetailActivity :

private val pagerAdapter = SessionDetailFragmentPagerAdapter(supportFragmentManager)

private lateinit var sessions: List<Session.SpeechSession>

val firstSessionId: String by lazy {
intent.getStringExtra(EXTRA_SESSION_ID)
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportPostponeEnterTransition()

supportActionBar?.let {
it.setDisplayHomeAsUpEnabled(true)
it.setDisplayShowTitleEnabled(false)
}
sessionDetailViewModel.sessions.observe(this) { result ->
when (result) {
is Result.Success -> {
val sessions = result.data
sessions = result.data
bindSessions(sessions)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
removeSharedElements()
}
}
is Result.Failure -> {
Timber.e(result.e)
Expand All @@ -72,8 +91,7 @@ class SessionDetailActivity :
val firstAssign = pagerAdapter.sessions.isEmpty() && sessions.isNotEmpty()
pagerAdapter.sessions = sessions
if (firstAssign) {
val sessionId = intent.getStringExtra(EXTRA_SESSION_ID)
val position = sessions.indexOfFirst { it.id == sessionId }
val position = sessions.indexOfFirst { it.id == firstSessionId }
binding
.detailSessionsPager
.setCurrentItem(
Expand All @@ -83,6 +101,23 @@ class SessionDetailActivity :
}
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun removeSharedElements() {
setEnterSharedElementCallback(object : SharedElementCallback() {
override fun onMapSharedElements(
names: MutableList<String>?,
sharedElements: MutableMap<String, View>?) {
super.onMapSharedElements(names, sharedElements)

val currentFragment = pagerAdapter.findFragmentByPosition(
binding.detailSessionsPager,
binding.detailSessionsPager.currentItem)
sharedElements?.clear()
currentFragment.hideButton()
}
})
}

override fun supportFragmentInjector(): AndroidInjector<Fragment> = dispatchingAndroidInjector

override fun onBackPressed() {
Expand All @@ -102,29 +137,53 @@ class SessionDetailActivity :
class SessionDetailFragmentPagerAdapter(
fragmentManager: FragmentManager
) : FragmentStatePagerAdapter(fragmentManager) {

var sessions: List<Session.SpeechSession> = listOf()
set(value) {
field = value
notifyDataSetChanged()
}

override fun getItem(position: Int): Fragment {
return SessionDetailFragment.newInstance(sessions[position].id)
return SessionDetailFragment.newInstance(sessions[position].id, sessions[position].id)
}

override fun getCount(): Int = sessions.size

fun findFragmentByPosition(viewPager: ViewPager, position: Int): SessionDetailFragment {
return instantiateItem(viewPager, position) as SessionDetailFragment
}
}

companion object {
const val EXTRA_SESSION_ID = "EXTRA_SESSION_ID"
private const val EXTRA_TRANSITION_NAME = "EXTRA_TRANSITION_NAME"

fun start(context: Context, session: Session) {
context.startActivity(createIntent(context, session.id))
}

fun start(activity: Activity, session: Session, sharedElement: Pair<View, String>) {
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
activity,
sharedElement)
val intent = createIntent(activity, session.id, sharedElement)
activity.startActivity(intent, options.toBundle())
}

fun createIntent(context: Context, sessionId: String): Intent {
return Intent(context, SessionDetailActivity::class.java).apply {
putExtra(EXTRA_SESSION_ID, sessionId)
}
}

private fun createIntent(context: Context, sessionId: String, sharedElement: Pair<View,
String>):
Intent {
return Intent(context, SessionDetailActivity::class.java).apply {
putExtra(EXTRA_SESSION_ID, sessionId)
putExtra(EXTRA_TRANSITION_NAME, sharedElement.second)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package io.github.droidkaigi.confsched2018.presentation.detail

import android.annotation.TargetApi
import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.graphics.drawable.Animatable
import android.os.Build
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.view.ViewCompat
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -16,6 +20,7 @@ import io.github.droidkaigi.confsched2018.model.Session
import io.github.droidkaigi.confsched2018.presentation.NavigationController
import io.github.droidkaigi.confsched2018.presentation.Result
import io.github.droidkaigi.confsched2018.util.SessionAlarm
import io.github.droidkaigi.confsched2018.util.ext.addOnetimeOnPreDrawListener
import io.github.droidkaigi.confsched2018.util.ext.context
import io.github.droidkaigi.confsched2018.util.ext.drawable
import io.github.droidkaigi.confsched2018.util.ext.observe
Expand Down Expand Up @@ -75,6 +80,15 @@ class SessionDetailFragment : Fragment(), Injectable {
}

binding.toolbar.setNavigationOnClickListener { activity?.finish() }

val firstSessionId = (activity as? SessionDetailActivity)?.firstSessionId ?: return
val transitionName = arguments!!.getString(EXTRA_TRANSITION_NAME)

if (!TextUtils.isEmpty(transitionName)
&& firstSessionId == transitionName
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
initViewTransitions(view)
}
}

private fun bindSession(session: Session.SpeechSession) {
Expand Down Expand Up @@ -110,17 +124,41 @@ class SessionDetailFragment : Fragment(), Injectable {
binding.nextSession = nextSession
}

fun hideButton() {
binding.fab.visibility = View.INVISIBLE
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private fun initViewTransitions(view: View) {
binding.speakerSummary.addOnetimeOnPreDrawListener {
ViewCompat.setTransitionName(
view.findViewById<View>(R.id.speaker_summary),
arguments!!.getString(EXTRA_TRANSITION_NAME))
activity?.supportStartPostponedEnterTransition()
}
}

interface OnClickBottomAreaListener {
fun onClickPrevSession()
fun onClickNextSession()
}

companion object {
const val EXTRA_SESSION_ID = "EXTRA_SESSION_ID"
const val EXTRA_TRANSITION_NAME = "EXTRA_TRANSITION_NAME"

fun newInstance(sessionId: String): SessionDetailFragment = SessionDetailFragment().apply {
arguments = Bundle().apply {
putString(EXTRA_SESSION_ID, sessionId)
}
}

fun newInstance(sessionId: String, transitionName: String): SessionDetailFragment =
SessionDetailFragment().apply {
arguments = Bundle().apply {
putString(EXTRA_SESSION_ID, sessionId)
putString(EXTRA_TRANSITION_NAME, transitionName)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.os.Bundle
import android.support.transition.TransitionInflater
import android.support.transition.TransitionManager
import android.support.v4.app.Fragment
import android.support.v4.util.Pair
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SimpleItemAnimator
Expand Down Expand Up @@ -91,9 +92,14 @@ class FavoriteSessionsFragment : Fragment(), Injectable {
private fun setupRecyclerView() {
val groupAdapter = GroupAdapter<ViewHolder>().apply {
add(sessionsSection)
setOnItemClickListener({ item, _ ->
setOnItemClickListener({ item, v ->
val sessionItem = item as? SpeechSessionItem ?: return@setOnItemClickListener
navigationController.navigateToSessionDetailActivity(sessionItem.session)
val sharedElement = Pair(
v.findViewById<View>(R.id.speaker_summary),
sessionItem.session.id)
navigationController.navigateToSessionDetailActivity(
sessionItem.session,
sharedElement)
})
}
binding.sessionsRecycler.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.util.Pair
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.xwray.groupie.GroupAdapter
import com.xwray.groupie.ViewHolder
import io.github.droidkaigi.confsched2018.R
import io.github.droidkaigi.confsched2018.databinding.FragmentSearchSessionsBinding
import io.github.droidkaigi.confsched2018.di.Injectable
import io.github.droidkaigi.confsched2018.model.Session
Expand Down Expand Up @@ -70,9 +72,14 @@ class SearchSessionsFragment : Fragment(), Injectable, TabLayoutItem {
private fun setupRecyclerView() {
val groupAdapter = GroupAdapter<ViewHolder>().apply {
add(sessionsSection)
setOnItemClickListener({ item, _ ->
setOnItemClickListener({ item, v ->
val sessionItem = (item as? HorizontalSessionItem) ?: return@setOnItemClickListener
navigationController.navigateToSessionDetailActivity(sessionItem.session)
val sharedElement = Pair(
v.findViewById<View>(R.id.speaker_summary),
sessionItem.session.id)
navigationController.navigateToSessionDetailActivity(
sessionItem.session,
sharedElement)
})
}
binding.searchSessionRecycler.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.os.Bundle
import android.support.transition.TransitionInflater
import android.support.transition.TransitionManager
import android.support.v4.app.Fragment
import android.support.v4.util.Pair
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SimpleItemAnimator
Expand Down Expand Up @@ -112,9 +113,14 @@ class AllSessionsFragment : Fragment(), Injectable, CurrentSessionScroller, TabL
private fun setupRecyclerView() {
val groupAdapter = GroupAdapter<ViewHolder>().apply {
add(sessionsSection)
setOnItemClickListener({ item, _ ->
setOnItemClickListener({ item, v ->
val sessionItem = item as? SpeechSessionItem ?: return@setOnItemClickListener
navigationController.navigateToSessionDetailActivity(sessionItem.session)
val sharedElement = Pair(
v.findViewById<View>(R.id.speaker_summary),
sessionItem.session.id)
navigationController.navigateToSessionDetailActivity(
sessionItem.session,
sharedElement)
})
}
binding.sessionsRecycler.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.os.Bundle
import android.support.transition.TransitionInflater
import android.support.transition.TransitionManager
import android.support.v4.app.Fragment
import android.support.v4.util.Pair
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.SimpleItemAnimator
Expand Down Expand Up @@ -120,9 +121,14 @@ class RoomSessionsFragment : Fragment(), Injectable, CurrentSessionScroller, Tab
private fun setupRecyclerView() {
val groupAdapter = GroupAdapter<ViewHolder>().apply {
add(sessionsSection)
setOnItemClickListener({ item, _ ->
setOnItemClickListener({ item, v ->
val sessionItem = item as? SpeechSessionItem ?: return@setOnItemClickListener
navigationController.navigateToSessionDetailActivity(sessionItem.session)
val sharedElement = Pair(
v.findViewById<View>(R.id.speaker_summary),
sessionItem.session.id)
navigationController.navigateToSessionDetailActivity(
sessionItem.session,
sharedElement)
})
}
binding.sessionsRecycler.apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import android.os.Build
import android.os.Bundle
import android.support.design.widget.BottomSheetDialog
import android.support.v4.app.Fragment
import android.support.v4.util.Pair
import android.support.v4.view.ViewCompat
import android.support.v7.widget.LinearLayoutManager
import android.text.TextUtils
Expand Down Expand Up @@ -214,9 +215,14 @@ class SpeakerDetailFragment : Fragment(), Injectable {
private fun setupRecyclerView() {
val groupAdapter = GroupAdapter<ViewHolder>().apply {
add(sessionsSection)
setOnItemClickListener({ item, _ ->
setOnItemClickListener({ item, v ->
val sessionItem = item as? SpeechSessionItem ?: return@setOnItemClickListener
navigationController.navigateToSessionDetailActivity(sessionItem.session)
val sharedElement = Pair(
v.findViewById<View>(R.id.speaker_summary),
sessionItem.session.id)
navigationController.navigateToSessionDetailActivity(
sessionItem.session,
sharedElement)
})
}
val linearLayoutManager = LinearLayoutManager(context)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.arch.lifecycle.ViewModelProvider
import android.arch.lifecycle.ViewModelProviders
import android.os.Bundle
import android.support.v4.app.Fragment
import android.support.v4.util.Pair
import android.support.v7.widget.LinearLayoutManager
import android.view.LayoutInflater
import android.view.View
Expand Down Expand Up @@ -78,9 +79,14 @@ class TopicDetailFragment : Fragment(), Injectable {
private fun setupRecyclerView() {
val groupAdapter = GroupAdapter<ViewHolder>().apply {
add(sessionsSection)
setOnItemClickListener { item, _ ->
setOnItemClickListener { item, v ->
val sessionItem = item as? SpeechSessionItem ?: return@setOnItemClickListener
navigationController.navigateToSessionDetailActivity(sessionItem.session)
val sharedElement = Pair(
v.findViewById<View>(R.id.speaker_summary),
sessionItem.session.id)
navigationController.navigateToSessionDetailActivity(
sessionItem.session,
sharedElement)
}
}
val linearLayoutManager = LinearLayoutManager(context)
Expand Down
Loading