Fragment
// related to making sliding from the side fragment transition
// https://www.reddit.com/r/androiddev/comments/3b6fe8/slide_in_a_new_fragment_over_the_existing_one/
// he can call remove() or hide() after transition animation completes. He will also need to call popBackStack() twice and override onBackPressed. But all of this are workarounds./**/
inline fun FragmentManager.inTransaction(func: FragmentTransaction.() -> FragmentTransaction) {
beginTransaction().func().commit()
}
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private val mFirebaseAnalytics: FirebaseAnalytics? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
supportFragmentManager.inTransaction {
replace(R.id.container, ListFragment())
}
}
supportFragmentManager.addOnBackStackChangedListener(this)
}
override fun onBackStackChanged() {
shouldDisplayHomeUp()
}
override fun onSupportNavigateUp(): Boolean { // This method is called when the up button is pressed. Just pop the back stack.
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStack()
return false
}
finish()
return true
}
fun popAllBackStackIfNeeded(manager: FragmentManager) {
if (manager.backStackEntryCount > 0) {
manager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
}
}
fun shouldDisplayHomeUp() { // Enable Up button only if there are entries in the back stack
val canBack = supportFragmentManager.backStackEntryCount > 0
supportActionBar?.setDisplayHomeAsUpEnabled(canBack)
}
}
// It's only abstract to log from subclasses with corresponding _tag
// Replace `abstract` with `open` if don't need this functionality
abstract class BaseFragment: Fragment() {
abstract fun log(message: String)
val compositeDisposable: CompositeDisposable by lazy { CompositeDisposable() }
override fun onPause() {
super.onPause()
log("onPause")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
cleanUp()
}
}
override fun onStop() {
super.onStop()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
cleanUp()
}
}
private fun cleanUp() {
compositeDisposable.clear()
}
fun showMessage(tv: TextView?, msg: String? = null) {
tv?.visibility = View.VISIBLE
msg?.let { tv?.text = it }
}
}
abstract class RealmBaseFragment : BaseFragment() {
lateinit var realm: Realm
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
log("onCreate")
realm = Realm.getDefaultInstance()
}
override fun onDestroy() {
super.onDestroy()
log("onDestroy")
realm.close()
}
}
class BaseFragment: Fragment() {
companion object {
fun newInstance(): BaseFragment {
val fragment = BaseFragment()
val bundle = Bundle()
fragment.arguments = bundle
return fragment
}
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
super.onCreateView(inflater, container, savedInstanceState)
val rootView = inflater?.inflate(R.layout.fragment_main, container, false)
return rootView
}
}
// https://medium.com/thoughts-overflow/how-to-add-a-fragment-in-kotlin-way-73203c5a450b
inline fun FragmentManager.inTransaction(func: FragmentTransaction.() -> FragmentTransaction) {
beginTransaction().func().commit()
}
fun FragmentManager.add(id: Int, fragment: Fragment, name: String? = null) {
beginTransaction()
.add(id, fragment)
.run { if (name != null) addToBackStack(name) else return@run this }
.commit()
}
fun FragmentManager.replace(id: Int, fragment: Fragment, name: String? = null) {
beginTransaction()
.replace(id, fragment)
.run { if (name != null) addToBackStack(name) else return@run this }
.commit()
}