Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 为RecyclerView片段实现ListAdapter_Android_Kotlin_Android Recyclerview_Android Livedata_Android Listadapter - Fatal编程技术网

Android 为RecyclerView片段实现ListAdapter

Android 为RecyclerView片段实现ListAdapter,android,kotlin,android-recyclerview,android-livedata,android-listadapter,Android,Kotlin,Android Recyclerview,Android Livedata,Android Listadapter,我已经用一个普通的视图适配器成功地完成了这项工作,但我似乎无法用列表适配器使其工作 这是我的片段,它完成了大部分工作: class CrimeListFragment: Fragment() { //Required interface for hosting activities interface Callbacks { fun onCrimeSelected(crimeId: UUID) } private var callbacks:

我已经用一个普通的视图适配器成功地完成了这项工作,但我似乎无法用列表适配器使其工作

这是我的片段,它完成了大部分工作:

class CrimeListFragment: Fragment() {

    //Required interface for hosting activities
    interface Callbacks {
        fun onCrimeSelected(crimeId: UUID)
    }

    private var callbacks: Callbacks? = null
    private lateinit var crimeRecyclerView: RecyclerView
    private val crimeListViewModel: CrimeListViewModel by lazy {
        ViewModelProviders.of(this).get(CrimeListViewModel::class.java)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)

        callbacks = context as Callbacks?
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val view = inflater.inflate(R.layout.fragment_crime_list, container, false)

        crimeRecyclerView =
            view.findViewById(R.id.crime_recycler_view) as RecyclerView
        crimeRecyclerView.layoutManager = LinearLayoutManager(context)
        crimeRecyclerView.adapter = CrimeListAdapter(emptyList())

        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        crimeListViewModel.crimeListLiveData.observe(
            viewLifecycleOwner,
            Observer { crimes ->
                crimes?.let {
                    Log.i(TAG, "Got crimes ${crimes.size}")
                    updateUI(crimes)
                }
            }
        )
    }

    override fun onDetach() {
        super.onDetach()

        callbacks = null
    }

    private fun updateUI(crimes: List<Crime>) {
        crimeRecyclerView.adapter = CrimeListAdapter(crimes)
    }

    companion object {
        fun newInstance(): CrimeListFragment {
            return CrimeListFragment()
        }
    }

    private inner class CrimeHolder(view: View)
        : RecyclerView.ViewHolder(view), View.OnClickListener {

        private lateinit var crime: Crime
        private val titleTextView = itemView.findViewById<TextView>(R.id.crime_title)
        private val dateTextView = itemView.findViewById<TextView>(R.id.crime_date)
        private val solvedImageView = itemView.findViewById<ImageView>(R.id.crime_solved)

        init {
            itemView.setOnClickListener(this)
        }

        fun bind(crime: Crime) {
            this.crime = crime
            titleTextView.text = crime.title
            dateTextView.text = crime.date.toString()
            solvedImageView.visibility = if(crime.isSolved) {
                View.VISIBLE
            } else {
                View.GONE
            }
        }

        override fun onClick(v: View) {
            callbacks?.onCrimeSelected(crime.id)
        }
    }

    private inner class CrimeListAdapter(var crimes: List<Crime>)
        : ListAdapter<Crime, CrimeHolder>(DiffCallback()) {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CrimeHolder {
            val view =
                layoutInflater.inflate(R.layout.list_item_crime, parent, false)

            return CrimeHolder(view)
        }

        override fun onBindViewHolder(holder: CrimeHolder, position: Int) {
            holder.bind(crimes[position])
        }
    }

    private inner class DiffCallback: DiffUtil.ItemCallback<Crime>() {

        override fun areItemsTheSame(oldItem: Crime, newItem: Crime): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Crime, newItem: Crime): Boolean {
            return oldItem == newItem
        }
    }
}
class-CrimeListFragment:Fragment(){
//托管活动所需的接口
接口回调{
已选择一次犯罪的乐趣(犯罪ID:UUID)
}
私有变量回调:回调?=null
私有lateinit var crimeRecyclerView:RecyclerView
private val crimeListViewModel:lazy提供的crimeListViewModel{
ViewModelProviders.of(this.get)(CrimeListViewModel::class.java)
}
重写转速表(上下文:上下文){
super.onAttach(上下文)
回调=作为回调的上下文?
}
覆盖创建视图(
充气机,
容器:视图组?,
savedInstanceState:捆绑?
):查看{
val视图=充气机。充气(R.layout.fragment\u crime\u列表,容器,false)
犯罪循环视图=
视图。findViewById(R.id.crime\u recycler\u视图)作为RecyclerView
crimeRecyclerView.layoutManager=LinearLayoutManager(上下文)
crimeRecyclerView.adapter=CrimeListAdapter(emptyList())
返回视图
}
覆盖已创建的视图(视图:视图,保存状态:捆绑?){
super.onViewCreated(视图,savedInstanceState)
crimeListViewModel.crimeListLiveData.observe(
viewLifecycleOwner,
观察员{罪行->
犯罪?让我来{
Log.i(标记“Got crimes${crimes.size}”)
更新(刑事)
}
}
)
}
覆盖连接(){
super.onDetach()
回调=null
}
私人娱乐更新(犯罪:列表){
crimeRecyclerView.adapter=CrimeListAdapter(犯罪)
}
伴星{
fun newInstance():CrimeListFragment{
返回CrimeListFragment()
}
}
私有内部类CrimeHolder(视图:视图)
:RecyclerView.ViewHolder(视图),view.OnClickListener{
私人犯罪:犯罪
private val titleTextView=itemView.findviewbyd(R.id.crime\u title)
private val dateTextView=itemView.findViewById(R.id.crime\U日期)
private val solvedImageView=itemView.findviewbyd(R.id.crime\u已解决)
初始化{
itemView.setOnClickListener(此)
}
娱乐绑定(犯罪:犯罪){
这是犯罪
titleTextView.text=crime.title
dateTextView.text=crime.date.toString()
solvedImageView.visibility=if(crime.isSolved){
View.VISIBLE
}否则{
视图消失了
}
}
覆盖趣味onClick(v:视图){
回调?.onCrimeSelected(crime.id)
}
}
私有内部类CrimeListAdapter(变量犯罪:列表)
:ListAdapter(DiffCallback()){
override fun onCreateViewHolder(父级:ViewGroup,viewType:Int):CrimeHolder{
瓦尔视图=
LayoutFlater.充气(R.layout.list\u item\u crime,parent,false)
返回CrimeHolder(视图)
}
覆盖BindViewHolder(holder:CrimeHolder,位置:Int){
持有者绑定(罪行[职位])
}
}
私有内部类DiffCallback:DiffUtil.ItemCallback(){
覆盖乐趣项目相同(旧项目:犯罪,新项目:犯罪):布尔值{
返回oldItem.id==newItem.id
}
覆盖乐趣内容相同(旧项:犯罪,新项:犯罪):布尔值{
返回oldItem==newItem
}
}
}
这是片段的视图模型:

