将数据传递给ViewModel时为Null

时间:2019-07-10 15:23:00

标签: android

因此,我有一个ViewModel用于检索搜索API的查询。为此,我也有SearchView,但是在SearchView上输入第一个字母时,应用崩溃了,因为KotlinNullPointer在翻新中的这一行上

resultsItem?.value = resultsItemList as List<ResultsItem>?

我认为我做对了所有事情,我尝试过

  1. 创建自己的方法以将数据传递给ViewModel
  2. 使用意图将数据传递给ViewModel
  3. 在ViewModel中定义有效的默认值,但定义后不能更改

以下是片段的代码

class Search : Fragment() {

var searchAdapter: SearchAdapter? = null
lateinit var recyclerView: RecyclerView
lateinit var model: picodiploma.dicoding.database.picodiploma.dicoding.database.search.adapter.SearchView


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setHasOptionsMenu(true)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                          savedInstanceState: Bundle?): View? {
    // Inflate the layout for this fragment
    val view = inflater.inflate(R.layout.fragment_search, container, false)


    recyclerView = view.findViewById(R.id.search_result_tv)


    val layoutManager = LinearLayoutManager(context)
    recyclerView.layoutManager = layoutManager

    model = ViewModelProviders.of(this).get(picodiploma.dicoding.database.picodiploma.dicoding.database.search.adapter.SearchView::class.java)

    return view
}

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
    inflater.inflate(R.menu.search, menu)
    val searchItem = menu.findItem(R.id.search_)
    val searchView = searchItem?.actionView as SearchView
    searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {

        override fun onQueryTextSubmit(s: String): Boolean {
            return false
        }

        override fun onQueryTextChange(s: String): Boolean {
            model.query = s
            getViewData()
            return true
        }
    })
}

fun getViewData() {

    model.getData().observe(this, Observer { resultsItem ->

        searchAdapter = SearchAdapter((resultsItem as ArrayList<ResultsItem>?)!!, this.context!!)
        recyclerView.adapter = searchAdapter
        recyclerView.visibility = View.VISIBLE
    })
}
}

和ViewModel

class SearchView : ViewModel() {
private val API_KEY = "2e08750083b7e21e96e915011d3f8e2d"
private val TAG = SearchView::class.java.simpleName
lateinit var query: String

companion object {
    var resultsItem: MutableLiveData<List<ResultsItem>>? = null
}

fun getData(): LiveData<List<ResultsItem>> {
    if (resultsItem == null) {
        resultsItem = MutableLiveData()
        loadData()
    }
    return resultsItem as MutableLiveData<List<ResultsItem>>
}


private fun loadData() {

    val apiInterface = ApiClient.getList().create(ApiInterface::class.java)

    val responseCall = apiInterface.getTvSearch(API_KEY, query)

    responseCall.enqueue(object : Callback<Response> {

        override fun onResponse(call: Call<Response>, response: retrofit2.Response<Response>) {
            val resultsItemList = response.body()!!.results
            resultsItem?.value = resultsItemList as List<ResultsItem>?
        }

        override fun onFailure(call: Call<Response>, t: Throwable) {
            Log.d(TAG, t.toString())
        }

    })
}
}

我在做什么错?

2 个答案:

答案 0 :(得分:0)

在行下方更改

var resultsItem: MutableLiveData<List<ResultsItem>>? = null

var resultsItem: MutableLiveData<List<ResultsItem>>? = MutableLiveData()

将所有内容放入

    run{
searchAdapter = SearchAdapter((resultsItem as ArrayList<ResultsItem>?)!!, this.context!!)
        recyclerView.adapter = searchAdapter
        recyclerView.visibility = View.VISIBLE
}

答案 1 :(得分:0)

好像您将resultsItem定义为可为空的MutableLiveData,但LiveData中的List<ResultsItem>不可为空。 因此,我想您从服务器得到响应时,您的resultsItemList为空。而且您之所以得到KotlinNullPointer,是因为您试图将null分配给resultsItem LiveData的notNull值。