Kotlin - przekazywanie zmiennych między funkcjami

0

Mam dwie funkcje i chcę stworzyć trzecią.
Potrzebuję w niej użyć wartości zmiennych z tych dwóch pierwszych funkcji.
Proszę o jakąś podpowiedź. :-)

4
val a = getA()
val b = getB()
val c = combine(a, b)
1

@Waran3:

a. Zmienna wewnętrzna FUNKCJI jest niedostępna .
b. rozumienie @stivens 'a ma sens, o ile zgadnął o co ci chodzi
c) osobiście sądzę, że nie zgadnął, a ty rozwiązujesz zły problem (Problem XY), i obstawiam że chcesz klasy, wtedy o funkcjach mówimy metody, i maja dostęp do pól klasy.

0

Opiszę to dokładniej.
Zrobiłem coś takiego:
screenshot-20220415193836.png

W sumie to są dwie funkcje:

 Column(
                       //modifier = Modifier.fillMaxHeight(22f)
                      // modifier = Modifier.fillMaxSize(1f)
                   modifier = Modifier
                       .padding(horizontal = 12.dp, vertical = 12.dp)
                   )
                   {

                       MainContent()
                       MainContent_2()

                   }

Potrzebuję wyciągnąć z nich to co się wyświetla jako "Wynik".
Czyli chodzi o zmienne: suma_1, suma_2, suma_3 i suma_4.
Niestety zadeklarowanie zmiennych jako globalnych nie załatwia sprawy bo i tak
wynik nie wychodzi poza funkcje.

Wrzucam fragment kodu odpowiadający za dwie ramki czyli jedną funkcję:

