通过 ViewModel 从 SQL Connector 更新 Jetpack Compose UI

updating Jetpack Compose UI from SQL Connector through ViewModel

我有一个价格查询应用程序。使用其条形码请求产品的详细信息。 很简单。。我只在第一页。

我创建了 UI 和 SQL 查询,我可以从服务器获取数据,但是,我无法更新 UI。有些事情我肯定做错了。但我还在学习 Kotlin,所以请耐心等待。

请求和显示数据的函数是这个

@Composable
fun PriceChecker(viewModel: MainViewModel,context: Context) {
    var barcode by remember {
        mutableStateOf("")
    }
    val focusManager = LocalFocusManager.current
    Box(modifier = Modifier.size(250.dp)) {
        Column(
            modifier = Modifier
                .size(500.dp)
                .border(width = 2.dp, color = Color.White, shape = RoundedCornerShape(12.dp))
        ) {
            TextField(
                onValueChange = {
                    barcode = it
                },
                value = barcode,
                singleLine = true,
                keyboardActions = KeyboardActions(onDone = ({
                    //hidekeyboard
                    focusManager.clearFocus()
                  
  //get product details
                    viewModel.getDetails(barcode) <-- this
                  
                    //erasing text after sending barcode
                    barcode = ""
                })),
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
            )
            Text(text = viewModel.name) <-- needed value from SQLthrough ViewModel
            Text(text = viewModel.price)<-- needed value from SQL through ViewModel
        }
    }
}

在视图模型中我有这个简单的


class MainViewModel:ViewModel() {

    var price= RepositorySQL().price


    var name = RepositorySQL().name


    fun getDetails(barcode:String){
        RepositorySQL().getProductDetails(barcode)
    }
}

我尝试使用 mutablestateof() 作为值,但它也没有更新 UI

在 Sql 连接器中我是这样的:

 var price by mutableStateOf("Product Name") //also var price = ""
    private set
    var name by mutableStateOf("Product Price") //also var name = ""
    private set

    val cls ="net.sourceforge.jtds.jdbc.Driver"
    var connection: Connection? = null


    fun getProductDetails(barcode: String){
        val policy = StrictMode.ThreadPolicy.Builder().permitAll().build()
        StrictMode.setThreadPolicy(policy)
        Class.forName(cls)
        connection = DriverManager.getConnection(newUrl, newUser, newPass)
        if (connection!=null){
            val statement = connection!!.createStatement()
            val result = statement.executeQuery("Select [ItemName],[Price] FROM [twisted].[dbo].[Inventory] WHERE [ItemNum] = '$barcode';")
            while (result.next()){
                name =  result.getString("ItemName")
                price = result.getDouble("Price").toString()
                Log.d(TAG, "Product name = ${name}") //values are printed correctly.
                Log.d(TAG, "Product Price = ${price}")//values are printed correctly.
                }
        }else{
            name = "Didn't get any data"
            Log.d(TAG, name)
        }
    }

即使我更新值,UI 也保持不变...我确定解决方案应该很简单,但我仍在学习...

出于某种原因,您要在每一行创建 RepositorySQL(),这将是所有不同的对象

在您的 RepositorySQL 中,您使用的是 mutableStateOf 委托。这使得 pricenameMainViewModel 纯字符串中,而不是状态,所以他们不会看 RepositorySQL

要使 MutableState private set 你必须声明私有 MutableState 和 public State,像这样:

class RepositorySQL {
    private val _price = mutableStateOf("Product Name")
    val price: State<String> = _price

    private val _name = mutableStateOf("Product Price")
    val name: State<String> = _name

    fun getProductDetails(t: String) {
        _price.value = "1"
        _name.value = "2"
    }
}

并且在 MainViewModel 中,您可以将您的值声明为 RepositorySQL 的委托:

class MainViewModel:ViewModel() {
    private val repositorySQL = RepositorySQL()

    val price by repositorySQL.price

    val name by repositorySQL.name

    fun getDetails(barcode:String){
        repositorySQL.getProductDetails(barcode)
    }
}