在SyncAdapter更改Kotlin中的数据后更新RecyclerView UI

问题描述 投票:0回答:1

我需要在SyncAdapter完成任务后刷新我的RecyclerView,当我点击我的RecyclerView中的一些项目时,我将数据发送到Web服务器,我的服务器返回一些数据并将其保存在本地数据库(Anko db)中,这很好,但是当数据保存在本地数据库中时,我需要更新UI项目。做这个的最好方式是什么?

那是我的RecyclerViewAdapter:

class TableRecyclerViewAdapter(private val tableList: List<TablesParser>) : RecyclerView.Adapter<TableHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TableHolder {
        val layoutView = LayoutInflater.from(parent.context).inflate(R.layout.table_item, parent, false)
        return TableHolder(layoutView)
    }

    override fun onBindViewHolder(holder: TableHolder, position: Int) {
        if (position < tableList.size) {
            val table = tableList[position]
            val node = holder.table
            val context = node.context
            holder.guestNumber.text = table.people.toString()
            holder.tableName.text = table.description
            if (node is MaterialCardView) {
                when (table.status) {
                    "A" -> {
                        holder.descriptionTable.text = "ABIERTA"
                        node.setCardBackgroundColor(ContextCompat.getColor(context!!, R.color.openTable))
                    }
                    "D" -> {
                        holder.descriptionTable.text = "DISPONIBLE"
                        node.setCardBackgroundColor(ContextCompat.getColor(context!!, R.color.orangePrimary))
                    }
                    "C" -> {
                        holder.descriptionTable.text = "CERRADA"
                        node.setCardBackgroundColor(ContextCompat.getColor(context!!, R.color.closedTable))
                    }
                    else -> {
                        holder.descriptionTable.text = node.context.getString(R.string.error_label)
                        node.setCardBackgroundColor(ContextCompat.getColor(context!!, R.color.errorTable))
                    }
                }
                node.setOnClickListener {
                    when (table.status) { //  Verificar los estados de las mesas
                        "C" -> context.toast("Mesa cerrada")
                        "D" -> {
                            openTable(context, it, table.people,"", table)
                        }
                        "A" -> {
                            command(context, it, table.people, table.description)
                        }
                    }
                }

            }
        }
    }

    override fun getItemCount(): Int = tableList.size

    /**
     * Open a table to send the updated data to a server
     */
    private fun openTable (context:Context, table:View, people: Int, title:String, tableData: TablesParser) {
        val view = context.layoutInflater.inflate(R.layout.open_table_modal, null, false) // Layout para abrir el modal

        val dialog = AlertDialog.Builder(context, R.style.com_madison_AlertDialog).create()
        if (title == "") {
            dialog.setTitle("Mesa ${tableData.description}")
        }
        dialog.setIcon(R.drawable.ic_guests)
        dialog.setCancelable(false)
        val guestTextEditor = view.txtGuestsNumber
        guestTextEditor.setText(people.toString())
        guestTextEditor.requestFocus()
        Keyboard.showKeyBoardInDialog(view)
        dialog.setButton(AlertDialog.BUTTON_POSITIVE, "OK") { _: DialogInterface, _: Int ->
            // Put the params for send to a server and update the System DB in a Bundle Object
            val bundle = Bundle()
            bundle.putInt("IDTABLE", tableData.tableId)
            if (guestTextEditor.text == null) {
                bundle.putInt("PEOPLE", tableData.people)
            } else {
                bundle.putInt("PEOPLE", guestTextEditor.text.toString().trim().toInt())
            }
            bundle.putString("TABLE", tableData.description)
            val seller = PreferenceManager.getDefaultSharedPreferences(context).getInt("idSeller", 0)
            // Verify if a idSeller exist in SharedPreference
            if (seller > 0) { // If seller is set continue to open a table
                bundle.putInt("SELLER", seller)
                bundle.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true)
                /*
                * SyncAdapter call 
                * the requestSync function triggers the SyncAdapter class and onPerformSync is the attendant of sync the data
                */
                ContentResolver.requestSync(SyncAdapter.getSyncAccounts(view.context), AUTHORITY, bundle)
            } else {
                context.toast("No se encontró vendedor para la mesa")
                dialog.dismiss()
            }
        }
        dialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Cancelar") { _: DialogInterface, _: Int ->
            context.toast("CANCEL")
            dialog.dismiss()
        }
        dialog.setView(view)

        dialog.show()
    }


    private fun command (context:Context, table:View, people: Int, description: String) {
        context.toast("Entro en command")
    }
}

