首页 > 解决方案 > ProgressBar 从代码中不会在 Android Studio 中可见

问题描述

所以我做了一个应用程序,我试图在单击按钮时显示进度条。

只有当我将View.VISIBLE放在处理程序之外时它才会显示。

科特林代码:

button.setOnClickListener {

progressBar.visibility = View.VISIBLE
    runBlocking {

        try {
            //HTTP request removed because of confidentiality, assume I'm setting delay

        } catch (e: Exception) {
            Log.e(tag, "Error: " + e.message)
            Toast.makeText(this@MainActivity, "Could not find page", Toast.LENGTH_LONG)
                .show()
        }

    }
    progressBar.visibility = View.GONE
}

按钮 XML:

<ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:alpha="1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:visibility= "invisible"/>

我已经搜索了几个小时,但找不到与我的案例相关的内容。

所需输出: 在单击按钮时获取进度条。

标签: androidkotlincoroutine

解决方案


执行类似的命令progressBar.visibility = View.VISIBLE可能需要几纳秒(大约 144100)。

主线程可能会要求其他一些线程执行某些任务,而不是等待这些线程的响应,它会恢复其正常执行(下一行代码)。您的下一行代码(runBlocking:运行一个新的协程并以可中断的方式阻塞当前线程,直到其完成。)阻塞当前线程,直到从 runBlocking 方法启动的协程完成。这仅仅意味着主线程在协程完成之前无法执行其他命令或处理从其他线程接收到的响应。

一旦协程完成。主线程恢复执行,同时显示和隐藏进度条,这就是您看不到进度条旋转的原因。

主线程应该只用于 UI 操作。您应该通过切换到 IO 上下文在协程中执行网络操作,而不是阻塞主线程。

在此处查看调度程序的类型。 https://medium.com/androiddevelopers/coroutines-on-android-part-i-getting-the-background-3e0e54d20bb

bt.setOnClickListener {
    progressBar.visibility = View.VISIBLE
    GlobalScope.launch {
        networkCall()
    }

}

private suspend fun networkCall() {
    withContext(Dispatchers.Default) {
        for (i in 1..50000) {
            Log.v("Network call", "$i")
        }
        runOnUiThread {
            progressBar.visibility = View.INVISIBLE
        }
    }
}

推荐阅读