Использовать данные из базы данных о действиях в Android - PullRequest
0 голосов
/ 09 апреля 2020

В моем приложении Android я читаю данные из базы данных Firebase Realtime .

Редактировать: Я изменил это с помощью обратных вызовов, потому что это работает асинхронно .

Я пытаюсь использовать класс ViewModel для хранения данных из базы данных Firebase и для обновления моего пользовательского интерфейса Google Maps новыми маркерами.

Проблема заключается в том, что мне нужно подписаться на мой Объект LiveData в onCreate () , но мне нужно обновить интерфейс карты с помощью маркеров в onMapReady () .

Нужно ли использовать обратные вызовы здесь или, возможно, ViewModel здесь избыточен? Любые предложения могут быть полезны. Я пытаюсь решить это в течение нескольких дней без успеха, кроме того, я искал много вопросов и ответов в Интернете, и ничто не кажется полезным.

функция readData из DatabaseManager:

fun readFromDatabase(type: String,  callBack: OwnerListCallBack) {
    when (type) {
        OWNERS -> {
            ownerRef.addValueEventListener(object : ValueEventListener {
                override fun onDataChange(dataSnapshot: DataSnapshot) {
                    // This method is called once with the initial value and again
                    // whenever data at this location is updated.
                    for (snapshot: DataSnapshot in dataSnapshot.children) {
                        val owner = snapshot.getValue(Owner::class.java)

                        Log.d(TAG, "readFromDatabase: onDataChange: owner's name is ${owner?.name}")
                        if (owner != null)
                            owners.add(owner)
                        Log.d(TAG, "readFromDatabase: onDataChange: owner's name is ${owners[0].name}")
                    }
                }

                override fun onCancelled(error: DatabaseError) {
                    // Failed to read value
                    Log.w(TAG, "Failed to read value.", error.toException())
                }
            })
        }

}

setRestaurantsOnMap функция, которая вызывается в onMapReady:

private fun setRestaurantsOnMap() {
    Log.d(TAG, "setRestaurantsOnMap: called")
    // Set markers on the map. The owner's restaurants.
    database.readFromDatabase(OWNERS)
//        Log.d(TAG, "setRestaurantsOnMap: ${owners[0]}")
    if (database.owners.isNotEmpty()) {
        for (owner in database.owners) {
            try {
                val ownerAddress = owner.getRestaurant().getAddress()
                Log.d(TAG, "setRestaurantsOnMap: owner's address is: ${ownerAddress.getAddress()}")
                Toast.makeText(this, "setRestaurantsOnMap: owner's address is: ${ownerAddress.getAddress()}", Toast.LENGTH_LONG).show()
                val latlng = getLocationFromAddress(this, ownerAddress.getAddress())
                Log.d(TAG, "setRestaurantsOnMap: latitude is - ${latlng?.latitude}, longitude is - ${latlng?.longitude} ")
                Toast.makeText(this, "setRestaurantsOnMap: latitude is - ${latlng?.latitude}, longitude is - ${latlng?.longitude} ", Toast.LENGTH_LONG).show()
                if (latlng != null) {
                    mMap.addMarker(MarkerOptions()
                        .position(latlng)
                        .title(owner.getRestaurant().getName())
                        .snippet(owner.getRestaurant().getAddress().getAddress())
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
                    )
                    mMap.moveCamera(CameraUpdateFactory.newLatLng(latlng))
                } else {
                    Toast.makeText(this, "setRestaurantsOnMap: latlng is null", Toast.LENGTH_SHORT).show()
                }
            } catch (e: NullPointerException) {
                e.printStackTrace()
            } catch (e: IndexOutOfBoundsException) {
                e.printStackTrace()
            }
        }
    }
}

Мой класс ViewModel:

class MapsViewModel : ViewModel() {
private val db = DatabaseManager()

private val owners = MutableLiveData<List<Owner>>()
val ownerList: LiveData<List<Owner>>
get() = owners


init {
    owners.postValue(loadOwners())
    Log.d(TAG, "init: Owners are ${owners.value}")
}


override fun onCleared() {
    Log.d(TAG, "onCleared: canceling pending downloads")
}


private fun loadOwners(): List<Owner> {
    var ownerList = ArrayList<Owner>()

    Log.d(TAG, "loadAddress: called")
    // Set markers on the map. The owner's restaurants.
    db.readFromDatabase(OWNERS, object : OwnerListCallBack {
        @SuppressLint("RestrictedApi")
        override fun onCallBack(owners: ArrayList<Owner>) {
            if (owners.isNotEmpty()) {
                ownerList = owners
                Log.d(TAG, "Owners are ${ownerList[0]}, ${ownerList[1]}, ${ownerList[2]}")
            } else {
                throw DatabaseException("Loaded was not success. Number of owners is ${owners.count()}")
            }
        }
    })
    return ownerList
}
...