Могу ли я исключить стандартный шаблон и привязку видового кода в моих Android фрагментах? - PullRequest
0 голосов
/ 18 апреля 2020

Я пишу шаблонный код для каждого нового фрагмента, который я создаю. это включает в себя настройку viewmodel и viewbinding, это две разные части моего кода, которые не зависят друг от друга, поэтому решение для одной из них все равно будет отличным.

Пример кода фрагмента:

class MyFragment : Fragment() {

    // View binding
    private var _binding: FragmentMyBinding? = null

    // View model
    private lateinit var model : MyViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Model init
        model = ViewModelProvider(this).get(MyViewModel::class.java)

        //binding init
        _binding = FragmentMyBinding.inflate(inflater, container, false)

        return _binding!!.root
    }

}

class MyViewModel : ViewModel()

1 Ответ

2 голосов
/ 18 апреля 2020

Как видно на странице документации ViewModel , код Kotlin не должен использовать ViewModelProvider(this), а вместо этого использовать by viewModels(), который является частью зависимости fragment-ktx. Это заменяет использование lateinit var model и необходимость что-либо делать в onCreateView(), что означает, что именно таким образом ваш фрагмент становится:

class MyFragment : Fragment() {

    // View binding
    private var _binding: FragmentMyBinding? = null

    // View model
    private val model: MyViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        //binding init
        _binding = FragmentMyBinding.inflate(inflater, container, false)

        return _binding!!.root
    }
}

Вы можете использовать такой подход, как этот и вообще не держитесь за переплет. Этот подход будет означать, что ваш фрагмент будет выглядеть следующим образом:

class MyFragment : Fragment(R.layout.my_fragment) {

    // View model
    private val model: MyViewModel by viewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val binding = FragmentMyBinding.bind(view)
        // Now use the binding and your ViewModel
    }
}

Еще один вариант - скопировать AutoClearedValue в ваш проект и использовать его, который вместо этого будет выглядеть так:

class MyFragment : Fragment() {

    // View binding
    private var binding by autoCleared<FragmentMyBinding>()

    // View model
    private val model: MyViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentMyBinding.inflate(inflater, container, false)
        // Now use the binding and your ViewModel

        return binding.root
    }
}

На этом этапе при любом решении вы используете не более 3 общих строк кода, причем все они разные, поэтому попытка построить базовый фрагмент и работать с универсальными элементами усложнит ситуацию. чем нет и было бы то, что я бы не предложил.

...