android - 在我的片段中设置适配器以使其工作
问题描述
我尝试了不同的方法将适配器实现到片段中,但它似乎不起作用
适配器
class AsteroidViewAdapter(private val onClickListener: OnClickListener) :
ListAdapter<Asteroid, AsteroidViewAdapter.AsteroidViewHolder>(DiffCallback) {
companion object DiffCallback : DiffUtil.ItemCallback<Asteroid>() {
override fun areItemsTheSame(oldItem: Asteroid, newItem: Asteroid): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Asteroid, newItem: Asteroid): Boolean {
return oldItem == newItem
}
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): AsteroidViewHolder {
return AsteroidViewHolder(
AsteroidListContainerBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: AsteroidViewHolder, position: Int) {
holder.bind(getItem(position), onClickListener)
}
class AsteroidViewHolder(private val binding: AsteroidListContainerBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(item: Asteroid, listener: OnClickListener) {
binding.value = item
binding.listener = listener
binding.executePendingBindings()
}
}
class OnClickListener(val clickListener: (asteroid: Asteroid) -> Unit) {
fun onClick(asteroid: Asteroid) = clickListener(asteroid)
}
}
视图模型
private const val TAG = "MainViewModel"
class MainViewModel(application: Application) : ViewModel() {
private val database = AsteroidDatabase.getDatabase(application)
private val repository = AsteroidRepository(database.asteroidDao)
private val _pictureOfDay = MutableLiveData<PictureOfDay>()
val pictureOfDay: LiveData<PictureOfDay>
get() = _pictureOfDay
val info: LiveData<List<Asteroid>> = Transformations.map(repository.feeds) {
it
}
private val _showProgress = MutableLiveData(true)
val showProgress: LiveData<Boolean>
get() = _showProgress
private val _navigation: MutableLiveData<Asteroid> = MutableLiveData()
val navigation: LiveData<Asteroid>
get() = _navigation
init {
fetchThePictureOfTheDay()
loadFeeds()
}
private fun loadFeeds() {
_showProgress.value = true
viewModelScope.launch {
try {
repository.fetchFeeds()
}catch (e: Exception) {
Log.e(TAG, e.message, e.cause)
}
}
}
private fun fetchThePictureOfTheDay() {
viewModelScope.launch {
try {
val picture = repository.getPictureOfTheDay()
_pictureOfDay.postValue(picture)
}catch (e: Exception) {
Log.e(TAG, e.message, e.cause)
}
}
}
fun navigateToDetails(asteroid: Asteroid) {
_navigation.value = asteroid
}
fun navigationDone() {
_navigation.value = null
}
fun progress(empty: Boolean) {
_showProgress.value = empty
}
fun filter(filter: Filter) {
viewModelScope.launch(Dispatchers.IO) {
repository.filterFeeds(filter)
}
}
}
片段
class MainFragment : Fragment() {
// private lateinit var manager: RecyclerView.LayoutManager
private lateinit var viewModel: MainViewModel
private lateinit var adapter: AsteroidViewAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val mainViewModelFactory = MainViewModelFactory(requireActivity().application)
viewModel = ViewModelProvider(this, mainViewModelFactory).get(MainViewModel::class.java)
val binding = FragmentMainBinding.inflate(inflater)
binding.lifecycleOwner = this
binding.viewModel = viewModel
// val mutableList: MutableList<Asteroid> = ArrayList()
// mutableList.add(Asteroid(1, "fgnuugrhrg", "bihagtyjerwailgubivb", 4.0, 8.0,3.0, 9.0, false))
// mutableList.add(Asteroid(2, "fguk.nuugrhrg", "bidjswjyhagrwailgubivb", 3.0, 90.0,355.0, 9.0, true))
// mutableList.add(Asteroid(3, "fgnssuugrhrg", "bshjtihagrwailgubivb", 4.0, 33.0,33.0, 9.0, false))
// mutableList.add(Asteroid(4, "fgnuw4suugrhrg", "bjsryjihagrwailgubivb", 6.0, 8.0,11.0, 9.0, true))
// mutableList.add(Asteroid(5, "fgnuugrudkdkhrg", "bihjjkkuagrwailgubivb", 4.0, 5.0,77.0, 9.0, false))
// manager = LinearLayoutManager(this.context)
binding.asteroidRecycler.adapter = AsteroidViewAdapter(AsteroidViewAdapter.OnClickListener {
viewModel.navigateToDetails(it)
})
viewModel.info.observe(viewLifecycleOwner, Observer {
viewModel.progress(it.isNullOrEmpty())
binding.asteroidRecycler.smoothScrollToPosition(0)
adapter.submitList(it)
})
viewModel.navigation.observe(viewLifecycleOwner, Observer { asteroid ->
asteroid?.let {
findNavController().navigate(MainFragmentDirections.actionShowDetail(it))
viewModel.navigationDone()
}
})
// binding.asteroidRecycler.adapter = adapter
setHasOptionsMenu(true)
return binding.root
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.main_overflow_menu, menu)
super.onCreateOptionsMenu(menu, inflater)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_show_week -> {
viewModel.filter(Filter.WEEK)
true
}
R.id.menu_show_today -> {
viewModel.filter(Filter.TODAY)
true
}
R.id.menu_show_saved -> {
viewModel.filter(Filter.SAVED)
true
}
else -> false
}
}
}
解决方案
根据错误消息,您实际上从未将您设置adapter
为任何值 - 您只是直接将其分配给binding.asteroidRecycler.adapter
.
由于适配器保持对 RecyclerView 本身的硬引用,因此无论如何您都不应该在片段级别持有对它的引用,而是应该在将其分配给 RecyclerView 之前为其创建一个局部变量:
val adapter = binding.asteroidRecycler.adapter = AsteroidViewAdapter(AsteroidViewAdapter.OnClickListener {
viewModel.navigateToDetails(it)
})
binding.asteroidRecycler.adapter = adapter
推荐阅读
- mongodb - com.mongodb.MongoTimeoutException:等待连接时超时 30000 毫秒。集群状态的客户端视图是 {type=UNKNOWN, servers=[]
- php - 在 Laravel 中在 db 结果上附加一列
- javascript - 自动更新 MongoDB 中的文档?
- javascript - React JS 功能组件中的复选框未更新
- typescript - 索引对象的打字稿参考值
- laravel - 如何使用实时服务器中的干预在 laravel 中创建缩略图?
- node.js - 如何使用 nodejs 创建具有特定域的 api 端点或 api?
- kubernetes - Kubernetes Pod 一次性初始任务
- vba - 如何仅替换字符串中的某些空格?
- omnet++ - 如何从 omnet++ 中的 c++ 代码访问运行时 queueLength 参数?