Sådan kommunikerer du mellem fragmenter og aktivitet ved hjælp af ViewModel

Kommunikation er et af de vigtigste emner for udviklerne og kan udføres på mange måder. Men udfordringen er at gøre det på den nemmeste og optimerede måde. Vi kan gøre det ved at bruge statisk arkiveret, men det vil opstå hukommelsesproblemer. For at undgå hukommelsesproblemer gør mange udviklere noget lignende

(aktivitet som MainActivity) .passDataToAnotherFragment ()

Hvad er problemet med denne måde? Det binder fragmentet med en bestemt aktivitet, reducerer genanvendeligheden. Hvad er så den anbefalede måde?

Google anbefaler at bruge interface (før ViewModel) doc. Til dette skal vi implementere grænsefladen i aktivitetsklasse. Børnefragmenter vil have en henvisning til grænsefladen implementeret af aktivitet. Data overføres via interfacemetoder.

arbejdsgang af kommunikation ved hjælp af interface

Lad os antage et simpelt scenarie, hvor vi har to fragmenter under samme aktivitet, det ene til at indtaste et tal og det andet er at vise det dobbelte (2 x input). Aktivitet viser også en meddelelse Dit input er 123 som dette.

Kan du forestille dig, hvor meget kode vi har brug for at skrive, og hvor mange scenarier vi skal håndtere. Jeg går ikke nærmere ind på det, da denne artikel handler om den nemmeste løsning snarere end at demonstrere interface-implementering. Du kan finde implementeringen her.

Nem vej

Her kommer ViewModel for at redde os fra at håndtere en masse scenarie og implementere interface. Vi behøver kun at oprette ViewModel-klassen og oprette forekomst i fragment, men bruge aktivitetsomfanget, så det vil være tilgængeligt for alt fragmentet af aktiviteten inklusive aktiviteten i sig selv.

arbejdsgang af kommunikation ved hjælp af ViewModel

Opret en ViewModel-klasse

klasse SharedViewModel: ViewModel () {
    val inputNumber = MutableLiveData  ()
}

For at udsende eller videregive data fra vores inputfragment skal du oprette ViewModel i aktivitetsomfang. For at gøre dette skal vi videregive aktivitetsreferencen som argument for ViewModelProvides.of () -metoden. Noe bare overføre dataene til ViewModel-objektet som dette

aktivitet? .let {
    sharedViewModel = ViewModelProviders.of (it) .get (SharedViewModel :: class.java)
}

et_input.addTextChangedListener (objekt: TextWatcher {
    tilsidesætte sjov afterTextChanged (p0: Redigerbar?) {}

    tilsidesætte sjov før TekstChanged (p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

    tilsidesætte sjov onTextChanged (txt: CharSequence?, p1: Int, p2: Int, p3: Int) {
        txt? .let {
            var input = 0
            if (txt.toString (). isNotEmpty ()) {
                input = txt.toString (). toInt ()
            }

            sharedViewModel? .inputNumber? .postValue (input)
        }
    }

I aktiviteten har vi bare brug for at oprette eksempel på vores ViewModel og observere de krævede data som denne

val sharedViewModel = ViewModelProviders.of (dette) .get (SharedViewModel :: class.java)

sharedViewModel.inputNumber.observe (dette, Observer {
    det? .let {
        // gør nogle ting med nummeret
    }
})

Hvad nu med outputfragment? Vi kan gøre det samme for outputfragmentet for at observere dataene. Men husk, at vi har brug for at oprette ViewModel-instansen i aktivitetsomfang, ellers vil Android oprette en separat instans i stedet for at dele den samme instans, og vi får ikke dataene.

For outputfragment gør det sådan

aktivitet? .let {
    val sharedViewModel = ViewModelProviders.of (it) .get (SharedViewModel :: class.java)

    sharedViewModel.inputNumber.observe (dette, Observer {
    det? .let {
            // gør nogle ting med nummeret
        }
    })
}

Det er det. Kildekode kan findes her.

StackOverflow-diskussion

Happy Coding