You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

跳转至Fragment时如何取消Main Activity中的进度条?

解决方案

核心问题分析

你当前的代码里,点击按钮后直接提交Fragment事务,但commit()是异步执行的——主线程不会等待Fragment完全创建/初始化完成就继续执行后续逻辑,导致进度条没有被自动隐藏,会持续旋转。另外日志D/eglCodecCommon: setVertexArrayObject是因为进度条显示时,GPU一直在渲染它的旋转动画;启用广告时会叠加渲染操作,让日志量更明显,本质还是进度条未隐藏的问题。

具体解决方法

要让进度条在Fragment准备好(或后台任务完成)后自动隐藏,需要实现Fragment与Activity的状态通信,以下是两种常用方案:


方案一:接口回调

  1. 定义回调接口,用于通知Activity Fragment已准备完成
interface OnFragmentReadyListener {
    fun onFragmentReady()
}
  1. 在Activity中实现接口,处理进度条隐藏逻辑
class MainActivity : AppCompatActivity(), OnFragmentReadyListener {
    private lateinit var binding: ActivityMainBinding
    private val MAIN_ACTIVITY_TAG = "MainActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.slowButton.setOnClickListener {
            binding.pBar.visibility = View.VISIBLE
            binding.mainActFields.visibility = View.GONE
            supportFragmentManager.beginTransaction()
                .replace(R.id.MainFragment, MainFragment())
                .commit()
            Log.i(MAIN_ACTIVITY_TAG, "Clicked")
        }
    }

    // 实现接口方法,隐藏进度条
    override fun onFragmentReady() {
        binding.pBar.visibility = View.GONE
        // 可选:恢复原界面控件显示
        // binding.mainActFields.visibility = View.VISIBLE
    }
}
  1. 在Fragment的合适时机调用回调
class MainFragment : Fragment() {
    private var listener: OnFragmentReadyListener? = null

    // 绑定Activity时获取回调实例
    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is OnFragmentReadyListener) {
            listener = context
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        // 如果Fragment包含网络请求等后台任务,需等待任务完成后再调用
        // 示例:网络请求成功后触发
        // yourApiCall.enqueue(object : Callback<YourData> {
        //     override fun onResponse(call: Call<YourData>, response: Response<YourData>) {
        //         listener?.onFragmentReady()
        //     }
        //     override fun onFailure(call: Call<YourData>, t: Throwable) {
        //         listener?.onFragmentReady() // 失败也需隐藏进度条
        //     }
        // })

        // 无后台任务时,Fragment加载完成即触发
        listener?.onFragmentReady()
    }

    // 解除绑定时清空回调,避免内存泄漏
    override fun onDetach() {
        super.onDetach()
        listener = null
    }
}

方案二:共享ViewModel(适合复杂场景)

通过ViewModel在Activity和Fragment之间共享加载状态,避免接口耦合:

  1. 创建共享ViewModel
class MainViewModel : ViewModel() {
    // 标记是否处于加载状态
    val isLoading = MutableLiveData<Boolean>()
}
  1. 在Activity中观察状态变化,自动更新UI
class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: MainViewModel
    private val MAIN_ACTIVITY_TAG = "MainActivity"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 初始化ViewModel
        viewModel = ViewModelProvider(this)[MainViewModel::class.java]

        // 观察加载状态,自动更新进度条和界面
        viewModel.isLoading.observe(this) { isLoading ->
            binding.pBar.visibility = if (isLoading) View.VISIBLE else View.GONE
            binding.mainActFields.visibility = if (isLoading) View.GONE else View.VISIBLE
        }

        binding.slowButton.setOnClickListener {
            viewModel.isLoading.value = true
            supportFragmentManager.beginTransaction()
                .replace(R.id.MainFragment, MainFragment())
                .commit()
            Log.i(MAIN_ACTIVITY_TAG, "Clicked")
        }
    }
}
  1. 在Fragment中更新加载状态
class MainFragment : Fragment() {
    private lateinit var viewModel: MainViewModel

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        // 获取与Activity共享的ViewModel实例
        viewModel = ViewModelProvider(requireActivity())[MainViewModel::class.java]

        // 后台任务完成后更新状态
        // 示例:网络请求完成
        // yourApiCall.enqueue(object : Callback<YourData> {
        //     override fun onResponse(call: Call<YourData>, response: Response<YourData>) {
        //         viewModel.isLoading.value = false
        //     }
        //     override fun onFailure(call: Call<YourData>, t: Throwable) {
        //         viewModel.isLoading.value = false
        //     }
        // })

        // 无后台任务时,Fragment加载完成即更新状态
        viewModel.isLoading.value = false
    }
}

关键注意点

  • 如果Fragment包含网络请求、数据库操作等后台任务,必须等任务完成后再触发进度条隐藏,而非Fragment一创建就隐藏,这样才符合你“让用户感知后台任务处理”的需求。
  • 进度条隐藏后,D/eglCodecCommon: setVertexArrayObject日志会自动消失,因为GPU不再渲染进度条的旋转动画。

内容的提问来源于stack exchange,提问作者kotlining

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 07:45:51