@Composable
fun MainContent(){
    var sliderPosition_1 by remember { mutableStateOf(0F)}
    var sliderPosition_2 by remember { mutableStateOf(0F)}
    var sliderPosition_3 by remember { mutableStateOf(0F)}

    var sliderPosition_4 by remember { mutableStateOf(0F)}
    var sliderPosition_5 by remember { mutableStateOf(0F)}
    var sliderPosition_6 by remember { mutableStateOf(0F)}

    var wynik_1 = (sliderPosition_1 * 33).roundToInt()
    var wynik_2 = (sliderPosition_2 * 33).roundToInt()
    var wynik_3 = (sliderPosition_3 * 33).roundToInt()
    var suma_2 = wynik_1 + wynik_2 + wynik_3

    var wynik_4 = (sliderPosition_4 * 33).roundToInt()
    var wynik_5 = (sliderPosition_5 * 33).roundToInt()
    var wynik_6 = (sliderPosition_6 * 33).roundToInt()
    var suma_3 = wynik_4 + wynik_5 + wynik_6


    Row(
        modifier = Modifier
            .fillMaxWidth()
            .background(Color.DarkGray)
            .padding(6.dp),
//verticalAlignment = Alignment.CenterVertically,
//horizontalArrangement = Arrangement.Center


    ) {
        Box(                // pole lewe górne
            Modifier
                .background(Color.Red)
                //.fillMaxSize(0.3F)
                .padding(0.dp)
                .background(Color.White)
                .fillMaxWidth(0.49F)
                .fillMaxHeight(0.3F)

        ) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally
            ) {


            Text(
                text = " MIND: ${(sliderPosition_1 * 33).roundToInt()}",
                fontWeight = FontWeight.Bold
            )
            Slider(
                value = sliderPosition_1,
                onValueChange = { sliderPosition_1 = it },
                enabled = true,
                colors = SliderDefaults.colors(
                thumbColor = Color.Red,
                activeTickColor = Color.Black,
                inactiveTickColor = Color.Gray
                )
            )
            Text(
                text = " BODY: ${(sliderPosition_2 * 33).roundToInt()}",
                fontWeight = FontWeight.Bold
            )
            Slider(
                value = sliderPosition_2,
                onValueChange = { sliderPosition_2 = it },
                        enabled = true,
                colors = SliderDefaults.colors(
                    thumbColor = Color.Red,
                    activeTickColor = Color.Black,
                    inactiveTickColor = Color.Gray
            )
            )
            Text(
                text = " SOUL: ${(sliderPosition_3 * 33).roundToInt()}",
                fontWeight = FontWeight.Bold
            )
            Slider(
                value = sliderPosition_3,
                onValueChange = { sliderPosition_3 = it },
                        enabled = true,
                colors = SliderDefaults.colors(
                    thumbColor = Color.Red,
                    activeTickColor = Color.Black,
                    inactiveTickColor = Color.Gray
            )
            )
                Text(
                    text = " ZAWODNIK 2   Wynik = $suma_2",
                    fontWeight = FontWeight.Bold,
                    fontStyle = FontStyle(1),
                    style = MaterialTheme.typography.h5,


                )
        }
        }

        Box(
            Modifier                        // pole prawe górne
                .background(Color.Yellow)
                .padding(0.dp)
                .background(Color.LightGray)
                .fillMaxWidth(1F)
                .fillMaxHeight(0.3F)
        ) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally
            ) {


            Text(
                text = " MIND: ${(sliderPosition_4 * 33).roundToInt()}",
                fontWeight = FontWeight.Bold
            )
            Slider(
                value = sliderPosition_4,
                onValueChange = { sliderPosition_4 = it },
                enabled = true,
                colors = SliderDefaults.colors(
                thumbColor = Color.Red,
                activeTickColor = Color.Black,
                inactiveTickColor = Color.Gray
                )
            )
            Text(
                text = " MIND: ${(sliderPosition_5 * 33).roundToInt()}",
                fontWeight = FontWeight.Bold
            )
            Slider(
                value = sliderPosition_5,
                onValueChange = { sliderPosition_5 = it },
                enabled = true,
                colors = SliderDefaults.colors(
                    thumbColor = Color.Red,
                    activeTickColor = Color.Black,
                    inactiveTickColor = Color.Gray
                )
            )
            Text(
                text = " MIND: ${(sliderPosition_6 * 33).roundToInt()}",
                fontWeight = FontWeight.Bold
            )
            Slider(
                value = sliderPosition_6,
                onValueChange = { sliderPosition_6 = it },
                enabled = true,
                colors = SliderDefaults.colors(
                    thumbColor = Color.Red,
                    activeTickColor = Color.Black,
                    inactiveTickColor = Color.Gray
                )
            )
                Text(
                    text = " ZAWODNIK 3   Wynik = $suma_3",
                    fontWeight = FontWeight.Bold,
                    fontStyle = FontStyle(1),
                    style = MaterialTheme.typography.h5,


                    )
        }
        }
        }
    }



1

Twoje funkcje sa za dlugie, robia za duzo. Musisz to podzielic na mniejsze, bardziej wyspecjalizowane. Wtedy latwo bedziesz mogl reuzywac raz policzone rzeczy i bedzie czytelniej.

Minimalne rozbicie bedzie wygladac np. tak:

val sliderPositions = getSliderPositions()
val sums = calcSums(sliderPositions)
MainContent(sliderPositions, sums)
MainContent_2(sums)

Docelowo powinienes to rozbic jeszcze bardziej.

I lepiej nazywac rzeczy. Ale to swoja droga :)

PS: masz totalnie zle wciecia, biale znaki. Popracuj nad tym bo to utrudnia czytanie funkcji. IDE powinno byc w stanie Ci to ladnie przeformatowac :)

0

Temat załatwiłem ( pewnie doraźnie ) przez return, tak żeby funkcja zwracała wartości tych zmiennych.

 return zawodnik_2
 return zawodnik_3

  var wynik_1 = (sliderPosition_1 * 33).roundToInt()
    var wynik_2 = (sliderPosition_2 * 33).roundToInt()
    var wynik_3 = (sliderPosition_3 * 33).roundToInt()
    var suma_2 = wynik_1 + wynik_2 + wynik_3

    var wynik_4 = (sliderPosition_4 * 33).roundToInt()
    var wynik_5 = (sliderPosition_5 * 33).roundToInt()
    var wynik_6 = (sliderPosition_6 * 33).roundToInt()
    var suma_3 = wynik_4 + wynik_5 + wynik_6

    zawodnik_2 = suma_2
    zawodnik_3 = suma_3

