Sobes.tech
Junior

Kaip iškviesti veiklos metodą iš fragmento?

sobes.tech AI

Atsakymas iš AI

Yra keletas būdų iškviesti aktyvumo metodą iš fragmento, priklausomai nuo situacijos ir architektūros:

  1. Per nuorodą į aktyvumą:

    Fragmentas gali gauti tiesioginę nuorodą į aktyvumą, prie kurio jis prijungtas.

    // Fragmento viduje
    if (activity is YourActivity) {
        (activity as YourActivity).yourActivityMethod()
    }
    

    Šis būdas yra paprastas, bet sukuria stiprią priklausomybę tarp fragmento ir konkretaus aktyvumo.

  2. Per atgalinio skambučio sąsają (Callback Interface):

    Tai lankstesnis ir rekomenduojamas būdas. Fragmentas apibrėžia sąsają, kurią turi įgyvendinti aktyvumas.

    // Fragmento viduje
    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
    }
    
    // Iškvietimas aktyvumo metodo iš fragmento
    fun callActivityMethod() {
        listener?.onYourActivityMethodCalled()
    }
    
    // Aktyvume
    class YourActivity : AppCompatActivity(), YourFragment.OnYourActivityMethodListener {
    
        override fun onYourActivityMethodCalled() {
            // Logika, kuri turi būti vykdoma aktyvume
        }
    
        // ... kitas aktyvumo kodas
    }
    

    Šis požiūris leidžia fragmentą naudoti pakartotinai, nes jis priklauso nuo sutarties (sąsajos), o ne nuo konkrečios aktyvumo klasės.

  3. Per ViewModel (rekomenduojama sudėtingesnėms sąveikoms):

    Bendro ViewModel naudojimas tarp fragmento ir aktyvumo leidžia jiems keistis duomenimis ir įvykiais be tiesioginių nuorodų.

    // Bendras ViewModel
    class SharedViewModel : ViewModel() {
        private val _callActivityMethodEvent = MutableLiveData<Event<Unit>>()
        val callActivityMethodEvent: LiveData<Event<Unit>> = _callActivityMethodEvent
    
        fun triggerActivityMethod() {
            _callActivityMethodEvent.value = Event(Unit)
        }
    }
    
    // Vienkartinių įvykių apvalkalo klasė
    open class Event<out T>(private val content: T) {
        var hasBeenHandled = false
            private set // Leidžia išorės skaityti, bet ne rašyti
    
        fun getContentIfNotHandled(): T? {
            return if (hasBeenHandled) {
                null
            } else {
                hasBeenHandled = true
                content
            }
        }
    
        fun peekContent(): T = content
    }
    
    // Fragmento viduje
    private val sharedViewModel: SharedViewModel by activityViewModels() // naudojame activityViewModels()
    
    // Aktivumo metodo iškvietimas per ViewModel
    fun callActivityMethod() {
        sharedViewModel.triggerActivityMethod()
    }
    
    // Aktivume
    private val sharedViewModel: SharedViewModel by viewModels()
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
    
        sharedViewModel.callActivityMethodEvent.observe(this, Observer { event ->
            event.getContentIfNotHandled()?.let {
                // Logika, kuri turi būti vykdoma aktyvume
            }
        })
    }
    

    Šis požiūris atitinka architektūrinių komponentų rekomendacijas ir palengvina testavimą.

Metodo pasirinkimas priklauso nuo sąveikos sudėtingumo. Paprastiems atvejams tinka tiesioginis iškvietimas arba sąsaja. Sudėtingesniems scenarijams, ypač duomenų perdavimui, geriau naudoti ViewModel.