0

I have been reading the different answers here on stackoverflow and tried to implement their solutions but I am still getting the error:

E/RecyclerView: No adapter attached; skipping layout

This error is logged in Log.cat .When I try to attach recyclerView Adapter in fragment .

This is the adapter which want to attached with the recyclerView

Adapter

 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)
}

}
  • 1
    Try to add the adapter in `onCreateView()` – Animesh Sahu Jun 03 '20 at 10:39
  • Can you post more information? add your adapter code and the place where you are attaching your adapter to your recyclerview. – eyadMhanna Jun 03 '20 at 11:04
  • @AnimeshSahu adapter can be added in `onViewCreated()` method. In fact, it is cleaner to do every `View` related stuff in `onViewCreated()` and `onCreateView()` should be used to just inflate the layout. – cgb_pandey Jun 03 '20 at 11:32
  • @ankitbhati, where and how did you setup your adapter? Post more code here so that we can find out what wrong happened there. – cgb_pandey Jun 03 '20 at 11:33
  • @cgb_pandey ,As i post adapter and fragment both . So now can you find out what wrong happened here. – ankit bhati Jun 05 '20 at 05:30
  • @ankitbhati I do not still see how you created the instance of the `RecyclerView`. I just saw you set `layoutmanager` and `adapter` to `sli` which I guess is a `RecyclerView` but I do not see how you assigned `sli` to the `RecylerView` in you `xml` file. Sorry, if things is done this way in Kotlin. I dont know Kotlin although I think there shouldn't be much differences in the way we do things in Kotlin and/or in Java. – cgb_pandey Jun 05 '20 at 06:23
  • @cgb_pandey actually sli is the id i choose for my recyclerView – ankit bhati Jun 06 '20 at 09:15
  • so how do you initialize the `sli` object? In java, we would do `sli = view.findViewById(R.id.sli)` to create the `sli` object, where is that part ? I saw that you just started assigning `layoutmanager` and `adapter` of `sli` without properly creating its instance. – cgb_pandey Jun 06 '20 at 09:32
  • @cgb_pandey but that's can be managed by an import kotlinx.android.synthetic.main.fragment_main_activity.* That's why i don't create an object of sli – ankit bhati Jun 06 '20 at 10:22
  • Try to check the value of `mAdapter` before setting it to the `sli` to see if it is non-null. If it is then `onViewCreated()` would be the best place to declare and initialize it or at least declare it as class variable and initialize it down there. – cgb_pandey Jun 06 '20 at 12:54

0 Answers0