package com.example.eliminacje_1

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.eliminacje_1.ui.theme.Eliminacje_1Theme
import kotlin.math.roundToInt


var zawodnik_1: Int = 0
var zawodnik_2: Int = 0
var zawodnik_3: Int = 0
var zawodnik_4: Int = 0

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Eliminacje_1Theme {

@Composable
fun MainContent(): Int {
    var sliderPosition_1 by remember { mutableStateOf(0F) }
    var sliderPosition_2 by remember { mutableStateOf(0F) }
    var sliderPosition_3 by remember { mutableStateOf(0F) }

Wygląda to teraz tak:
https://youtube.com/shorts/D0Y2u5QXdpk

Nie wiem czemu link nie chce działać z tego miejsca.

1
return zawodnik_2
return zawodnik_3

Ale ze tak doslownie jak wyzej? Tylko jeden return z funkcji jest efektywny. Reszta sie nie wykona. Ale mozesz zwrocic kilka wartosci na raz (w jakiejs strukturze - np. customowej klasie lub krotce).

PS: moze nie zaczynaj od razu od androida per se a naucz sie podstaw w konsoli - bedzie prosciej. Bo tutaj duzo szumu androidowego jest

0
stivens napisał(a):
return zawodnik_2
return zawodnik_3

Ale ze tak doslownie jak wyzej? Tylko jeden return z funkcji jest efektywny. Reszta sie nie wykona. Ale mozesz zwrocic kilka wartosci na raz (w jakiejs strukturze - np. customowej klasie lub krotce).

PS: moze nie zaczynaj od razu od androida per se a naucz sie podstaw w konsoli - bedzie prosciej. Bo tutaj duzo szumu androidowego jest

  1. Ciekawa jest wiara kolegi, że z tym podwójnym returnem "jest dobrze", ale na pewnym etapie się nie widzi błędów. To nawet kompialtor protestuje, ale jak sie nie czyta komunikatów to ...
  2. @Waran3 w pelni sie zgadzam, ze trochę za wysoko próbujesz w stosunku do umiejętności. Musisz głęboko poćwiczyć podstawy w neutralnym (od naleciałości, czyli konsola) środowisku, w pełni sie zgadzam.
1

Zgadzam sie(bo sam rok temu zaczynalem) zeby nie zaczynac od Androida z Kotlinem. Poswiec 2-3 miesiace, ile tam uwazasz na poznanie Kotlina, zrob sobie sumiennie sciezke na hyperskillu, poznaj typy danych, jak kod ze soba wspolpracuje.
Zaczynanie od Androida bez pojecia o programowaniu ogromnie zaciemnia obraz co jest w ogole specyficzne dla programowania ogolnie, Kotlina czy platformy. Ty jeszcze dokladasz Compose, ktory ma ogrom swoich ‚wlasciwosci’.

Imho baw sie dobrze tym projektem ale sam po sobie wiem jak duzo da porzadne zrozumienie podstaw.

Na przyklad zrob sobie sciezke basic i nastepna wraz z projektami na hyperskillu, beda to na wpol porzadne projekty konsolowe, ja nastepnie przenioslem takie projekty na androida, dorobilem ui, podzielilem kod na klasy i funkcje i jakos zaczelo isc :)

0
stivens napisał(a):
return zawodnik_2
return zawodnik_3

Ale ze tak doslownie jak wyzej?

Tak, dosłownie. :-) Nic nie poradzę że to działa :-) ale ok, dzięki za info. A i kompilator nic nie zgłasza.
To że działa widać na filmie. Zmienne pod tabelką są wyciągnięte ( po dwie ) z funkcji. Fragmenty kodów zamieściłem.

Na przyklad zrob sobie sciezke basic

