Skip to content

Commit

Permalink
feat: added a feature to dispose recyclers without any hussle
Browse files Browse the repository at this point in the history
  • Loading branch information
FunkyMuse committed Feb 15, 2021
1 parent 3b04c96 commit aea261e
Show file tree
Hide file tree
Showing 21 changed files with 274 additions and 8 deletions.
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dependencies {
implementation project(path: ':customviews')
implementation project(path: ':recyclerview')
implementation project(path: ':biometrics')
implementation project(path: ':navigation')

testImplementation 'junit:junit:4.13.1'

Expand Down Expand Up @@ -79,6 +80,10 @@ dependencies {
implementation "androidx.constraintlayout:constraintlayout:$constraint_layout"
implementation "androidx.constraintlayout:constraintlayout-solver:$constraint_layout"

//nav
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

//coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines"
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainAbstractActivity">
<activity android:name=".nav.NavActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.crazylegend.setofusefulkotlinextensions.nav

import android.annotation.SuppressLint
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.LiveData
import androidx.navigation.NavController
import com.crazylegend.navigation.setupWithNavController
import com.crazylegend.setofusefulkotlinextensions.R
import com.crazylegend.setofusefulkotlinextensions.databinding.ActivityNavBinding
import com.crazylegend.viewbinding.viewBinder

/**
* Created by Hristijan, date 2/15/21
*/
class NavActivity : AppCompatActivity() {
private var currentNavController: LiveData<NavController>? = null

private val binding by viewBinder(ActivityNavBinding::inflate)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
if (savedInstanceState == null) {
setupBottomNavigationBar()
} // Else, need to wait for onRestoreInstanceState
}

@SuppressLint("ResourceType")
private fun setupBottomNavigationBar() {

val navGraphIds = listOf(
R.navigation.test01,
R.navigation.test02,
R.navigation.test03,
R.navigation.test04,
R.navigation.test05)
// Setup the bottom navigation view with a list of navigation graphs

val controller = binding.bottomNav.setupWithNavController(
navGraphIds = navGraphIds,
fragmentManager = supportFragmentManager,
containerId = R.id.fragmentContainer,
intent = intent,
R.anim.nav_default_enter_anim,
R.anim.nav_default_exit_anim,
R.anim.nav_default_pop_enter_anim,
R.anim.nav_default_pop_exit_anim
)

// Whenever the selected controller changes, setup the action bar.
controller.observe(this) { navController ->
listenToDestinationChanges(navController)
}
currentNavController = controller

}

private fun listenToDestinationChanges(navController: NavController?) {
navController ?: return

}

override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
setupBottomNavigationBar()
}


override fun onSupportNavigateUp() = currentNavController?.value?.navigateUp() ?: false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.crazylegend.setofusefulkotlinextensions.nav

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import com.crazylegend.customviews.databinding.CustomizableCardViewBinding
import com.crazylegend.kotlinextensions.collections.generateRandomStringList
import com.crazylegend.recyclerview.generateRecyclerWithHolder
import com.crazylegend.setofusefulkotlinextensions.R
import com.crazylegend.setofusefulkotlinextensions.databinding.FragmentTestBinding
import com.crazylegend.viewbinding.viewBinding

/**
* Created by Hristijan, date 2/15/21
*/
class TestFragment : Fragment(R.layout.fragment_test) {

private val binding by viewBinding(FragmentTestBinding::bind)

private val testAdapter by lazy {
generateRecyclerWithHolder<String, CustomizableCardViewBinding>(CustomizableCardViewBinding::inflate){
item, position, _, binding, _ ->
binding.title.text = "Title ${position+1}"
binding.content.text = item
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.recycler.adapter = testAdapter
testAdapter.submitList(generateRandomStringList(100))
}
}
31 changes: 31 additions & 0 deletions app/src/main/res/layout/activity_nav.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_above="@id/bottomNav"
android:layout_margin="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottomNav"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottomNav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:elevation="15dp"
app:itemIconTint="@color/colorAccent"
app:labelVisibilityMode="selected"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_nav_menu" />

</androidx.constraintlayout.widget.ConstraintLayout>
13 changes: 13 additions & 0 deletions app/src/main/res/layout/fragment_test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

</androidx.constraintlayout.widget.ConstraintLayout>
19 changes: 19 additions & 0 deletions app/src/main/res/menu/bottom_nav_menu.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item
android:id="@+id/test01"
android:title="1" />
<item
android:id="@+id/test02"
android:title="2" />
<item
android:id="@+id/test03"
android:title="3" />
<item
android:id="@+id/test04"
android:title="4" />
<item
android:id="@+id/test05"
android:title="5" />
</menu>
11 changes: 11 additions & 0 deletions app/src/main/res/navigation/test01.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/test01"
app:startDestination="@id/testFragment">

<fragment
android:id="@+id/testFragment"
android:name="com.crazylegend.setofusefulkotlinextensions.nav.TestFragment"
android:label="TestFragment" />
</navigation>
11 changes: 11 additions & 0 deletions app/src/main/res/navigation/test02.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/test02"
app:startDestination="@id/testFragment2">

<fragment
android:id="@+id/testFragment2"
android:name="com.crazylegend.setofusefulkotlinextensions.nav.TestFragment"
android:label="TestFragment" />
</navigation>
11 changes: 11 additions & 0 deletions app/src/main/res/navigation/test03.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/test03"
app:startDestination="@id/testFragment3">

<fragment
android:id="@+id/testFragment3"
android:name="com.crazylegend.setofusefulkotlinextensions.nav.TestFragment"
android:label="TestFragment" />
</navigation>
11 changes: 11 additions & 0 deletions app/src/main/res/navigation/test04.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/test04"
app:startDestination="@id/testFragment4">

<fragment
android:id="@+id/testFragment4"
android:name="com.crazylegend.setofusefulkotlinextensions.nav.TestFragment"
android:label="TestFragment" />
</navigation>
11 changes: 11 additions & 0 deletions app/src/main/res/navigation/test05.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/test05"
app:startDestination="@id/testFragment5">

<fragment
android:id="@+id/testFragment5"
android:name="com.crazylegend.setofusefulkotlinextensions.nav.TestFragment"
android:label="TestFragment" />
</navigation>
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ ext {
appCompat = "1.2.0"
coreKTX = "1.5.0-beta01"
securityVersion = "1.1.0-alpha03"
recyclerview = '1.1.0'


//app only
room_version = "2.3.0-beta01"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ object AutoStartHelper {


private lateinit var confirmationDialogAutoStart: ConfirmationDialogAutoStart
const val DIALOG_TAG = "dialogAutoStartTag"
private const val DIALOG_TAG = "dialogAutoStartTag"

private fun showAlert(context: Context, bundle: Bundle, action: () -> Unit) {
when (context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ class ConfirmationDialogAutoStart : DialogFragment(R.layout.dialog_confirmation_
binding.dialogText.text = getString(TEXT_FIELD, "Please enable auto-start ability for this application.")
binding.cancelButton.text = getString(CANCEL_TEXT, "Cancel")
binding.confirmButton.text = getString(CONFIRM_TEXT, "Submit")
val dontShowAgainVisiblity = getBoolean(DO_NOT_SHOW_AGAIN_VISIBILITY, false)
binding.dontShowAgain.visibleIfTrueGoneOtherwise(dontShowAgainVisiblity)
if (dontShowAgainVisiblity) {
val doNotShowAgainVisibility = getBoolean(DO_NOT_SHOW_AGAIN_VISIBILITY, false)
binding.dontShowAgain.visibleIfTrueGoneOtherwise(doNotShowAgainVisibility)
if (doNotShowAgainVisibility) {
binding.dontShowAgain.text = getString(DO_NOT_SHOW_AGAIN_TEXT, "Do not show again")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import android.util.SparseArray
import androidx.collection.LongSparseArray
import androidx.collection.SparseArrayCompat
import androidx.collection.forEach
import com.crazylegend.kotlinextensions.randomUUIDstring
import java.util.*
import kotlin.collections.ArrayList

Expand Down Expand Up @@ -868,6 +869,14 @@ fun generateRandomIntegerList(size: Int, range: IntRange): MutableList<Int> {
return resultList
}

fun generateRandomStringList(size: Int): MutableList<String> {
val resultList = ArrayList<String>(size)
for (i in 1..size) {
resultList.add(randomUUIDstring)
}
return resultList
}


fun <T> List<T>.getStringRepresentation(maxElements: Int = Integer.MAX_VALUE): String {
if (size > maxElements) return " The list is too long to output!"
Expand Down
2 changes: 1 addition & 1 deletion recyclerview/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ android {
}

dependencies {
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation "androidx.recyclerview:recyclerview:$recyclerview"
implementation "com.google.android.material:material:$material"
implementation "androidx.core:core-ktx:$coreKTX"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.crazylegend.recyclerview

import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.Transition
import androidx.transition.TransitionManager
Expand Down Expand Up @@ -32,3 +33,13 @@ fun RecyclerView.replaceAdapterWith(replacementAdapter: RecyclerView.Adapter<*>,
}
}

fun RecyclerView.clearOnDetach(){
addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener{
override fun onViewAttachedToWindow(v: View?) {
}

override fun onViewDetachedFromWindow(v: View?) {
adapter = null
}
})
}
2 changes: 2 additions & 0 deletions viewbinding/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ dependencies {
implementation "androidx.fragment:fragment-ktx:$fragment"
implementation "androidx.appcompat:appcompat:$appCompat"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle"
implementation "androidx.recyclerview:recyclerview:$recyclerview"

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import kotlin.reflect.KProperty

class FragmentViewBindingDelegate<T : ViewBinding>(private val fragment: Fragment,
private val viewBinder: (View) -> T,
private val disposeRecyclerViewsAutomatically: Boolean = true,
private val disposeEvents: T.() -> Unit = {}) : ReadOnlyProperty<Fragment, T>, LifecycleObserver {

private inline fun Fragment.observeLifecycleOwnerThroughLifecycleCreation(crossinline viewOwner: LifecycleOwner.() -> Unit) {
Expand All @@ -27,6 +28,8 @@ class FragmentViewBindingDelegate<T : ViewBinding>(private val fragment: Fragmen
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun disposeBinding() {
fragmentBinding?.disposeEvents()
if (disposeRecyclerViewsAutomatically)
fragmentBinding.disposeRecyclers()
fragmentBinding = null
}

Expand All @@ -52,3 +55,4 @@ class FragmentViewBindingDelegate<T : ViewBinding>(private val fragment: Fragmen
return viewBinder(thisRef.requireView()).also { fragmentBinding = it }
}
}

Loading

0 comments on commit aea261e

Please sign in to comment.