这是我的SyncAdapter:

class SyncAdapter @JvmOverloads constructor(ctx: Context, autoInitialize: Boolean,
                                            allowParallelSyncs: Boolean = false,
                                            val mContentResolver:ContentResolver = ctx.contentResolver) : AbstractThreadedSyncAdapter (ctx, autoInitialize, allowParallelSyncs) {
    // Var for retrieve the server api data
    private val serverNegotiation = ServerDataNegotiation()

    override fun onPerformSync(account: Account?, extras: Bundle?, authority: String?, provider: ContentProviderClient?, syncResult: SyncResult?) {
        Log.e("SYNC", "ENTRO EN EL PERFORM SYNC")
        if (extras != null) {
            // Sync the local data changes to a Server
            if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD,true)) {
                syncResult?.run {
                    syncLocalDataToServer(context, this, extras)
                } ?: this.context.longToast("No se pudo sincronizar la información con el servidor, no se pudo obtener el resultado de la sincronización")
            } else {
                // Sync the data locally
                syncResult?.run {
                    syncServerDataToLocalDB(context, this)
                }
            }
        }
    }

    private fun syncLocalDataToServer (ctx:Context, syncResult: SyncResult, extras: Bundle) {
        serverNegotiation.openTableInServer(extras.getInt("IDTABLE", 0), extras.getInt("PEOPLE", 2), extras.getInt("SELLER", 0), {tableData ->
            // Update the local AnkoDB
            DBQueryHelper.getInstance().updateTableInfo(ctx, tableData, extras)
            syncResult.stats.numUpdates ++
        }, {error ->
            ctx.longToast(error)
        })
    }

    private fun syncServerDataToLocalDB (ctx:Context, syncResult: SyncResult?) {
        Log.e("SYNC", "OBTENIENDO LOS DATOS DEL SERVIDOR PARA ACTUALIZAR LA UI Y LA BASE DE DATOS LOCAL")
    }

    companion object {
        /**fun initSync (ctx:Context, upload: Boolean, args: MutableList<Any>) {
            Log.e("SYNC", "ENTRO EN EL iniSync")
            val bundle = Bundle()
            bundle.putInt("PEOPLE", args[0].toString().toInt())
            bundle.putString("TABLE", args[1].toString())

            if (upload)
                bundle.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true)
            // Call to my SyncAdapter (supposed :( )
            Log.e("SYNC", "ENTRO ANTES DEL REQUESTSYNC")
            ContentResolver.requestSync(getSyncAccounts(ctx), AUTHORITY, bundle)
            Log.e("SYNC", "DESPUES DEL REQUEST SYNC")
            // Init the sync service every 4 seconds
            ContentResolver.addPeriodicSync(getSyncAccounts(ctx), AUTHORITY, Bundle.EMPTY, 4)
        }**/

        fun getSyncAccounts(ctx: Context): Account? {
            val accountManager = ctx.getSystemService(Context.ACCOUNT_SERVICE) as AccountManager
            val newAccount = Account(ACCOUNT, ACCOUNT_TYPE)
            if (!accountManager.addAccountExplicitly(newAccount, null, null)) {
                return null
            }
            return newAccount
        }
    }
}

这是我更新本地数据库中服务器更改的功能,在此功能中我需要更新我的UI:

  fun updateTableInfo (context: Context, tableInfo: ResponseOpenTable, extras: Bundle) {
        context.database.use {
            update("tableplan", "sellRelated" to tableInfo.sell, "originalSell" to tableInfo.sell,
                "status" to "A", "people" to extras.getInt("PEOPLE", 0))
                .whereArgs("idmesa = {tableId}", "tableId" to extras.getInt("IDTABLE", 0)).exec()
        }
        val layout = context.layoutInflater.inflate(R.layout.tables_plan_layout, null, false)
        //*********** THAT'S NOT WORKS
        layout.recyclerview_tableplan.children.forEach { node ->
            if (node is MaterialCardView) {
                node.lblTableDescription.text = "ABIERTA"
                node.setCardBackgroundColor(ContextCompat.getColor(context, R.color.openTable))
            }
        }
    }
android kotlin android-syncadapter
1个回答
0
投票

要更新RecyclerView值,可以使用以下命令刷新适配器:

adapter.notifyDataSetChanged
© www.soinside.com 2019 - 2024. All rights reserved.