我一直在 stackoverflow 上阅读不同的答案,并尝试实施他们的解决方案,但我仍然收到错误消息:
E/RecyclerView: No adapter attached; skipping layout
此错误记录在 Log.cat 中。当我尝试在片段中附加 recyclerView 适配器时。
这是要与 recyclerView 连接的适配器
适配器
class SubjectViewHolder(override val containerView: View):
RecyclerView.ViewHolder(containerView)
, LayoutContainer {
fun bind(subject: Subject, listener: CursorRecyclerViewAdapter.OnSubjectClickListener) {
subject_list_name.text = subject.name
subject_list_present.text = subject.present.toString()
subject_list_total.text = subject.totalClass.toString()
subject_list_delete.setOnClickListener {
Log.d(TAG,"delete button tapped. task name is ${subject.name}")
listener.onDeleteClick(subject)
}
}
}
private const val TAG="CursorViewAdapt"
class CursorRecyclerViewAdapter(private var cursor: Cursor?, private val listener: OnSubjectClickListener) :
RecyclerView.Adapter<SubjectViewHolder>(){
interface OnSubjectClickListener {
fun onDeleteClick(subject: Subject)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubjectViewHolder {
Log.d(TAG,"onSubjectViewHolder: new view requested")
val view= LayoutInflater.from(parent.context).inflate(R.layout.subject_list,parent,false)
Log.d(TAG,"onCreateViewHolder: ends")
return SubjectViewHolder(view)
}
override fun getItemCount(): Int {
Log.d(TAG,"getItemCount: starts")
val cursor=cursor// to remove the smart cast problem
val itemcount= if(cursor==null || cursor.count==0){
1
}else{
cursor.count
}
Log.d(TAG,"returning $itemcount")
return itemcount
}
override fun onBindViewHolder(holder: SubjectViewHolder, position: Int) {
Log.d(TAG, "onBindViewHolder: starts")
val cursor = cursor //avoid problems with smart cast
if (cursor == null || cursor.count == 0) {
holder.subject_list_name.setText("Instruction_heading")
} else {
if (!cursor.moveToPosition(position)) {
throw IllegalStateException("Couldn't move cursor to position $position")
}
val task = Subject(
cursor.getString(cursor.getColumnIndex(SubjectContract.Columns.SUBJECT_NAME)),
cursor.getInt(cursor.getColumnIndex(SubjectContract.Columns.TOTAL_PRESENT)),
cursor.getInt(cursor.getColumnIndex(SubjectContract.Columns.TOTAL_CLASS))
)
task.id = cursor.getLong(cursor.getColumnIndex(SubjectContract.Columns.ID))
holder.bind(task, listener)
}
}
fun swapCursor(newCursor: Cursor?): Cursor?{
if (newCursor==cursor){
return null
}
val numItems=itemCount
val oldCursor=cursor
cursor=newCursor
if (newCursor!=null){
notifyDataSetChanged()
}else{
notifyItemRangeRemoved(0,numItems)
}
return oldCursor
}
}
MainActivityFragment
private const val TAG="MainActivityFragment"
class MainActivityFragment : Fragment(),
CursorRecyclerViewAdapter.OnSubjectClickListener {
interface OnUpdate{
fun onUpdate()
}
private val viewModel by lazy { ViewModelProvider(requireActivity()).get(AttendanceViewModel::class.java) }
private val mAdapter=CursorRecyclerViewAdapter(null,this )
override fun onCreate(savedInstanceState: Bundle?) {
Log.d(TAG,"onCreate: starts")
super.onCreate(savedInstanceState)
viewModel.cursor.observe(this, Observer { cursor-> mAdapter.swapCursor(cursor)?.close() })
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.d(TAG,"onCreateView: called")
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_main_activity, container, false)
}
override fun onAttach(context: Context) {
Log.d(TAG,"onAttach: called")
super.onAttach(context)
if (context !is OnUpdate){
throw RuntimeException("${context.toString()} must implement OnTaskEdit")
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
Log.d(TAG,"attaching Adapter")
sli.layoutManager= LinearLayoutManager(context)
sli.adapter=mAdapter
}
override fun onDeleteClick(subject: Subject) {
viewModel.deleteSubject(subject.id)
}
}