Текст TextView изменяется, но не обновляется в макете (Kotlin - Android) - PullRequest
0 голосов
/ 21 марта 2020

Текст TextView изменяется, но не обновляется в макете. Я перепробовал все методы, которые мог найти, но ничего не получалось. У меня очень простое c приложение с одним видом деятельности и 3 макетами *. * Это первое приложение, которое я сделал, поэтому я подумал, что так будет проще Основные проблемы, с которыми я сталкиваюсь, две: почти вся информация вокруг старая и в java, и мой текст textView не меняется .. Приложение представляет собой простую игру "Рок-бумага-ножницы", которую я пытаюсь сделать в качестве упражнения.

Значения textViews.text обновляются, но в макете всегда отображается один и тот же текст ... Я понятия не имею, в чем может быть проблема. Я также изо всех сил пытаюсь понять, как именно все это работает точно ... как InflateLayout, Context и Android в целом. Я не очень понимаю из ссылки android.

НЕТ ВНУТРЕННЕГО (), POSTINFLATE (), FORCELAYOUT (), ВИДИМОСТЬ ВИДИМОСТИ, ПОТОМУ ЧТО НЕ ИХ РАБОТАЛ: (

Выдержка из кода

class MainActivity : AppCompatActivity() {

lateinit var TITLE:TextView
lateinit var PARAGRAPH:TextView

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

    val InflaterInitializer = LayoutInflater.from(applicationContext) as LayoutInflater
    val inflater = InflaterInitializer.inflate(R.layout.activity_2, null, false)

    TITLE= inflater.findViewById(R.id.title) as TextView
    PARAGRAPH= inflater.findViewById(R.id.paragraph) as TextView

}

Существует три функции, подобные этой:

fun FUNCTION(v :View) {
    val userChoice = "XXX"
    val computerChoice = getComputerChoice()
    if (userChoice == computerChoice) {
        FUNCTION_2(computerChoice)
    } else {
        runOnUiThread {
            TITLE.text =
                if (computerChoice == "YYY") getString(R.string.YOU_WON) else getString(R.string.YOU_LOSE);
            PARAGRAPH.text = getString(R.string.STRING, computerChoice)
        }
    }; resultScreen()
}

Функция_2 ...

private fun FUNCTION_2(cc :String) {
    runOnUiThread {
        TITLE.text = getString(R.string.STRING)
        PARAGRAPH.text = getString(R.string.STRING, cc)
    }; resultScreen()
}

resultScreen () - это просто вызов setContentView (LAYOUT)

Вот видео приложения и проблема обновления: https://imgur.com/a/iWCRMkq

Код завершен здесь: https://github.com/noiwyr/MorraCinese


РЕДАКТИРОВАТЬ К сожалению, ни один из ответов на самом деле не сработал, как я надеялся, однако Редизайн приложения и использование нескольких действий с некоторыми изменениями решили проблему. Вы можете найти новый код в репозитории github.

Однако мне было бы интересно узнать, есть ли работающее решение для этого вопроса:)

Ответы [ 3 ]

1 голос
/ 21 марта 2020

Вызывая InflaterInitializer.inflate(R.layout.activity_2, null, false), вы накачиваете новую иерархию представлений из указанного ресурса xml, который не привязан ни к одному из ваших представлений (эти новые представления не отображаются на вашем экране). Затем вы нашли текстовые представления из этой новой иерархии представления и изменили их заголовки.

Итак, ваш onCreate метод должен выглядеть следующим образом:

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

   TITLE = findViewById(R.id.title)
   PARAGRAPH = findViewById(R.id.paragraph)
}

Также , избыточно использовать методы runOnUiThread() (ваш код уже выполняется в потоке пользовательского интерфейса) и resultScreen().

0 голосов
/ 21 марта 2020

В вашем коде довольно много ошибок, поэтому я собираюсь разбить ответ вашим кодом. Обязательно найдите Комментарии встроенными

class MainActivity : AppCompatActivity() {

    /**
    * First, Follow conventions for naming variables, they are usually in camelcase for variables and functions, Capitalized for Constants.
    * Second, lateinit is used to defer the initialization of a variable, for views, such as 
    * TextView's, you could use the Kotlin Synthentic library which automatically references the Views of your layout. 
    */
    lateinit var TITLE:TextView
    lateinit var PARAGRAPH:TextView

    override fun onCreate(savedInstanceState :Bundle?) {
        super.onCreate(savedInstanceState)
        /** 
        * Set content view, internally set's the layout file after inflation using the Activity context. Which means, that you do not 
        * need to specifically inflate the view. 
        */
        setContentView(R.layout.activity_main)

        /**
        * This is the reason why your layout doesn't know refresh, what you're doing here is inflating another layout, but not setting it to your activity. 
        * This is not required as explained above
        */
        val InflaterInitializer = LayoutInflater.from(applicationContext) as LayoutInflater
        /**
        * Inflater inflates a View Object. one would use this approach if they were programatically adding Views 
        */
        val inflater = InflaterInitializer.inflate(R.layout.activity_2, null, false)

        /**
        * the below views are pointing to a reference of TextView for the non visible inflated view. Which is the reason why the text is not updated. 
        */
        TITLE= inflater.findViewById(R.id.title) as TextView
        PARAGRAPH= inflater.findViewById(R.id.paragraph) as TextView

    }
}

Вот код, который заставит все работать

class MainActivity : AppCompatActivity() {

    private var title:TextView? = null
    private var paragraph:TextView? = null

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

        title= inflater.findViewById(R.id.title) as TextView
        paragraph= inflater.findViewById(R.id.paragraph) as TextView

    }

    fun function(v :View) {
        val userChoice = "XXX"
        val computerChoice = getComputerChoice()
        if (userChoice == computerChoice) {
            function2(computerChoice)
        } else {
            title.text = if (computerChoice == "YYY") getString(R.string.YOU_WON) else getString(R.string.YOU_LOSE);
            paragraph.text = getString(R.string.STRING, computerChoice)

        } 
        resultScreen()
    }

    private fun function2(cc :String) { 
       title.text = getString(R.string.STRING)
       paragraph.text = getString(R.string.STRING, cc)
       resultScreen()
    }
}

Если ваш вариант использования предназначен для показа разных экранов, посмотрите на запуск нескольких действий и переход между их используя Intents

0 голосов
/ 21 марта 2020

Вам ничего не нужно, вы создали код без проблем. Я предлагаю вам

val InflaterInitializer = LayoutInflater.from (applicationContext) как LayoutInflater val inflater = InflaterInitializer.inflate (R.layout.activity_outcome, null, false )

Комментировать этот код выше не нужно: kotlin

motivoRisultato.text = getString (R.string.scelta_p c, computerChoice)

Просто сделайте этот тип кода

...