class CrimeListViewModel: ViewModel() {

    private val crimeRepository = CrimeRepository.get()
    val crimeListLiveData = crimeRepository.getCrimes() //returns LiveData<List<Crime>>
}
class-CrimeListViewModel:ViewModel(){
private val crimeRepository=crimeRepository.get()
val crimeListLiveData=crimeRepository.getCrimes()//返回LiveData
}
Android文档中有关于ListAdapter的以下内容:

虽然使用LiveData是向适配器提供数据的一种简单方法,但它不是必需的-当新列表可用时,您可以使用submitList(List)

  • 我应该在每次更新UI时提交一个新列表,而不是创建一个新的ListAdapter对象。但是
    crimeRecyclerView.adapter
    没有
    .submitList()
    函数。那么我如何传递新的列表呢

  • LiveData对我来说还是个新鲜事物,所以我对此不太清楚。我已经观察到存储在我的viewmodel中的LiveData。那么这次我观察到了什么呢?或者我只是将代码添加到现有的观察者中

  • 最后,当我在这种状态下运行代码时,手机会显示一个空的RecyclerView。只调用了
    UpdateUI()
    ,没有调用
    CrimeListAdapter
    的函数。我不确定这是一个真正的问题,还是仅仅是上述问题的后果

  • 1.我应该在每次更新UI时提交一个新列表,而不是创建一个新的ListAdapter对象。但是 crimeRecyclerView.adapter没有.submitList()函数。那我该怎么做呢 把新名单传下去

    crimeRecyclerView.adapter
    return RecyclerView.adapter类型

    submitList()
    是ListAdapter的一个方法,ListAdapter是RecyclerView.Adapter的一个子类

    在调用该方法之前,需要从超类转换为子类,如下所示

    (crimeRecyclerView.adapter as CrimeListAdapter).submitList(crimes)
    
    2.LiveData对我来说还是新的,所以我对此不太清楚。我已经观察到存储在viewmodel中的LiveData。那我该怎么办 观察这一次?或者我只是向现有的观察者添加代码

    这部分代码很好,不需要做更多的工作

    3.最后,当我在这种状态下运行代码时,手机显示一个空的RecyclerView。只调用UpdateUI(),而不调用CrimeListAdapter的 函数被调用。我不确定这是不是一个r
    // crimeRecyclerView.adapter = CrimeListAdapter(emptyList())
    crimeRecyclerView.adapter = CrimeListAdapter()
    
    // crimeRecyclerView.adapter = CrimeListAdapter(crimes)
    (crimeRecyclerView.adapter as CrimeListAdapter).submitList(crimes)
    
    //private inner class CrimeListAdapter(var crimes: List<Crime>) :
    //    ListAdapter<Crime, CrimeHolder>(DiffCallback()) {
    //
    //    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CrimeHolder {
    //        val view = layoutInflater.inflate(R.layout.list_item_crime, parent, false)
    //        return CrimeHolder(view)
    //    }
    //
    //    override fun onBindViewHolder(holder: CrimeHolder, position: Int) {
    //        holder.bind(crimes[position])
    //    }
    //}
    
    private inner class CrimeListAdapter : ListAdapter<Crime, CrimeHolder>(DiffCallback()) {
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CrimeHolder {
            val view = layoutInflater.inflate(R.layout.list_item_crime, parent, false)
            return CrimeHolder(view)
        }
    
        override fun onBindViewHolder(holder: CrimeHolder, position: Int) {
            holder.bind(getItem(position))
        }
    }