Bardzo dziękuję za rady :-) ale będę bardzo wdzięczy za podpowiedzi w tym "szalonym" sposobie nauki. :-)
Konsoli mam dosyć, jest nudna. :-) Jadę zadaniowo...a że trafiła się taka okazja to tym bardziej.
Nie muszę wymyślać sam sobie programów, ktoś to zrobił za mnie.
Czegoś nie wiem...douczam się, czytam i pytam...Wiem, że może to być irytujące ale liczę, że kilku osobą starczy cierpliwości. :-)
Naprawdę jestem bardzo wdzięczny za wszystko co tu piszecie ale będę jechał po swojemu. :-)
A...i mam świadomość,że kod krzywy, że pytam o oczywiste oczywistości i że robię całą masą błędów, nawet głupich...ale pomimo wszystko już jest kawałek działającego programu, nieprawdaż? Howk ;-)

0

Filmik nie dziala. Dwa returny, jeden za drugim tez nie dzialaja. Trust me - wiem co mowie :)

EDIT: widze teraz ze zrobiles zmienne globalne. Moze w tym rzecz? ;)

0
stivens napisał(a):

Filmik nie dziala.

https://www.youtube.com/shorts/D0Y2u5QXdpk - działa tylko jakoś z tego forum nie chce. Skopiuj może link i wstaw bezpośrednio w YT.:-)
Wiem że wiesz co mówisz...i to bardzo doceniam. :-)

EDIT: widze teraz ze zrobiles zmienne globalne. Moze w tym rzecz? ;)

Od tego zacząłem ale samo to nic nie dało, dopiero jak dołożyłem te returny w funkcjach.

0
Waran3 napisał(a):

..ale pomimo wszystko już jest kawałek działającego programu, nieprawdaż? Howk ;-)

Tym gorzej. Jak nie działa - tzn autor ma świadomość, że nie działa - ma jakieś szanse. Jak sam sobie udowodni, że jest dobrze - juz żadnych

"Coś działa" ale nawet nie rozumiesz dlaczego. Po prostu masz "parzystą ilość błędów"

A ta a propos, udowadnianie doskonałości swojego programu jest podstawowym wskaźnikiem pewnego rodzaju początkujących - i wielu z nich zostaje takimi do końca, sam sobie sterem, żeglarzem, okrętem.
Teoria - szajs, propozycje jakościowe do kodu - szajs, wzorce dobrego programowani - szajs.

0

Pokazesz cay kod co masz? Moze git hub?
We fragmentach ktore tu wkleiles nie ma tego o czym myslimy wydaje mi sie, poza tym cudow nie ma, dwa returny w metodzie w ten sposob to Android Studio drugi Ci powinno oznaczyc jako unreachable code. Albo nie rozumiemy dokladnie jak to masz zaimplementowane albo nie widzisz tego po prostu ze drugi return w ogole nie jest brany pod uwage.

Dodatkowo wystarczyloby przypisac nowa wartosc do zmiennej globalnej, returny nie sa tu w ogole potrzebne chyba ze faktycznie wydzieliles jakies kawalki kodu do osobnych metod. Ale znowu, czesto jak ktos chce pomoc to pisze jak mu sie wydaje ale Twoj przypadek moze byc zupelnie inny, pokaz po prostu co tam masz dokladniej :)

0
Waran3 napisał(a):
stivens napisał(a):

Filmik nie dziala.

https://www.youtube.com/shorts/D0Y2u5QXdpk - działa tylko jakoś z tego forum nie chce. Skopiuj może link i wstaw bezpośrednio w YT.:-)
Wiem że wiesz co mówisz...i to bardzo doceniam. :-)

EDIT: widze teraz ze zrobiles zmienne globalne. Moze w tym rzecz? ;)

Od tego zacząłem ale samo to nic nie dało, dopiero jak dołożyłem te returny w funkcjach.

Nie. Pierwsza wersja kodu, ktora wstawiles NIE miala zmiennych globalnych. Te sie pojawily dopiero teraz.

