Привязка данных в onActivityResult

#android #kotlin

#Android #kotlin

Вопрос:

Во-первых, я хочу сказать вам, что я новичок в программировании на Kotlin, и это мое первое приложение. Вкратце, часть моего приложения состоит из интерфейса Bluetooth, и я решил использовать функциональность привязки данных вместо FindViewById . Я хочу изменить текст идентификатора status_bluetooth , Fragment_bluetooth когда пользователь нажимает переключатель, но мое приложение выходит из строя, когда я пытаюсь связать свои представления внутри OnActivityResult , и я не знаю почему (в других случаях это работает). Заранее спасибо. Вот код: 1).kt

 import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import com.example.drinkbf.databinding.FragmentBluetoothBinding


class ConnectivityBluetooth : Fragment() {

    data class Statusbluetooth(
        var status: String = ""
    )

    lateinit var bAdapter: BluetoothAdapter
    private lateinit var STATUS: Statusbluetooth
    private val REQUEST_CODE_ENABLE_BT: Int = 1

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View {
        // Inflate the layout for this fragment
        val binding = DataBindingUtil.inflate<FragmentBluetoothBinding>(
            inflater, R.layout.fragment_bluetooth, container, false
        )

        bAdapter = BluetoothAdapter.getDefaultAdapter()

        if (bAdapter.isEnabled) {
            STATUS = Statusbluetooth("Bluetooth is available")
            binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_on)
        } else {
            STATUS = Statusbluetooth("Bluetooth isn't available")
            binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_off)
        }
        binding.bluetoothSwitch.setOnClickListener {
            if (bAdapter.isEnabled) {
                bAdapter.disable()
                STATUS = Statusbluetooth("Bluetooth isn't available")
                binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_off)
                Toast.makeText(requireActivity(), "Bluetooth is disabled", Toast.LENGTH_SHORT)
                    .show()
            } else {
                val intent = Intent(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
                startActivityForResult(intent, REQUEST_CODE_ENABLE_BT)
            }
        }

        binding.statusB = STATUS
        return binding.root
    }
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?){
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE_ENABLE_BT) {
            if (resultCode == Activity.RESULT_OK) {
            }
//I don't know how can i binding here, for example : STATUS = Statusbluetooth("Bluetooth is available")
// binding.BluetoothImage.setImageResource(R.drawable.ic_bluetooth_on)
        }
//binding.statusB = STATUS
    }

}
 
  1. XML-файл (Fragment_bluetooth)
     <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <variable
            name="statusB"
            type="com.example.drinkbf.ConnectivityBluetooth.Statusbluetooth" />

    </data>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@ id/linearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:layout_editor_absoluteY="81dp">

            <TextView
                android:id="@ id/status_bluetooth"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginBottom="16dp"
                android:gravity="center"
                android:text="@={statusB.status}"
                app:layout_constraintBottom_toTopOf="@ id/BluetoothImage"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <ImageView
                android:id="@ id/BluetoothImage"
                android:layout_width="100dp"
                android:layout_height="100dp"
                android:layout_marginTop="8dp"
                android:layout_marginBottom="100dp"
                android:contentDescription="@string/icona_bluetooth_OFF"
                android:padding="5dp"
                app:layout_constraintBottom_toTopOf="@ id/bluetooth_switch"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.498"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@ id/discoverable_switch" />

            <Switch
                android:id="@ id/bluetooth_switch"
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                android:layout_marginBottom="20dp"
                android:contentDescription="@string/attiva_disattivaSWITCH"
                android:gravity="start"
                android:text="@string/on_off_switch"
                android:textAlignment="gravity"
                app:layout_constraintBottom_toTopOf="@ id/discoverable_switch"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.504"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@ id/BluetoothImage"
                tools:ignore="UseSwitchCompatOrMaterialXml" />

            <Switch
                android:id="@ id/discoverable_switch"
                android:layout_width="300dp"
                android:layout_height="wrap_content"
                android:layout_marginBottom="20dp"
                android:contentDescription="@string/discoverable"
                android:gravity="start"
                android:text="@string/discoverable"
                android:textAlignment="gravity"
                app:layout_constraintBottom_toTopOf="@ id/textView2"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@ id/bluetooth_switch"
                tools:ignore="UseSwitchCompatOrMaterialXml" />

            <TextView
                android:id="@ id/textView2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:text="@string/paired_devices_text"
                app:layout_constraintBottom_toTopOf="@ id/paired_devices"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@ id/discoverable_switch" />

            <TextView
                android:id="@ id/paired_devices"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="1.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@ id/textView2" />
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</layout>
 

Ошибки, которые появляются в androidruntime:

 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.drinkbf, PID: 12743
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=null} to activity {com.example.drinkbf/com.example.drinkbf.MainActivity}: kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5041)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5084)
        at android.app.ActivityThread.-wrap20(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053)
        at android.os.Handler.dispatchMessage(Handler.java:108)
        at android.os.Looper.loop(Looper.java:166)
        at android.app.ActivityThread.main(ActivityThread.java:7529)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
     Caused by: kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized
        at com.example.drinkbf.ConnectivityBluetooth.onActivityResult(ConnectivityBluetooth.kt:66)
        at androidx.fragment.app.FragmentActivity.onActivityResult(FragmentActivity.java:170)
        at android.app.Activity.dispatchActivityResult(Activity.java:7701)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:5037)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:5084) 
        at android.app.ActivityThread.-wrap20(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2053) 
        at android.os.Handler.dispatchMessage(Handler.java:108) 
        at android.os.Looper.loop(Looper.java:166) 
        at android.app.ActivityThread.main(ActivityThread.java:7529) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921

Ответ №1:

Создайте binding глобальную переменную, инициализируйте ее onCreateView , таким образом, вы можете использовать binding переменную во всем классе.

Это:

 private lateinit var binding:FragmentBluetoothBinding // global variable

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View {
        // Initialize it here
         binding = 
        DataBindingUtil.inflate<FragmentBluetoothBinding>(
            inflater, R.layout.fragment_bluetooth, container, false
           )

        return binding.root
     } 

      override fun onActivityResult() {
         binding // It's valid here
    } 
 

Комментарии:

1. Это работает! Я инициализировал «привязку к значению» вместо только «привязки»! Большое спасибо!