Fragment中调用ProgressBar.setVisibility出现空指针异常如何解决
问题原因
- Fragment生命周期执行顺序为
onCreate→onCreateView→onViewCreated,你在onCreate阶段就调用fetchdata触发控件操作,此时布局还未加载完成,generalBar未被实例化,调用其setVisibility方法就会触发空指针异常。 - 代码中没有提前声明并初始化
generalBar变量,直接通过ID访问控件必须要等视图挂载完成后才能生效。
解决方案
调整请求触发时机,在视图初始化完成的onViewCreated方法中发起网络请求,同时手动初始化ProgressBar控件,修改后的完整代码如下:
class GeneralFragment : Fragment() { private lateinit var mAdapter: NewsListAdapter // 提前声明ProgressBar变量 private lateinit var generalBar: ProgressBar override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 移除此处的fetchdata调用 } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.fragment_general, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val recyclerView = view.findViewById<RecyclerView>(R.id.recyclerView) // 初始化ProgressBar generalBar = view.findViewById(R.id.generalBar) mAdapter = NewsListAdapter(this) recyclerView.adapter = mAdapter // 视图加载完成后再发起网络请求 fetchdata("https://news-api-don.herokuapp.com/api/v1?apiKey=20d14506791144cc8b424549c42068c0") } private fun fetchdata(url: String) { generalBar.visibility = View.VISIBLE val jsonObjectRequest = JsonObjectRequest( Request.Method.GET, url, null, { val newsJsonArray = it.getJSONArray("articles") val newsArray = ArrayList<News>() for (i in 0 until newsJsonArray.length()) { val newsJsonObject = newsJsonArray.getJSONObject(i) val news = News( newsJsonObject.getString("title"), newsJsonObject.getString("author"), newsJsonObject.getString("url"), newsJsonObject.getString("urlToImage") ) newsArray.add(news) } mAdapter.updateNews(newsArray) generalBar.visibility = View.GONE }, { Toast.makeText(activity, "Something went wrong", Toast.LENGTH_LONG).show() generalBar.visibility = View.GONE } ) // 此处替换this为requireContext(),避免Fragment上下文获取异常 MySingleton.getInstance(requireContext()).addToRequestQueue(jsonObjectRequest) } fun onItemClicked(item: News) { val builder = CustomTabsIntent.Builder() val customTabsIntent = builder.build() activity?.let { customTabsIntent.launchUrl(it, Uri.parse(item.url)) } } }
额外优化建议
- 网络请求回调执行时要先判断Fragment是否已挂载,避免视图销毁后更新控件触发异常,可以在回调开头添加
if (!isAdded) return判断。 - ProgressBar可以默认设置为
android:visibility="gone",避免初始化阶段的视觉闪烁。
内容的提问来源于stack exchange,提问作者Mayur Panchal
相关产品推荐
相关产品推荐