A z filmikiem nie chce mi sie kombinowac bo i tak nie ma on dla mnie duzej wartosci. Kodu z niego nie skopiuje zeby poprawic. To co chcemy widziec to wklejony kod a nie nagranie :)

0

Android Studio drugi Ci powinno oznaczyc jako unreachable code.

Dokładnie tak jest ;-)
Pomimo że tę linię wykasowałem zmienna jest widoczna na zewnątrz.
Ale jak wyrzucę zupełnie Return z funkcji to żadna zmienna nie działa tak jak powinna.

0

"Coś działa" ale nawet nie rozumiesz dlaczego.

No tak, jest w tym sporo prawdy :-)

Po prostu masz "parzystą ilość błędów"

Tego to nie rozumiem :-)

1

No dziala to dlatego, ze masz zmienne globalne a nie returny

1

Ok, po pierwsze gratulacje, że program działa :)

Twój cały widok jest statyczny, nie ma żadnego listenera, który by słuchał zmiany stanu na sliderach i wyświetlał nową wartość w polu tekstowym.
W Compose musisz miec MutableState dla każdej funkcji @Composable aby dynamicznie zmieniać jej wartość. Text() którego używasz jest typem funkcji Composable właśnie.

Tak żeby Ci kompletnie nie namieszać, możesz sobie zamienić swoje 'zmienne globalne' z typu Int na mutableStateOf():

private val zawodnik1 = mutableStateOf(0)
private val zawodnik2 = mutableStateOf(0)
private val zawodnik3 = mutableStateOf(0)
private val zawodnik4 = mutableStateOf(0)

Następnie każdy Twój Text() niech odnosi się do tych wartości:

Text(
    text = " zawodnik 1 = ${zawodnik1.value}",
    fontWeight = FontWeight.Bold,
    fontStyle = FontStyle(1),
    style = MaterialTheme.typography.h5,
    )

funkcje:

@Composable
fun MainContent() {
    var sliderPosition_1 by remember { mutableStateOf(0F) }
    var sliderPosition_2 by remember { mutableStateOf(0F) }
    var sliderPosition_3 by remember { mutableStateOf(0F) }

    var sliderPosition_4 by remember { mutableStateOf(0F) }
    var sliderPosition_5 by remember { mutableStateOf(0F) }
    var sliderPosition_6 by remember { mutableStateOf(0F) }

    var wynik_1 = (sliderPosition_1 * 33).roundToInt()
    var wynik_2 = (sliderPosition_2 * 33).roundToInt()
    var wynik_3 = (sliderPosition_3 * 33).roundToInt()
    var suma_2 = wynik_1 + wynik_2 + wynik_3

    var wynik_4 = (sliderPosition_4 * 33).roundToInt()
    var wynik_5 = (sliderPosition_5 * 33).roundToInt()
    var wynik_6 = (sliderPosition_6 * 33).roundToInt()
    var suma_3 = wynik_4 + wynik_5 + wynik_6

    zawodnik2.value = suma_2
    zawodnik3.value = suma_3

    etc
    etc

To jest jakaś tam podstawa dynamicznego zmieniania wartości, możesz mieć viewModel z LiveData czy na przykład Flow, samego mutableStateFlow już zresztą używasz.
Powyższy kod to tylko lekki refaktor, następnie czytając o np mutableStateFlow może ogarniesz sobie swoje własne funkcje wyświetlające text dynamicznie i pozbędziesz się zmiennych globalnych.

https://developer.android.com/jetpack/compose/architecture
https://developer.android.com/jetpack/compose/text
https://joebirch.co/android/exploring-jetpack-compose-column/

A dlaczego działało z returnami?
Ciekawym zrządzeniem losu wstawiłeś funckcje w których są obliczenia razem z widokiem. Dzięki returnowi wychodziłeś z funkcji i cały widok przeładowywał się i budował od nowa, przy każdym poruszeniu slidera, upraszczając, przeładowywałeś swój widok(a nie odświeżałeś pole tekstowe).

Podaj sobie np do funkcji return "lol" i zobacz, że również Ci 'zadziała' :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1