英文:
Android: Where to put functions that multiple fragments share
问题
以下是翻译好的内容:
我有三个片段,它们都有两个完全相同的函数。我的问题是,我(显然)不想一遍又一遍地复制相同的两个函数并将其放在这些片段中。
难道没有一种方法可以将这些函数放在一个地方,并从我的片段中调用它们吗?这些函数与 navController 和 Toolbar 导航有关,所以我不能将它们放在我的视图模型中。另一个解决方案可能是创建一个基类片段,在那里放置这些函数并从中继承?
## 函数 ##
private fun initProgressbar(currentStateNumber: StateProgressBar.StateNumber, progressBarDescription: ArrayList<String>) =
state_progress_bar.apply {
setStateDescriptionData(progressBarDescription)
setCurrentStateNumber(currentStateNumber)
}
private fun initToolbar(navController: NavController, appBarConf: AppBarConfiguration, textToolbar: String?) =
toolbar.apply {
setupWithNavController(navController, appBarConf)
toolbar_title.text = textToolbar
}
我没有找到任何在不违反 mvvm 架构或片段的生命周期的情况下的解决方案。我正在使用 jetpack navigation、mvvm 和 dagger hilt。
我感谢所有的帮助。
## 编辑:可能的解决方案 ##
abstract class BaseFragment(
layout: Int,
private val progressBarDescription: ArrayList<String>,
private val stateNumber: StateProgressBar.StateNumber
) : Fragment(layout) {
private val _navController: NavController by lazy { findNavController() }
private val appBarConf by lazy { AppBarConfiguration(_navController.graph) }
private val calibrateRepairToolbarText by lazy { arguments?.getString("calibrate_repair_toolbar_text") }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initProgressbar()
initToolbar()
}
val navController: NavController
get() = _navController
fun initProgressbar(): StateProgressBar = state_progress_bar.apply {
setStateDescriptionData(progressBarDescription)
setCurrentStateNumber(stateNumber)
}
fun initToolbar(): MaterialToolbar = toolbar.apply {
setupWithNavController(_navController, appBarConf)
toolbar_title.text = calibrateRepairToolbarText
}
}
然后在另一个片段中:
class Fragment(
private val progressBarDescription: ArrayList<String>,
@StateNumberOne private val stateNumber: StateProgressBar.StateNumber
) : BaseFragment(
R.layout.fragment_calibrate_repair_message,
progressBarDescription,
stateNumber
) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
英文:
I have three fragments and all of them have two functions which are EXACTLY THE SAME. My problem is that I (obviously) don't want to copy the same two functions over and over again and put it in the fragments.
Ain't there a way to put these functions in one place and call them from my fragments? These functions have to do with navController and Toolbar Navigation so I cant put it in my viewmodel. Another solution could be to create a Baseclass fragment, put these functions in there and inherit from it?
Functions
private fun initProgressbar(currentStateNumber: StateProgressBar.StateNumber, progressBarDescription: ArrayList<String>) =
state_progress_bar.apply {
setStateDescriptionData(progressBarDescription)
setCurrentStateNumber(currentStateNumber)
}
private fun initToolbar(navController: NavController, appBarConf: AppBarConfiguration, textToolbar: String?) =
toolbar.apply {
setupWithNavController(navController, appBarConf)
toolbar_title.text = textToolbar
}
I didn't found any solution without violating the mvvm architecture or the lifecyle of the fragments. I am using jetpack navigation, mvvm and dagger hilt.
I appreciate every help.
EDIT: Possible Solution
abstract class BaseFragment(
layout: Int,
private val progressBarDescription: ArrayList<String>,
private val stateNumber: StateProgressBar.StateNumber
) : Fragment(layout) {
private val _navController: NavController by lazy { findNavController() }
private val appBarConf by lazy { AppBarConfiguration(_navController.graph) }
private val calibrateRepairToolbarText by lazy { arguments?.getString("calibrate_repair_toolbar_text") }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initProgressbar()
initToolbar()
}
val navController: NavController
get() = _navController
fun initProgressbar(): StateProgressBar = state_progress_bar.apply {
setStateDescriptionData(progressBarDescription)
setCurrentStateNumber(stateNumber)
}
fun initToolbar(): MaterialToolbar = toolbar.apply {
setupWithNavController(_navController, appBarConf)
toolbar_title.text = calibrateRepairToolbarText
}
}
And then in the other Fragment:
class Fragment(
private val progressBarDescription: ArrayList<String>,
@StateNumberOne private val stateNumber: StateProgressBar.StateNumber
) : BaseFragment(
R.layout.fragment_calibrate_repair_message,
progressBarDescription,
stateNumber
) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
}
}
答案1
得分: 1
你可以创建一个baseFragment,并使用这些方法,然后让你的三个Fragment扩展baseFragment。
英文:
You can create a baseFragment, with these methods, and then have your three Fragments extend baseFragment
答案2
得分: 0
解决方案是,这些initToolbar
方法不属于Fragment
,而是属于Toolbar
。这就是为什么它的名称中包含init**Toolbar**
。
因此,如果您可以保证无论在任何调用点何时使用该方法,都是合理的,那么您可以为Toolbar
创建一个顶级扩展函数。
否则,您可以扩展Toolbar
并使用一个“复合ViewGroup
”来包含共享的视图逻辑。
英文:
The solution is that these initToolbar methods belong not to the Fragment, but to the Toolbar. Hence why it has initToolbar in it.
So if you can guarantee that whenever this method is used on any callsite, then it makes sense, then you can create a top-level extension function for the Toolbar.
Otherwise, you could extend Toolbar and use a "compound ViewGroup" to contain the shared view logic.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论