Как получить значение переменной в лямбда-выражении извне функции в Kotlin - PullRequest
0 голосов
/ 06 апреля 2019

Я пытаюсь получить значение переменной "finalvalue", чтобы использовать ее в другой функции, но она не видна / недоступна извне функции "edittext.onClickListener ()".

Я пытался объявить его как объект-компаньон, но все же не смог сделать это.Кроме того, объявление его в основном классе делает его видимым, но я хочу, чтобы обновленное значение этой переменной было установлено в функции "edittext.onClickListener ()".

Чего мне не хватает?Спасибо.

ОБНОВЛЕНИЕ: Несколько слов о программе.Это просто таймер обратного отсчета.edittext.getText () принимает ввод (сколько секунд), затем преобразует его в целое число.В следующей функции с именем «startbutton.onClickListener» я умножаю ее на 1000, чтобы преобразовать в секунды и начать обратный отсчет.проблема в том, что я не могу получить обновленное значение "finalvalue".У меня есть только доступ к начальному значению переменной.

class MainActivity : AppCompatActivity() {



override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var finalvalue = 30

    val day_night=findViewById<Button>(R.id.day_night)
    val setbutton=findViewById<Button>(R.id.setbutton)
    val stopbutton=findViewById<Button>(R.id.stopbutton)
    val startbutton=findViewById<Button>(R.id.startbutton)
    val antistrofimetrisi=findViewById<TextView>(R.id.antistrofimetrisi)
    val edittext=findViewById<EditText>(R.id.edittext)


    var edittextIsVisible = false
    antistrofimetrisi.setText("0")

    setbutton.setOnClickListener() {
        if(edittextIsVisible == false) {
            edittext.setVisibility(View.VISIBLE)
            edittextIsVisible = true }

        else {
            edittext.setVisibility(View.GONE)
            edittextIsVisible = false }

    }


    edittext.setOnEditorActionListener() { v, actionId, event ->
        if (actionId == EditorInfo.IME_ACTION_DONE && edittext.getText().toString() == "")
        {
            Toast.makeText(this, "Εισάγετε έγκυρο αριθμό δευτερολέπτων", Toast.LENGTH_LONG).show()
            true
        }

        else

        {
            var value: String = edittext.getText().toString()
            var finalvalue = Integer.parseInt(value)
            antistrofimetrisi.setText(finalvalue.toString())
            Toast.makeText(
                this,
                "Πιέστε START για αντίστροφη μέτρηση από τα " + finalvalue + " δευτερόλεπτα",
                Toast.LENGTH_SHORT
            ).show()



            false
        }
    }



    startbutton.setOnClickListener()
    {
        var secondsLeft: Int = 0
        var finalseconds = finalvalue*1000
        val timer = object: CountDownTimer(finalseconds.toLong(), 100) {
            override fun onTick(millisUntilFinished: Long) {

                if (Math.round(millisUntilFinished.toFloat() / 1000.0f) != secondsLeft)
                {
                    secondsLeft = Math.round(millisUntilFinished.toFloat() / 1000.0f)
                    antistrofimetrisi.setText(secondsLeft.toString())
                }



                var timeleft = millisUntilFinished / 1000
                antistrofimetrisi.setText(timeleft.toString()) }



            override fun onFinish() {
                antistrofimetrisi.setText("0")
                start()
            }
        }.start()


        stopbutton.setOnClickListener()
        {
            timer.cancel()
            antistrofimetrisi.setText("0")
        }
    }

1 Ответ

1 голос
/ 07 апреля 2019

Ваша главная проблема в том, что вы следите за переменной.Вы объявили var finalValue дважды - около вершины onCreate и внутри обратного вызова.Внутри обратного вызова вы обновляете временную переменную, которая существует только в этой области.Внешняя переменная никогда не обновляется.

У вас нет переменной на уровне класса.Самая внешняя версия определяется только в пределах onCreate.

class MainActivity : AppCompatActivity() {

    // this is not a good variable name, since the variable is not final 
    // in the programming sense or in any other sense of the word
    var finalValue = 30   

    override fun onCreate(savedInstanceState: Bundle?) {

        // ...

        edittext.setOnEditorActionListener { v, actionId, event ->

            // ...

            var value: String = edittext.getText().toString()

            // note that I'm not re-declaring with "var" here
            finalvalue = Integer.parseInt(value)

            // ...
        }

        // ...
    }
}

Если бы я мог дать другой совет:

  1. Правильно отформатируйте код.Используйте функцию автоматического форматирования Android Studio.То, что у вас здесь есть, похоже на стиль C, но это Котлин, так что ...
  2. Разбейте свой код.Причина, по которой вы столкнулись с проблемами, заключается в том, что у вас есть только одна гигантская функция, которая делает все.Ваши обратные вызовы должны просто вызывать функцию, где эта функция выполняет всю логику.Примерно так:
fun onCreate(savedInstanceState: Bundle?) {

    editText.setOnEditorActionListener { v, actionId, event ->
        onEditTextChanged(editText.getText())
    }
}

fun onEditTextChanged(text : String) {
    // all of the logic from the callback goes here
}

Когда ваш код менее перемешан, легче понять, что такое логика.

Часто найти ошибку в грязном коде - это как найти что-тов грязной комнате.Если вы хотите что-то найти, начните собирать.Тогда вы выполняете две вещи одновременно.Когда вы будете чистить, вы найдете то, что ищете - и у вас будет хорошая чистая комната!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...