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

Fix navigation bar animation #3859

Merged
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 @@ -9,6 +9,7 @@ import android.transition.TransitionManager
import android.view.View
import androidx.activity.viewModels
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.fillMaxWidth
Expand Down Expand Up @@ -185,8 +186,8 @@ class ProgramEventDetailActivity :

AnimatedVisibility(
visible = uiState.items.size > 1 && isBackdropActive.not(),
enter = slideInVertically { it },
exit = slideOutVertically { it },
enter = slideInVertically(animationSpec = tween(200)) { it },
exit = slideOutVertically(animationSpec = tween(200)) { it },
) {
NavigationBar(
modifier = Modifier.fillMaxWidth(),
Expand Down Expand Up @@ -321,13 +322,13 @@ class ProgramEventDetailActivity :
val transition: Transition = ChangeBounds()
transition.addListener(object : Transition.TransitionListener {
override fun onTransitionStart(transition: Transition) {
programEventsViewModel.updateBackdrop(backDropActive)
if (!backDropActive) {
binding.clearFilters.hide()
}
}

override fun onTransitionEnd(transition: Transition) {
programEventsViewModel.updateBackdrop(backDropActive)
if (backDropActive) {
binding.clearFilters.show()
}
Expand All @@ -345,11 +346,11 @@ class ProgramEventDetailActivity :
/*No action needed*/
}
})
backDropActive = !backDropActive

transition.duration = 200
TransitionManager.beginDelayedTransition(binding.backdropLayout, transition)

backDropActive = !backDropActive

val initSet = ConstraintSet()
initSet.clone(binding.backdropLayout)
if (backDropActive) {
Expand All @@ -360,6 +361,20 @@ class ProgramEventDetailActivity :
ConstraintSet.BOTTOM,
16.dp,
)
initSet.connect(
R.id.fragmentContainer,
ConstraintSet.BOTTOM,
ConstraintSet.PARENT_ID,
ConstraintSet.BOTTOM,
0,
)
initSet.connect(
R.id.addEventButton,
ConstraintSet.BOTTOM,
R.id.fragmentContainer,
ConstraintSet.BOTTOM,
16.dp,
)
} else {
initSet.connect(
R.id.fragmentContainer,
Expand All @@ -368,6 +383,20 @@ class ProgramEventDetailActivity :
ConstraintSet.BOTTOM,
0,
)
initSet.connect(
R.id.fragmentContainer,
ConstraintSet.BOTTOM,
R.id.navigationBar,
ConstraintSet.TOP,
0,
)
initSet.connect(
R.id.addEventButton,
ConstraintSet.BOTTOM,
R.id.navigationBar,
ConstraintSet.TOP,
16.dp,
)
}
initSet.applyTo(binding.backdropLayout)
}
Expand Down Expand Up @@ -424,12 +453,15 @@ class ProgramEventDetailActivity :

