Sobes.tech
Junior

Kuidas kutsuda tegevuse meetodit fragmentidest?

sobes.tech AI

Vastus AI-lt

On mitmeid viise, kuidas kutsuda tegevuse meetod fragmentist, sõltuvalt olukorrast ja arhitektuurist:

  1. Võrgu kaudu tegevuse viitamisega:

    Fragment võib saada otse viite tegevusele, millega see on ühendatud.

    // Fragmenti sees
    if (activity is YourActivity) {
        (activity as YourActivity).yourActivityMethod()
    }
    

    See meetod on lihtne, kuid loob tugeva sõltuvuse fragmenti ja konkreetse tegevuse vahel.

  2. Tagasiside liidese kaudu:

    See on paindlikum ja soovitatav viis. Fragment defineerib liidese, mida tegevus peab rakendama.

    // Fragmenti sees
    interface OnYourActivityMethodListener {
        fun onYourActivityMethodCalled()
    }
    
    private var listener: OnYourActivityMethodListener? = null
    
    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is OnYourActivityMethodListener) {
            listener = context
        } else {
            throw RuntimeException("$context must implement OnYourActivityMethodListener")
        }
    }
    
    override fun onDetach() {
        super.onDetach()
        listener = null
    }
    
    // Fragmentist tegevuse meetodi kutsumine
    fun callActivityMethod() {
        listener?.onYourActivityMethodCalled()
    }
    
    // Tegevuses
    class YourActivity : AppCompatActivity(), YourFragment.OnYourActivityMethodListener {
    
        override fun onYourActivityMethodCalled() {
            // Logika, mis peab toimuma tegevuses
        }
    
        // ... ülejäänud tegevuse kood
    }
    

    See lähenemine muudab fragmendi taaskasutatavaks, kuna see sõltub lepingust (liidesest), mitte konkreetse klassi tegevusest.

  3. ViewModel kaudu (soovitatav keerulisemate interaktsioonide jaoks):

    Ühise ViewModel kasutamine fragmenti ja tegevuse vahel võimaldab neil vahetada andmeid ja sündmusi ilma otseste viideteta.

    // Ühine ViewModel
    class SharedViewModel : ViewModel() {
        private val _callActivityMethodEvent = MutableLiveData<Event<Unit>>()
        val callActivityMethodEvent: LiveData<Event<Unit>> = _callActivityMethodEvent
    
        fun triggerActivityMethod() {
            _callActivityMethodEvent.value = Event(Unit)
        }
    }
    
    // Ühekordsed sündmused
    open class Event<out T>(private val content: T) {
        var hasBeenHandled = false
            private set // Väljast lugeda, mitte kirjutada
    
        fun getContentIfNotHandled(): T? {
            return if (hasBeenHandled) {
                null
            } else {
                hasBeenHandled = true
                content
            }
        }
    
        fun peekContent(): T = content
    }
    
    // Fragmenti sees
    private val sharedViewModel: SharedViewModel by activityViewModels() // kasutame activityViewModels()
    
    // Tegevuse meetodi kutsumine ViewModel kaudu
    fun callActivityMethod() {
        sharedViewModel.triggerActivityMethod()
    }
    
    // Tegevuses
    private val sharedViewModel: SharedViewModel by viewModels()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
    
        sharedViewModel.callActivityMethodEvent.observe(this, Observer { event ->
            event.getContentIfNotHandled()?.let {
                // Logika, mis peab toimuma tegevuses
            }
        })
    }
    

    See lähenemine vastab arhitektuurikomponentide soovitustele ja lihtsustab testimist.

Meetodi valik sõltub suhtluse keerukusest. Lihtsate juhtude puhul sobib otse kutsumine või liides. Keerulisemate stsenaariumide puhul, eriti andmete edastamisega seotud, on parem kasutada ViewModel.