mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-21 17:05:39 +03:00
Fragment factory: start including the new version with FragmentFactory [WIP]
This commit is contained in:
parent
cd1a964067
commit
3013d67c16
12 changed files with 164 additions and 27 deletions
|
@ -217,6 +217,7 @@ android {
|
|||
dependencies {
|
||||
|
||||
def epoxy_version = '3.8.0'
|
||||
def fragment_version = '1.2.0-rc01'
|
||||
def arrow_version = "0.8.2"
|
||||
def coroutines_version = "1.3.2"
|
||||
def markwon_version = '4.1.2'
|
||||
|
@ -234,6 +235,8 @@ dependencies {
|
|||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation "androidx.fragment:fragment:$fragment_version"
|
||||
implementation "androidx.fragment:fragment-ktx:$fragment_version"
|
||||
//Do not use beta2 at the moment, as it breaks things
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
|
||||
implementation 'androidx.core:core-ktx:1.1.0'
|
||||
|
|
28
vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt
Normal file
28
vector/src/main/java/im/vector/riotx/core/di/FragmentKey.kt
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package im.vector.riotx.core.di
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.MapKey
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
@MapKey
|
||||
annotation class FragmentKey(val value: KClass<out Fragment>)
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package im.vector.riotx.core.di
|
||||
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.multibindings.IntoMap
|
||||
import im.vector.riotx.core.platform.ConfigurationViewModel
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromKeyViewModel
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreFromPassphraseViewModel
|
||||
import im.vector.riotx.features.crypto.keysbackup.restore.KeysBackupRestoreSharedViewModel
|
||||
import im.vector.riotx.features.crypto.keysbackup.setup.KeysBackupSetupSharedViewModel
|
||||
import im.vector.riotx.features.crypto.verification.SasVerificationViewModel
|
||||
import im.vector.riotx.features.home.HomeNavigationViewModel
|
||||
import im.vector.riotx.features.home.createdirect.CreateDirectRoomNavigationViewModel
|
||||
import im.vector.riotx.features.home.room.list.RoomListFragment
|
||||
import im.vector.riotx.features.reactions.EmojiChooserViewModel
|
||||
import im.vector.riotx.features.roomdirectory.RoomDirectoryNavigationViewModel
|
||||
import im.vector.riotx.features.workers.signout.SignOutViewModel
|
||||
|
||||
@Module
|
||||
interface FragmentModule {
|
||||
|
||||
/**
|
||||
* Fragments with @IntoMap will be injected by this factory
|
||||
*/
|
||||
@Binds
|
||||
fun bindFragmentFactory(factory: VectorFragmentFactory): FragmentFactory
|
||||
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(RoomListFragment::class)
|
||||
fun bindRoomListFragment(viewModel: RoomListFragment): ViewModel
|
||||
|
||||
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package im.vector.riotx.core.di
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
|
@ -88,6 +89,8 @@ interface ScreenComponent {
|
|||
|
||||
fun activeSessionHolder(): ActiveSessionHolder
|
||||
|
||||
fun fragmentFactory(): FragmentFactory
|
||||
|
||||
fun viewModelFactory(): ViewModelProvider.Factory
|
||||
|
||||
fun bugReporter(): BugReporter
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2019 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package im.vector.riotx.core.di
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Provider
|
||||
|
||||
/**
|
||||
* FragmentFactory which uses Dagger to create the instances.
|
||||
*/
|
||||
class VectorFragmentFactory @Inject constructor(
|
||||
private val creators: @JvmSuppressWildcards Map<Class<out Fragment>, Provider<Fragment>>
|
||||
) : FragmentFactory() {
|
||||
|
||||
override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
|
||||
val fragmentClass = loadFragmentClass(classLoader, className)
|
||||
val creator: Provider<out Fragment>? = creators[fragmentClass]
|
||||
return if (creator == null) {
|
||||
Timber.v("Unknown model class: $className, fallback to default instance")
|
||||
super.instantiate(classLoader, className)
|
||||
} else {
|
||||
creator.get()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,15 +19,15 @@ package im.vector.riotx.core.extensions
|
|||
import androidx.fragment.app.Fragment
|
||||
|
||||
fun Fragment.addFragment(fragment: Fragment, frameId: Int) {
|
||||
fragmentManager?.inTransaction { add(frameId, fragment) }
|
||||
parentFragmentManager.inTransaction { add(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun Fragment.replaceFragment(fragment: Fragment, frameId: Int) {
|
||||
fragmentManager?.inTransaction { replace(frameId, fragment) }
|
||||
parentFragmentManager.inTransaction { replace(frameId, fragment) }
|
||||
}
|
||||
|
||||
fun Fragment.addFragmentToBackstack(fragment: Fragment, frameId: Int, tag: String? = null) {
|
||||
fragmentManager?.inTransaction { replace(frameId, fragment).addToBackStack(tag) }
|
||||
parentFragmentManager.inTransaction { replace(frameId, fragment).addToBackStack(tag) }
|
||||
}
|
||||
|
||||
fun Fragment.addChildFragment(fragment: Fragment, frameId: Int) {
|
||||
|
|
|
@ -26,6 +26,7 @@ import androidx.annotation.*
|
|||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.FragmentFactory
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
|
@ -125,7 +126,7 @@ abstract class VectorBaseActivity : BaseMvRxActivity(), HasScreenInjector {
|
|||
}
|
||||
Timber.v("Injecting dependencies into ${javaClass.simpleName} took $timeForInjection ms")
|
||||
ThemeUtils.setActivityTheme(this, getOtherThemes())
|
||||
|
||||
supportFragmentManager.fragmentFactory = screenComponent.fragmentFactory()
|
||||
super.onCreate(savedInstanceState)
|
||||
viewModelFactory = screenComponent.viewModelFactory()
|
||||
configurationViewModel = ViewModelProviders.of(this, viewModelFactory).get(ConfigurationViewModel::class.java)
|
||||
|
|
|
@ -134,7 +134,11 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScreenInjector {
|
|||
}
|
||||
|
||||
protected fun setArguments(args: Parcelable? = null) {
|
||||
arguments = args?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } }
|
||||
arguments = args.toMvRxBundle()
|
||||
}
|
||||
|
||||
protected fun Parcelable?.toMvRxBundle(): Bundle? {
|
||||
return this?.let { Bundle().apply { putParcelable(MvRx.KEY_ARG, it) } }
|
||||
}
|
||||
|
||||
@MainThread
|
||||
|
|
|
@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.crypto.keysbackup.KeysBackupState
|
|||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ScreenComponent
|
||||
import im.vector.riotx.core.extensions.inTransaction
|
||||
import im.vector.riotx.core.platform.ToolbarConfigurable
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.ui.views.KeysBackupBanner
|
||||
|
@ -172,14 +173,17 @@ class HomeDetailFragment : VectorBaseFragment(), KeysBackupBanner.Delegate {
|
|||
|
||||
private fun updateSelectedFragment(displayMode: RoomListFragment.DisplayMode) {
|
||||
val fragmentTag = "FRAGMENT_TAG_${displayMode.name}"
|
||||
var fragment = childFragmentManager.findFragmentByTag(fragmentTag)
|
||||
val fragment = childFragmentManager.findFragmentByTag(fragmentTag)
|
||||
if (fragment == null) {
|
||||
fragment = RoomListFragment.newInstance(RoomListParams(displayMode))
|
||||
childFragmentManager.inTransaction {
|
||||
replace(R.id.roomListContainer, RoomListFragment::class.java, RoomListParams(displayMode).toMvRxBundle(), fragmentTag).addToBackStack(fragmentTag)
|
||||
}
|
||||
} else {
|
||||
childFragmentManager.inTransaction {
|
||||
replace(R.id.roomListContainer, fragment, fragmentTag).addToBackStack(fragmentTag)
|
||||
}
|
||||
}
|
||||
childFragmentManager.beginTransaction()
|
||||
.replace(R.id.roomListContainer, fragment, fragmentTag)
|
||||
.addToBackStack(fragmentTag)
|
||||
.commit()
|
||||
|
||||
}
|
||||
|
||||
/* ==========================================================================================
|
||||
|
|
|
@ -44,7 +44,6 @@ class FilteredRoomsActivity : VectorBaseActivity() {
|
|||
super.onCreate(savedInstanceState)
|
||||
configureToolbar(filteredRoomsToolbar)
|
||||
if (isFirstCreation()) {
|
||||
roomListFragment = RoomListFragment.newInstance(RoomListParams(RoomListFragment.DisplayMode.FILTERED))
|
||||
replaceFragment(roomListFragment, R.id.filteredRoomsFragmentContainer, FRAGMENT_TAG)
|
||||
} else {
|
||||
roomListFragment = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as RoomListFragment
|
||||
|
|
|
@ -52,7 +52,13 @@ data class RoomListParams(
|
|||
val sharedData: SharedData? = null
|
||||
) : Parcelable
|
||||
|
||||
class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, FabMenuView.Listener {
|
||||
class RoomListFragment @Inject constructor(
|
||||
private val roomController: RoomSummaryController,
|
||||
val roomListViewModelFactory: RoomListViewModel.Factory,
|
||||
private val errorFormatter: ErrorFormatter,
|
||||
private val notificationDrawerManager: NotificationDrawerManager
|
||||
|
||||
) : VectorBaseFragment(), RoomSummaryController.Listener, OnBackPressed, FabMenuView.Listener {
|
||||
|
||||
enum class DisplayMode(@StringRes val titleRes: Int) {
|
||||
HOME(R.string.bottom_action_home),
|
||||
|
@ -62,25 +68,14 @@ class RoomListFragment : VectorBaseFragment(), RoomSummaryController.Listener, O
|
|||
SHARE(/* Not used */ 0)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun newInstance(roomListParams: RoomListParams): RoomListFragment {
|
||||
return RoomListFragment().apply {
|
||||
setArguments(roomListParams)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val roomListParams: RoomListParams by args()
|
||||
@Inject lateinit var roomController: RoomSummaryController
|
||||
@Inject lateinit var roomListViewModelFactory: RoomListViewModel.Factory
|
||||
@Inject lateinit var errorFormatter: ErrorFormatter
|
||||
@Inject lateinit var notificationDrawerManager: NotificationDrawerManager
|
||||
private val roomListViewModel: RoomListViewModel by fragmentViewModel()
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_room_list
|
||||
|
||||
override fun injectWith(injector: ScreenComponent) {
|
||||
injector.inject(this)
|
||||
setArguments()
|
||||
}
|
||||
|
||||
private var hasUnreadRooms = false
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<FrameLayout
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/homeDetailFragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
@ -20,7 +20,7 @@
|
|||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
|
||||
<FrameLayout
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/homeDrawerFragmentContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
|
Loading…
Reference in a new issue