override fun showPeriodRequest(periodRequest: PeriodRequest) {
if (periodRequest == PeriodRequest.FROM_TO) {
DateUtils.getInstance().fromCalendarSelector(this.context) { datePeriod: List<DatePeriod?>? ->
FilterManager.getInstance().addPeriod(datePeriod)
}
DateUtils.getInstance()
.fromCalendarSelector(this.context) { datePeriod: List<DatePeriod?>? ->
FilterManager.getInstance().addPeriod(datePeriod)
}
} else {
val onFromToSelector =
OnFromToSelector { datePeriods -> FilterManager.getInstance().addPeriod(datePeriods) }
OnFromToSelector { datePeriods ->
FilterManager.getInstance().addPeriod(datePeriods)
}

DateUtils.getInstance().showPeriodDialog(
this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import org.dhis2.commons.filters.workingLists.WorkingListViewModel
import org.dhis2.commons.filters.workingLists.WorkingListViewModelFactory
import org.dhis2.databinding.FragmentComposeHolderBinding
import org.dhis2.usescases.general.FragmentGlobalAbstract
import org.dhis2.usescases.programEventDetail.ProgramEventDetailActivity
import org.dhis2.usescases.programEventDetail.ProgramEventDetailViewModel
Expand Down Expand Up @@ -48,16 +48,18 @@ class EventListFragment : FragmentGlobalAbstract() {
programEventsViewModel.eventClicked.value = Pair(eventUid, orgUnitUid)
}

return ComposeView(requireContext()).apply {
val binding = FragmentComposeHolderBinding.inflate(inflater, container, false)
binding.composeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val workingListViewModel by viewModels<WorkingListViewModel> { workingListViewModelFactory }
EventListScreen(
eventListViewModel,
workingListViewModel,
eventListViewModel = eventListViewModel,
workingListViewModel = workingListViewModel,
)
}
}
return binding.root
}

override fun onResume() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import android.view.View
import androidx.activity.viewModels
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
Expand Down Expand Up @@ -272,7 +276,7 @@ class SearchTEActivity : ActivityGlobalAbstract(), SearchTEContractsModule.View
override fun onBackPressed() {
viewModel.onBackPressed(
isPortrait(),
viewModel.searchOrFilterIsOpen(),
viewModel.backdropActive.value ?: false,
this.isKeyboardOpened(),
{
super.onBackPressed()
Expand Down Expand Up @@ -369,6 +373,7 @@ class SearchTEActivity : ActivityGlobalAbstract(), SearchTEContractsModule.View
binding.navigationBar.setContent {
DHIS2Theme {
val uiState by viewModel.navigationBarUIState
val isBackdropActive by viewModel.backdropActive.observeAsState(false)
var selectedItemIndex by remember(uiState) {
mutableIntStateOf(
uiState.items.indexOfFirst {
Expand All @@ -387,7 +392,9 @@ class SearchTEActivity : ActivityGlobalAbstract(), SearchTEContractsModule.View
}

AnimatedVisibility(
visible = viewModel.searchOrFilterIsOpen().not() && uiState.items.isNotEmpty(),
visible = (isBackdropActive.not() && uiState.items.isNotEmpty()) || isLandscape(),
enter = slideInVertically(animationSpec = tween(200)) { it },
exit = slideOutVertically(animationSpec = tween(200)) { it },
) {
NavigationBar(
modifier = Modifier.fillMaxWidth(),
Expand All @@ -397,7 +404,7 @@ class SearchTEActivity : ActivityGlobalAbstract(), SearchTEContractsModule.View
selectedItemIndex = uiState.items.indexOfFirst { it.id == page }
if (sessionManagerServiceImpl.isUserLoggedIn().not()) return@NavigationBar

if (viewModel.searchOrFilterIsOpen()) {
if (viewModel.backdropActive.value == true) {
searchScreenConfigurator.closeBackdrop()
}

Expand Down Expand Up @@ -511,6 +518,7 @@ class SearchTEActivity : ActivityGlobalAbstract(), SearchTEContractsModule.View

private fun observeScreenState() {
viewModel.screenState.observe(this, searchScreenConfigurator::configure)
viewModel.screenState.observe(this, viewModel::updateBackdrop)
}

private fun observeDownload() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ class SearchTEIViewModel(
private val _filtersOpened = MutableLiveData(false)
val filtersOpened: LiveData<Boolean> = _filtersOpened

private val _backdropActive = MutableLiveData<Boolean>()
val backdropActive: LiveData<Boolean> get() = _backdropActive

private val _teTypeName = MutableLiveData("")
val teTypeName: LiveData<String> = _teTypeName

Expand Down Expand Up @@ -727,7 +730,6 @@ class SearchTEIViewModel(
SearchResult(
SearchResult.SearchResultType.SEARCH_OUTSIDE,
searchRepository.getProgram(initialProgramUid)?.displayName(),

),
)
}
Expand Down Expand Up @@ -865,11 +867,13 @@ class SearchTEIViewModel(
}
}

fun searchOrFilterIsOpen(): Boolean {
return _screenState.value?.takeIf { it is SearchList }?.let {
val currentScreen = it as SearchList
currentScreen.searchForm.isOpened || currentScreen.searchFilters.isOpened
} ?: false
fun updateBackdrop(screenState: SearchTEScreenState) {
_backdropActive.postValue(
screenState.takeIf { it is SearchList }?.let {
val currentScreen = it as SearchList
currentScreen.searchForm.isOpened || currentScreen.searchFilters.isOpened
} ?: false,
)
}

fun filterIsOpen(): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ import org.dhis2.R
object BackdropManager {
private const val changeBoundDuration = 200L

private fun changeBounds(backdropLayout: ConstraintLayout, endID: Int, margin: Int) {
private fun changeBounds(
isNavigationBarVisible: Boolean,
backdropLayout: ConstraintLayout,
endID: Int,
margin: Int,
) {
val transition: Transition = ChangeBounds()
transition.duration = changeBoundDuration
TransitionManager.beginDelayedTransition(backdropLayout, transition)
Expand All @@ -19,15 +24,33 @@ object BackdropManager {
initSet.clone(backdropLayout)

initSet.connect(R.id.mainComponent, ConstraintSet.TOP, endID, ConstraintSet.BOTTOM, margin)
if (isNavigationBarVisible) {
initSet.connect(
R.id.mainComponent,
ConstraintSet.BOTTOM,
R.id.navigationBar,
ConstraintSet.TOP,
0,
)
} else {
initSet.connect(
R.id.mainComponent,
ConstraintSet.BOTTOM,
ConstraintSet.PARENT_ID,
ConstraintSet.BOTTOM,
0,
)
}
initSet.applyTo(backdropLayout)
}

fun changeBoundsIf(
condition: Boolean,
isNavigationBarVisible: Boolean,
backdropLayout: ConstraintLayout,
endID: Int,
margin: Int,
) {
if (condition) changeBounds(backdropLayout, endID, margin)
if (condition) changeBounds(isNavigationBarVisible, backdropLayout, endID, margin)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import androidx.constraintlayout.widget.ConstraintSet
import org.dhis2.R
import org.dhis2.bindings.display
import org.dhis2.bindings.dp
import org.dhis2.commons.animations.hide
import org.dhis2.commons.animations.show
import org.dhis2.databinding.ActivitySearchBinding
import org.dhis2.usescases.searchTrackEntity.SearchAnalytics
import org.dhis2.usescases.searchTrackEntity.SearchList
Expand Down Expand Up @@ -83,9 +81,8 @@ class SearchScreenConfigurator(
}
binding.filterRecyclerLayout.visibility = View.VISIBLE
binding.searchContainer.visibility = View.GONE
if (isPortrait()) binding.navigationBar.hide()
filterIsOpenCallback(true)
changeBounds(R.id.filterRecyclerLayout, 16.dp)
changeBounds(false, R.id.filterRecyclerLayout, 16.dp)
}

fun closeBackdrop() {
Expand All @@ -95,9 +92,8 @@ class SearchScreenConfigurator(
}
binding.filterRecyclerLayout.visibility = View.GONE
binding.searchContainer.visibility = View.GONE
if (isPortrait()) binding.navigationBar.show()
filterIsOpenCallback(false)
changeBounds(R.id.backdropGuideTop, 0)
changeBounds(true, R.id.backdropGuideTop, 0)
}

private fun openSearch() {
Expand All @@ -107,14 +103,14 @@ class SearchScreenConfigurator(
binding.title.visibility = View.VISIBLE
}
binding.searchContainer.visibility = View.VISIBLE
if (isPortrait()) binding.navigationBar.hide()
filterIsOpenCallback(false)
changeBounds(R.id.searchContainer, 0)
changeBounds(false, R.id.searchContainer, 0)
}

private fun changeBounds(endID: Int, margin: Int) {
private fun changeBounds(isNavigationBarVisible: Boolean, endID: Int, margin: Int) {
changeBoundsIf(
isPortrait(),
isNavigationBarVisible,
binding.backdropLayout,
endID,
margin,
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/layout/activity_search.xml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@
android:id="@+id/navigationBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/mainComponent"
app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
Expand Down
23 changes: 23 additions & 0 deletions app/src/main/res/layout/fragment_compose_holder.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">

<androidx.compose.ui.platform.ComposeView
android:id="@+id/composeView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>