Вопросы по использованию liveData.observe - PullRequest
0 голосов
/ 28 января 2020

Я изучаю Android разработку самостоятельно. Я думал, что я получил голову о том, что / как 'liveData.observe' работал. Но ...

Создание небольшого простого приложения, которое прослушивает ввод с устройства Bluetooth и отображает или скрывает изображение на основе этого входа Bluetooth.

У меня все это работает, но теперь я хочу добавить еще одну функцию, и я бегу в стену. Особенность заключается в увеличении счетчика каждый раз, когда liveData.Observe возвращает TRUE.

Либо я не понимаю 'liveData.observe', либо я пытаюсь использовать его неправильно (возможно, это обе эти вещи ).

Сейчас я работаю над функцией увеличения счетчика, и это то место, где я зацикливаюсь. В настоящее время я думаю создать отдельную функцию (pigCounter ()). Но я никуда не денусь.

onCreate

class MainActivity : AppCompatActivity() {
private var liveData: MutableLiveData<String> = MutableLiveData()

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

...
</SNIP>

liveData.observe(this, androidx.lifecycle.Observer {
        imageView_mothership_LED_state.showOrHideImage(it == "1")
    })

pigCounter()

}

Ниже приведено имя Activity_main. xml

imageView_mothership_LED_state

<ImageView
        android:id="@+id/imageView_mothership_LED_state"
        android:layout_width="124dp"
        android:layout_height="144dp"
        android:scaleType="fitCenter"
        android:soundEffectsEnabled="false"
        app:layout_constraintBottom_toBottomOf="@+id/imageView_blueYesOrNo"
        app:layout_constraintEnd_toEndOf="@+id/imageView_blueYesOrNo"
        app:layout_constraintStart_toStartOf="@+id/imageView_blueYesOrNo"
        app:layout_constraintTop_toTopOf="@+id/imageView_blueYesOrNo"
        app:srcCompat="@drawable/ic_check_black_24dp"
        android:contentDescription="Check mark image to indicate if LED is on/off" />

Ниже приведена функция, которая устанавливает видимость изображений

showOrHideImage ()

// display or don't display check mark image
private fun View.showOrHideImage(imageShow: Boolean) {
    visibility = if (imageShow) View.VISIBLE else View.GONE
}

Это функция, которая обрабатывает входящие данные Bluetooth.

readBlueToothDataFromMothership ()

private fun readBlueToothDataFromMothership(bluetoothSocket: BluetoothSocket) {
    Log.i(LOGTAG, Thread.currentThread().name)
    val bluetoothSocketInputStream = bluetoothSocket.inputStream
    val buffer = ByteArray(1024)
    var bytes: Int
    //Loop to listen for received bluetooth messages
    while (true) {
        try {
            bytes = bluetoothSocketInputStream.read(buffer)
            val readMessage = String(buffer, 0, bytes)
            liveData.postValue(readMessage)
        } catch (e: IOException) {
            e.printStackTrace()
            break
        }
    }

Это функция, которую я пишу, в которой я хочу увеличивать счетчик каждый раз.

pigCount

private fun pigCount() {
    var count = 0
    var counterTextView = findViewById<TextView>(R.id.textView_blueCounter)

    if(imageView_mothership_LED_state.showOrHideImage(true)) {
        counterTextView.text = count.toString()
        count++
    }

Это не работает из-за несоответствия типов (ожидание логического значения, получение модуля). Я также попытался переместить это в функцию liveData.observe в onCreate (). Но тот же дорожный блок.

Может кто-нибудь направить меня в правильном направлении. У меня есть подлое чувство, что я далеко от этого. И оценил бы толчок. :)

1 Ответ

1 голос
/ 29 января 2020

Чтобы подсчитать, сколько раз LiveData возвращает true, это действительно легко, вы можете просто использовать MediatorLiveData.

Если у вас есть правильный LiveData<Boolean>, вы можете сделать следующее :

val trueFalse = MutableLiveData<Boolean>()

val counter by lazy {
     MediatorLiveData<Int>().apply {
          value = 0 // Initialize the counter
          // Add the trueFalse as a source of this live data
          addSource(trueFalse) { boolVal ->
              if(boolVal == true) {
                  // If the mediator live data had a value, use it, if null use 0; and add +1 to it because the boolVal was true
                  value = (value ?: 0) + 1
              }
          }
     }
}

/* Somewhere else in the code */
fun setupTextView() {
    counter.observe({lifecycle}) {
        val tv = findViewById<TextView>(R.id.tv_something)
        tv.text = "$it"
    }
}

Это создает MediatorLiveData, который будет иметь в качестве источника действительные данные trueFalse. Если значение true будет продолжено и опубликует новое значение в counter живых данных.

...