From 387ea890dea772cd0d165116495e1b0705161ad1 Mon Sep 17 00:00:00 2001 From: Daniele Date: Sun, 5 Sep 2021 17:35:37 +0200 Subject: [PATCH] Layout animations --- .../subitobeers/MainActivity.kt | 2 + .../subitobeers/ui/BeersFragment.kt | 84 ++++++++++++------- app/src/main/res/anim/slide_in_right.xml | 26 ++++++ app/src/main/res/anim/slide_out_left.xml | 26 ++++++ .../main/res/layout/fragment_beers_list.xml | 3 +- 5 files changed, 109 insertions(+), 32 deletions(-) create mode 100644 app/src/main/res/anim/slide_in_right.xml create mode 100644 app/src/main/res/anim/slide_out_left.xml diff --git a/app/src/main/java/it/danieleverducci/subitobeers/MainActivity.kt b/app/src/main/java/it/danieleverducci/subitobeers/MainActivity.kt index 866a7c7..4b1c352 100644 --- a/app/src/main/java/it/danieleverducci/subitobeers/MainActivity.kt +++ b/app/src/main/java/it/danieleverducci/subitobeers/MainActivity.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.Menu import android.view.MenuInflater import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.FragmentManager import it.danieleverducci.subitobeers.entities.Beer import it.danieleverducci.subitobeers.ui.BeerDetailFragment @@ -17,6 +18,7 @@ class MainActivity : AppCompatActivity(), BeerNavigation { override fun showBeerDetail(beer: Beer) { val detailFragment = BeerDetailFragment(beer) supportFragmentManager.beginTransaction() + .setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left, android.R.anim.slide_in_left, android.R.anim.slide_out_right) .replace(R.id.fragment_container, detailFragment) .addToBackStack(null) .commit() diff --git a/app/src/main/java/it/danieleverducci/subitobeers/ui/BeersFragment.kt b/app/src/main/java/it/danieleverducci/subitobeers/ui/BeersFragment.kt index cda5b09..9d79632 100644 --- a/app/src/main/java/it/danieleverducci/subitobeers/ui/BeersFragment.kt +++ b/app/src/main/java/it/danieleverducci/subitobeers/ui/BeersFragment.kt @@ -24,9 +24,15 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter. enum class FILTERTYPE {SINCE, TO, CLEAR} + companion object { + val INSTANCESTATE_FILTER_OPEN = "filter_open" + val INSTANCESTATE_FILTER_SINCE = "filter_since" + val INSTANCESTATE_FILTER_TO = "filter_to" + } + private val rvAdapter = BeerRecyclerAdapter() private val repo = BeersRepository() - lateinit var binding: FragmentBeersListBinding + private var binding: FragmentBeersListBinding? = null override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -34,36 +40,52 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter. ): View? { setHasOptionsMenu(true); - // Inflate layout - binding = FragmentBeersListBinding.inflate( - LayoutInflater.from(container!!.context), - container, - false - ) + if (binding == null) { + // Inflate layout + binding = FragmentBeersListBinding.inflate( + LayoutInflater.from(container!!.context), + container, + false + ) - // Register filter buttons listeners - binding.listFilterSinceBt.setOnClickListener { onFilterButtonClicked(FILTERTYPE.SINCE) } - binding.listFilterToBt.setOnClickListener { onFilterButtonClicked(FILTERTYPE.TO) } - binding.listFilterClear.setOnClickListener { onFilterButtonClicked(FILTERTYPE.CLEAR) } + // Register filter buttons listeners + binding!!.listFilterSinceBt.setOnClickListener { onFilterButtonClicked(FILTERTYPE.SINCE) } + binding!!.listFilterToBt.setOnClickListener { onFilterButtonClicked(FILTERTYPE.TO) } + binding!!.listFilterClear.setOnClickListener { onFilterButtonClicked(FILTERTYPE.CLEAR) } - // Set the adapter - with(binding.list) { - layoutManager = LinearLayoutManager(context) - adapter = rvAdapter + // Set the adapter + with(binding!!.list) { + layoutManager = LinearLayoutManager(context) + adapter = rvAdapter + } + + // Register for recyclerview adapter events + rvAdapter.listener = this + + // Register for network completed events + repo.listener = this + + // Restore state + repo.filter.brewedBefore = savedInstanceState?.getString(INSTANCESTATE_FILTER_TO) + repo.filter.brewedAfter = savedInstanceState?.getString(INSTANCESTATE_FILTER_SINCE) + binding!!.listFilterDropdown.visibility = + if (savedInstanceState?.getBoolean(INSTANCESTATE_FILTER_OPEN) == true) View.VISIBLE else View.GONE + + // Load first page + loadBeers(true) } - // Register for recyclerview adapter events - rvAdapter.listener = this - - // Register for network completed events - repo.listener = this - - // Load first page - loadBeers(true) - - return binding.root + return binding!!.root } + override fun onSaveInstanceState(outState: Bundle) { + outState.putBoolean(INSTANCESTATE_FILTER_OPEN, binding!!.listFilterDropdown.visibility == View.VISIBLE) + outState.putString(INSTANCESTATE_FILTER_SINCE, repo.filter.brewedAfter) + outState.putString(INSTANCESTATE_FILTER_TO, repo.filter.brewedBefore) + super.onSaveInstanceState(outState) + } + + override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { super.onCreateOptionsMenu(menu, inflater) requireActivity().menuInflater.inflate(R.menu.list_menu, menu) @@ -101,8 +123,8 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter. if (type == FILTERTYPE.CLEAR) { repo.filter.clear() loadBeers(true) - binding.listFilterSinceBt.setText(R.string.list_filter_brewed_after) - binding.listFilterToBt.setText(R.string.list_filter_brewed_before) + binding!!.listFilterSinceBt.setText(R.string.list_filter_brewed_after) + binding!!.listFilterToBt.setText(R.string.list_filter_brewed_before) return } @@ -111,10 +133,10 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter. if (type == FILTERTYPE.SINCE) { repo.filter.setBrewedAfter(selMonth, selYear) - binding.listFilterSinceBt.setText(repo.filter.brewedAfter) + binding!!.listFilterSinceBt.setText(repo.filter.brewedAfter) } else { repo.filter.setBrewedBefore(selMonth, selYear) - binding.listFilterToBt.setText(repo.filter.brewedBefore) + binding!!.listFilterToBt.setText(repo.filter.brewedBefore) } // Update list @@ -146,8 +168,8 @@ class BeersFragment : Fragment(), BeersRepository.Listener, BeerRecyclerAdapter. * Toggles beer filter visibility */ private fun toggleFilter() { - binding.listFilterDropdown.visibility = - if (binding.listFilterDropdown.visibility == View.VISIBLE) View.GONE else View.VISIBLE + binding!!.listFilterDropdown.visibility = + if (binding!!.listFilterDropdown.visibility == View.VISIBLE) View.GONE else View.VISIBLE } /** diff --git a/app/src/main/res/anim/slide_in_right.xml b/app/src/main/res/anim/slide_in_right.xml new file mode 100644 index 0000000..125060e --- /dev/null +++ b/app/src/main/res/anim/slide_in_right.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/app/src/main/res/anim/slide_out_left.xml b/app/src/main/res/anim/slide_out_left.xml new file mode 100644 index 0000000..73337d4 --- /dev/null +++ b/app/src/main/res/anim/slide_out_left.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/app/src/main/res/layout/fragment_beers_list.xml b/app/src/main/res/layout/fragment_beers_list.xml index 29c29b5..3a8af27 100644 --- a/app/src/main/res/layout/fragment_beers_list.xml +++ b/app/src/main/res/layout/fragment_beers_list.xml @@ -4,7 +4,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:orientation="vertical"> + android:orientation="vertical" + android:animateLayoutChanges="true">