Android-视图实例在屏幕旋转时为空 [英] Android - View instance gets null on screen rotation
问题描述
我正在使用Kotlin Android扩展程序通过其ID直接访问视图. 我有一个进度条,可以使用id直接访问片段,即progress_bar
I am using Kotlin Android Extension to access view directly by their id. I have a progress bar which I access directly in fragment using id i.e progress_bar
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="15dp"
android:indeterminate="true"/>
在片段中,我正在使用此代码显示和隐藏它
In fragment, I am showing and hiding it with this code
progress_bar.visibility = if (visible) View.VISIBLE else View.GONE
在我旋转屏幕之前,它一直运行良好.之后,它会引发异常
It is working perfectly until I rotate the screen. After that, it throws the exception
java.lang.IllegalStateException:progress_bar不能为null.
java.lang.IllegalStateException: progress_bar must not be null.
该变量在屏幕旋转时为空.如何解决这个问题?
The variable gets null on screen rotation. How to solve this problem?
片段代码
class SingleAppFragment : Fragment() {
private lateinit var appName: String
companion object {
fun newInstance(appName: String = ""): SingleAppFragment {
val fragment = SingleAppFragment()
val args = Bundle()
args.putString(Constants.EXTRA_APP_NAME, appName)
fragment.arguments = args
return fragment
}
}
private var mListener: OnFragmentInteractionListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
appName = if (arguments != null && !arguments.getString(Constants.EXTRA_APP_NAME).isEmpty()) {
arguments.getString(Constants.EXTRA_APP_NAME)
} else {
Constants.APP_NAME_FACEBOOK
}
}
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater!!.inflate(R.layout.fragment_single_app, container, false)
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initView()
setEventListeners()
}
private fun initView() {
var canShowSnackBar = true
web_single_app.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
showHideProgressBar(true)
canShowSnackBar = true
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
showHideProgressBar(false)
}
override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
web_single_app.stopLoading()
if (canShowSnackBar) {
mListener?.onErrorWebView()
canShowSnackBar = false
}
}
}
web_single_app.settings.javaScriptEnabled = true
web_single_app.loadUrl(Constants.APP_NAME_URL_MAP[appName])
}
private fun setEventListeners() {
back_web_control.setOnClickListener({
web_single_app.goBack()
})
}
fun showHideProgressBar(visible: Boolean) {
progress_bar_web_control.visibility = if (visible) View.VISIBLE else View.GONE
}
fun loadUrl(appName: String) {
web_single_app.loadUrl(Constants.APP_NAME_URL_MAP[appName])
}
override fun onAttach(context: Context?) {
super.onAttach(context)
if (context is OnFragmentInteractionListener) {
mListener = context
}
}
override fun onDetach() {
super.onDetach()
mListener = null
}
interface OnFragmentInteractionListener {
fun onErrorWebView()
}
}
复制步骤:
- 开始活动
- 片段加载
- 加载片段时,我加载一个URL并显示进度条
- 加载URL时,我旋转手机,进度栏变量为null
推荐答案
就我而言,此错误有时会发生.当然,onViewCreated()
是放置代码的好方法.但是有时它不足以使它奇怪.而setRetainInstance(true)
可能有帮助,可能没有帮助.因此有时这会有所帮助:使用view
变量访问View
.您甚至可以在onCreateView()
中访问它们.您可以使用?.
来确保应用程序不会崩溃(当然,在这种情况下某些视图不会更新).如果希望获取context
,请使用view.context
.
In my case this bug happens from time to time. Of course, onViewCreated()
is a good method to place your code in. But sometimes it's strangely not enough. And setRetainInstance(true)
may help, may not. So sometimes this helps: access your View
s with a view
variable. You can even access them inside onCreateView()
. You can use ?.
for a guarantee that an application won't crash (of course, some views won't update in this case). If you wish to get context
, use view.context
.
就我而言,此错误仅在Kotlin协程中复制.
In my case this bug reproduced only in Kotlin coroutines.
private fun showProgress(view: View) {
view.progressBar?.visibility = View.VISIBLE
}
private fun hideProgress(view: View) {
view.progressBar?.visibility = View.GONE
}
然后输入代码:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
showData(view)
}
private fun showData(view: View) {
showProgress(view)
adapter = SomeAdapter()
adapter.setItems(items)
val divider = SomeItemDecoration(view.context)
view.recycler_view?.run {
addItemDecoration(divider)
adapter = this@SomeFragment.adapter
layoutManager = LinearLayoutManager(view.context)
setHasFixedSize(true)
}
hideProgress(view)
}
这篇关于Android-视图实例在屏幕旋转时为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!