Android Fragments Android View Binding for a“base fragment”?

tvz2xvvm  于 2023-08-06  发布在  Android
关注(0)|答案(1)|浏览(137)

Android/Kotlin新手在这里。我正在转换别人的代码,这是写的合成,以查看绑定每个Google Play的即将到来的弃用截止日期。我读了这个和this,并转换了显而易见的东西,但是:
开发人员设置了2个使用“基本片段”的片段,如下所示:

class FragmentA: BaseFragment() { ... }
class FragmentB: BaseFragment() { ... }
and then
open class BaseFragment: Fragment() { ... }

字符串
基本片段使用合成来引用与片段A/B相关联的布局中的视图。(她之所以能做到这一点,是因为她将片段A/B的布局分解为可重用的组件,而这两个片段是互斥的--在任何给定时刻,只有一个片段可以运行。每个可重用的布局组件都有一个绑定类,我可以看到它们,但我不能在基本片段中引用它们,它们没有膨胀。
我的问题是:我如何摆脱基本片段中的合成引用?(最坏的情况是,我复制粘贴所有内容,并删除基本片段,但不知道是否有办法保留设计。
多谢了

  • 2023年7月21日,根据要求添加一些示例代码。@Obscure Cookie *

代码中的所有这些(表面上未定义的)变量都来自使用android. synthetic在顶部导入的布局。BaseGamesFragment本身没有布局。基于它的片段膨胀了布局。

import androidx.navigation.fragment.findNavController
import kotlinx.android.synthetic.main.fragment_fib.*
import kotlinx.android.synthetic.main.games_top_panel.*
import kotlinx.android.synthetic.main.hints_panel_games.*
import kotlinx.android.synthetic.main.no_headset_container.*
import kotlinx.android.synthetic.main.song_panel.*
import kotlinx.coroutines.launch

open class BaseGamesFragment : PitchBaseFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        startForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {}
    }

    open fun initUI() {

        extra_button.setOnClickListener {
            try {
                // Exit games, then nav to settings
                val intent = Intent(activity, SettingsActivity::class.java)
                startActivity(intent)
                lifecycleScope.launch {
                    PSM.handleEvent(Event.SettingsButton93)
                }
            } catch (e: IllegalArgumentException) {
                Timber.e("LC: BaseGamesActivity initUI : %s", e.localizedMessage)
            }
        }

        btn_continue_anyway.setOnClickListener {
            displayDialog(no_headset_container, false)
            lifecycleScope.launch {
                // This is supposed to set the headsetSession to false
                PSM.handleEvent(Event.GenericFalse)
            }
        }
    }

    override fun updateSongPanel() {  // should be called song clock; just how deep we are into the song.
        song_panel?.let {
            SongLearningProgress.song?.let { currentSong ->
                currentLine?.let { currentLine ->
                    val (_, lyricsLine) = currentSong.findSectionAndLine(currentLine)
                    val startsAt = lyricsLine.startsAt.toInt()
                    song_progress_bar.progress = startsAt
                }
            }
        }
    }

    private fun showBottomSheet() {
        main_debug_bottom_sheet_contents.show()
        main_debug_bottom_sheet_contents.visibility = View.VISIBLE
    }

    open fun displayDialog(dialogType: String, visible: Boolean) {
        param = dialogType
        if (dialogType == "DNH1") {
            // display/hide no headset dialog
            if (visible) {
                view_flipper?.startFlipping()
            } else {
                view_flipper?.stopFlipping()
            }
            displayDialog(no_headset_container, visible)
        }
    }
}

gv8xihay

gv8xihay1#

我认为最好的做法是创建一个BaseFragment,如下所示,这样你就可以从BaseFragment引用ViewBinding。

abstract class BaseFragment<VBinding : ViewBinding, ViewModel : BaseViewModel> : Fragment() {

open var useSharedViewModel: Boolean = false

protected lateinit var viewModel: ViewModel
protected abstract fun getViewModelClass(): Class<ViewModel>

protected lateinit var binding: VBinding
protected abstract fun getViewBinding(): VBinding

private val disposableContainer = CompositeDisposable()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    init()
}

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    setUpViews()
    observeData()
}

open fun setUpViews() {}

open fun observeView() {}

open fun observeData() {}

private fun init() {
    binding = getViewBinding()
    viewModel = if (useSharedViewModel) {
        ViewModelProvider(requireActivity()).get(
            getViewModelClass()
        )
    } else {
        ViewModelProvider(this).get(getViewModelClass())
    }
}

fun Disposable.addToContainer() = disposableContainer.add(this)

override fun onDestroyView() {
    disposableContainer.clear()
    super.onDestroyView()
}}

字符串
link

相关问题