因此,我有一个ViewModel
用于检索搜索API的查询。为此,我也有SearchView
,但是在SearchView
上输入第一个字母时,应用崩溃了,因为KotlinNullPointer
在翻新中的这一行上
resultsItem?.value = resultsItemList as List<ResultsItem>?
我认为我做对了所有事情,我尝试过
以下是片段的代码
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())
}
})
}
}
我在做什么错?
答案 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值。