【问题标题】:Android Kotlin: check if view is not null before displaying SnackbarAndroid Kotlin:在显示 Snackbar 之前检查视图是否不为空
【发布时间】:2020-08-10 19:20:03
【问题描述】:

我使用以下代码在使用retrofit 加载数据时显示一个快餐栏。

有时,当用户尝试从该片段导航到另一个片段而获取数据的请求尚未终止时,我会收到 NullPointerException

kotlin.KotlinNullPointerException 在 com.test.data.ui.cars.SiteCarsFragment$getCars$1.onFailure(SiteCarsFragment.kt:279) 在 retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$2.run(DefaultCallAdapterFactory.java:92) 在 android.os.Handler.handleCallback(Handler.java:883) 在 android.os.Handler.dispatchMessage(Handler.java:100) 在 android.os.Looper.loop(Looper.java:224) 在 android.app.ActivityThread.main(ActivityThread.java:7520) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)

这是因为view 在这种情况下为空。

如何修改代码以确保在显示快餐栏之前定义视图?

// Call getCars() API
val call = App.myService.getCars(site.id!!)
call.enqueue(object : Callback<CarsResponse> {

    override fun onResponse(call: Call<CarsResponse>, response: Response<CarsResponse>) {

        Log.i(tagLabel, "getCars() - onResponse() Result = ${response.body()}")

        if (response.code() == 200) {

            if (response.body()?.data?.size == 0){
                // do stuff
            } else {
                val sb = Snackbar.make(view!!, getString(R.string.mytitle), Snackbar.LENGTH_SHORT)
                sb.view.setBackgroundColor(ContextCompat.getColor(context!!, R.color.snackbarGreen))
                sb.show()
            }

        }
    }

    override fun onFailure(call: Call<CarsResponse>, t: Throwable) {
        // do stuff
    }

})

【问题讨论】:

  • 你能显示你从哪里调用这个代码吗?
  • @Rahul 是的,刚刚编辑了我的帖子
  • @wawanopoulos 你能发布错误堆栈跟踪吗
  • 尝试放入一个 try-catch 块并创建一个该 throwable 的 Toast。把截图贴在帖子里,让我们看看是什么错误。
  • @wawanopoulos 您从哪里获取此视图并添加此视图?.let{ ...您的代码在这里...}?:Log.e(TAG,“view is null”)保存由于视图而导致的崩溃。

标签: android kotlin


【解决方案1】:

我会试试这个。我刚刚添加了一个空检查

if(view != null){

  // Your code
  val sb = Snackbar.make(view!!, getString(R.string.mytitle), Snackbar.LENGTH_SHORT)
  sb.view.setBackgroundColor(ContextCompat.getColor(context!!, R.color.snackbarGreen))
  sb.show()
}

【讨论】:

    【解决方案2】:

    您应该使用引用到您的活动的视图(因为如果您的片段之一被销毁,则活动视图不会被破坏)。如果您有任何活动视图的实例,请将其传递给那里。

    或者你可以试试这个:

    val sb = Snackbar.make(activity!!.findViewById(android.R.id.content), getString(R.string.mytitle), Snackbar.LENGTH_SHORT)
    

    这里我使用了!!,但除非被销毁,否则活动不会为空。

    编辑:在这里,如果您使用带有空检查的片段视图,如果您的片段视图被片段之间的切换破坏,您的小吃栏将不会显示。因此,如果您希望在 Fragment 的视图被破坏后仍显示它,则应该使用 Activity 的视图或上面的代码。

    【讨论】:

      【解决方案3】:

      我建议您摆脱双键(!!)运算符并在您的位置使用 null-safety(?) 运算符正在使用 view!!context!!。

      你应该这样做:

      if(view !=null){
      //TODO Snakbar code here.
      }
      

      希望这会有所帮助。

      【讨论】:

      • 这应该是一条评论
      • 当你用'view'声明snackbar(这里是'sb')时?当它为空时,以下两行可能会出错。
      猜你喜欢
      • 2016-09-12
      • 2018-04-28
      • 2014-01-01
      • 2011-06-12
      • 1970-01-01
      • 2017-04-10
      • 1970-01-01
      • 2021-02-25
      • 1970-01-01
      相关资源
      最近更新 更多