ListView обновляется только в методе onCreate () при использовании Firebase - PullRequest
0 голосов
/ 14 апреля 2019

Я пишу список задач и хочу, чтобы ListView отображал изменения, когда пользователь добавляет новые такты в список или удаляет их.Я не уверен почему, но adaptor.notifyDataSetChanged () работает только тогда, когда приложение использует метод onCreate () (включение, изменение на горизонтальное).

Я пытался поставить адаптер.notifyDataSetChanged () везде, и он не обновляет содержимое.Только после добавления задачи в базу данных (она отображается на консоли Firebase) и перехода в горизонтальный режим / перезапуска вы можете увидеть новые данные в ListView.Я также создал кнопку, которая использует только adapter.notifyDataSetChanged () в методе onClick ().

MainActivity.kt:

package com.example.toodoo

import android.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.design.widget.FloatingActionButton
import android.util.Log
import android.view.View
import android.widget.EditText
import android.widget.ListView
import android.widget.Toast
import com.google.firebase.database.*

class MainActivity : AppCompatActivity(), ItemRowListener {

//Get Access to Firebase database, no need of any URL, Firebase
//identifies the connection via the package name of the app
lateinit var mDatabase: DatabaseReference
var toDoItemList: MutableList<ToDoItem>? = null
lateinit var adapter: ToDoItemAdapter
private var listViewItems: ListView? = null

override fun modifyItemState(itemObjectId: String, isDone: Boolean) {
    val itemReference = mDatabase.child(Constants.FIREBASE_ITEM).child(itemObjectId)
    itemReference.child("done").setValue(isDone);
}
//delete an item
override fun onItemDelete(itemObjectId: String) {
    //get child reference in database via the ObjectID
    val itemReference = mDatabase.child(Constants.FIREBASE_ITEM).child(itemObjectId)
    //deletion can be done via removeValue() method
    itemReference.removeValue()
}

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

    //reference for FAB
    val fab = findViewById<View>(R.id.fab) as FloatingActionButton
    listViewItems = findViewById<View>(R.id.items_list) as ListView
    //Adding click listener for FAB
    fab.setOnClickListener { view ->

        //Show Dialog here to add new Item
        addNewItemDialog()
    }

    mDatabase = FirebaseDatabase.getInstance().reference
    toDoItemList = mutableListOf<ToDoItem>()
    adapter = ToDoItemAdapter(this, toDoItemList!!)
    listViewItems!!.setAdapter(adapter)
    mDatabase.orderByKey().addListenerForSingleValueEvent(itemListener)
}

private fun addNewItemDialog() {
    val alert = AlertDialog.Builder(this)
    val itemEditText = EditText(this)
    alert.setMessage("Add New Item")
    alert.setTitle("Enter To Do Item Text")
    alert.setView(itemEditText)
    alert.setPositiveButton("Submit") { dialog, positiveButton ->
        val todoItem = ToDoItem.create()
        todoItem.itemText = itemEditText.text.toString()
        todoItem.done = false
        //We first make a push so that a new item is made with a unique ID
        val newItem = mDatabase.child(Constants.FIREBASE_ITEM).push()
        todoItem.objectId = newItem.key
        //then, we used the reference to set the value on that ID
        newItem.setValue(todoItem)
        dialog.dismiss()
        Toast.makeText(this, "Item saved with ID " + todoItem.objectId, Toast.LENGTH_SHORT).show()
    }
    alert.show()

}

var itemListener: ValueEventListener = object : ValueEventListener {
    override fun onDataChange(dataSnapshot: DataSnapshot) {
        // Get Post object and use the values to update the UI
        addDataToList(dataSnapshot)
    }
    override fun onCancelled(databaseError: DatabaseError) {
        // Getting Item failed, log a message
        Log.w("MainActivity", "loadItem:onCancelled", databaseError.toException())
    }
}
private fun addDataToList(dataSnapshot: DataSnapshot) {
    val items = dataSnapshot.children.iterator()
    //Check if current database contains any collection
    if (items.hasNext()) {
        val toDoListindex = items.next()
        val itemsIterator = toDoListindex.children.iterator()

        //check if the collection has any to do items or not
        while (itemsIterator.hasNext()) {
            //get current item
            val currentItem = itemsIterator.next()
            val todoItem = ToDoItem.create()
            //get current data in a map
            val map = currentItem.getValue() as HashMap<String, Any>
            //key will return Firebase ID
            todoItem.objectId = currentItem.key
            todoItem.done = map.get("done") as Boolean?
            todoItem.itemText = map.get("itemText") as String?
            toDoItemList!!.add(todoItem);
        }
    }
    //alert adapter that has changed
    adapter.notifyDataSetChanged()
}

fun onClick(view: View){
    adapter.notifyDataSetChanged()
}
}

Я думаю, что это также может быть проблемой, связанной с синхронизацией Firebaseданные с ListView, но я использую его впервые и не могу решить эту проблему.Я впервые с этой базой данных, так что, может быть, я что-то упустил.

1 Ответ

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

Вы добавляете прослушиватель для данных с помощью:

mDatabase.orderByKey().addListenerForSingleValueEvent(itemListener)

Поскольку вы используете addListenerForSingleValueEvent, он только прослушивает текущие данные, а затем удаляет прослушиватель. Поэтому после загрузки текущих данных вы больше не слушаете изменения.

Чтобы продолжить прослушивание исходных данных и изменений впоследствии, используйте:

mDatabase.orderByKey().addValueEventListener(itemListener)

Обратите внимание, что вы можете очистить toDoItemList в addDataToList, так как в противном случае вы будете добавлять все существующие элементы снова и снова при каждом изменении.

Или, альтернативно, используйте addChildEventListener, который дает вам более детальную информацию о том, что изменилось в дочерних узлах, так что вы выполняете детальные обновления для адаптера.

...