Hi, I've been having this problem all day and can'...
# android
b
Hi, I've been having this problem all day and can't figure it our. I have asked in other places but no joy (There is a link to the Stack Overflow question at the end). Ime really stuck and hoping someone here takes pity on me :). I've been following a tutorial that uses a provider to talk to a DB and use an observer to keep a RecyclerView up to date. Its a bit out of date so I've spent a few hours getting it (kind of working). I got as far as getting it working when there were no records in the DB (I pass null cursor to the RecycleViewAdapter and if this is the case it displays instructions in the list view). When I run it I get the instructions even though there are 2 records in DB (it should dhow the records). The problem is when I have data it does not seem to put it in the RecycleView.
😶 5
🧵 3
In the Fragment, I am setting up the adapter and observer. So I have set up the adapter in the Fragment class
Copy code
private val viewModel by lazy { ViewModelProvider(this)[TaskTimerViewModel::class.java] } 
private val mAdapter = CursorRecyclerViewAdapter(null) // null=view with instructions
In onCreate set up the observer
Copy code
viewModel.cursor.observe( // New
  this, Observer { cursor -> mAdapter.swapCursor(cursor)?.close() }
)
and in onViewCreated setup the adapter
Copy code
binding.taskList.adapter = mAdapter // Attach Adapter to Recyclerview
Looking at Logcat when I query the DB in AppPrivider I get two rows returned then later on I see the CursorRecyclerView adapter has no records. This Logcat is from just running the App without interacting with it. I am expecting to see the records from the database but I just see the instructions (which are displayed when there is no data).
Copy code
AppProviderXX        com.funkytwig.takstimer  D  onCreate
MainActivityXX       com.funkytwig.takstimer  D  onCreate
MainFragmentXX       com.funkytwig.takstimer  D  onAttach
MainFragmentXX       com.funkytwig.takstimer  D  onCreate
TaskTimerViewModelXX com.funkytwig.takstimer  D  init
TaskTimerViewModelXX com.funkytwig.takstimer  D  loadTasks
AppProviderXX        com.funkytwig.takstimer  D  query for uri=<content://com.funkytwig.tasktimer.provider/Tasks>
AppProviderXX        com.funkytwig.takstimer  D  buildUriMatcher
AppProviderXX        com.funkytwig.takstimer  D  query: 2 rows returned **********
TaskTimerViewModelXX com.funkytwig.takstimer  D  loadTasks done
MainFragmentXX       com.funkytwig.takstimer  D  onCreate done
MainActivityXX       com.funkytwig.takstimer  D  onCreate done
MainActivityXX       com.funkytwig.takstimer  D  onStart
MainFragmentXX       com.funkytwig.takstimer  D  onCreateView
MainFragmentXX       com.funkytwig.takstimer  D  onViewCreated
MainFragmentXX       com.funkytwig.takstimer  D  onViewStateRestored
MainFragmentXX       com.funkytwig.takstimer  D  onStart
MainActivityXX       com.funkytwig.takstimer  D  onResume
MainFragmentXX       com.funkytwig.takstimer  D  onResume
CurRecViewAdapterXX  com.funkytwig.takstimer  D  getItemCount: no items so return 1 **************
CurRecViewAdapterXX  com.funkytwig.takstimer  D  swapCursor new & previous cursor unchanged
CurRecViewAdapterXX  com.funkytwig.takstimer  D  getItemCount: no items so return 1
CurRecViewAdapterXX  com.funkytwig.takstimer  D  getItemCount: no items so return 1
CurRecViewAdapterXX  com.funkytwig.takstimer  D  onCreateViewHolder
CurRecViewAdapterXX  com.funkytwig.takstimer  D  onBindViewHolder: cursor empty
MainActivityXX       com.funkytwig.takstimer  D  onCreateOptionsMenu
Full code at https://github.com/funkytwig/tasktimer/tree/master/app/src/main but I have included what I think are the most relevant classes below. I have also posted a longer more detailed version of this question at https://stackoverflow.com/questions/74071324/problem-with-adapter-on-cursor-recyclervew but have had no responses.
c
In your
swapCursor
method you are not assigning the
newCursor
to
this.cursor
b
So tried
Copy code
fun swapCursor(newCursor: Cursor?): Cursor? {
    val func = "swapCursor"
    if (newCursor === cursor) return null

    val numItems = itemCount
    val oldCursor = cursor

    if (newCursor != null) {
        Log.d(TAG, "$func new & previous cursor unchanged")
        this.cursor = cursor // *******
        // notify observer about cursor
        notifyDataSetChanged()
    } else { // cursor has changed
        Log.d(TAG, "$func new & previous cursor different")
        // Notify observer about lack of dataset, all of it from 0 to newItems,
        // i.e. whole range of records has gone
        notifyItemRangeChanged(0, numItems)
    }

    return oldCursor
}
ut no joy. Is that what you mean?
c
Ehm, do you have any programming skills? Do you understand the difference between a class property and a method parameter? You’ll need something like this:
Copy code
...
if (newCursor != null) {
  this.cursor = newCursor
  notifyDataSetChanged()
}
...
so then you/the adapter has access to the new cursor in all the other methods and the Recyclerview can start from the beginning with creating your views.
So I’d advise you to start learning Object-Oriented-Programming before you start building an android application. That’s also the reason why your question is 😶 - it’s more about how to implement something in an Object oriented programming language than a ā€œissueā€ you have with Kotlin.
šŸ‘ 1
šŸ‘šŸ¼ 1
b
Going to reply to your post on Stack Overflow as it seems more appropriate place.
Ok, actually got it working. In terms of OO I've done quite a few languages that use OO, first did it at University. Starting with Brooks There is no silver bullet article and we did a little Smalltalk. I then ended up using OO in PHP (which barely counts) and did some Ruby and recently Python. I think I have a fairly good grasp of it but if there are any teaching resources for OOP/Kotlin be great if you could point me at them. I ended up getting it working. I did not really understand the swapCursor function when it was put in the course (with the course I find I don't totally understand stuff until I see it actually working so was not overly conserved). Think my confusion was partly because I missed the line '
Copy code
cursor = newCursor
at the beginning but when I put it in it made a lot more sense. Thanks your help. now you have pointed me in the correct direction. It now makes a lot more sence.
šŸ‘ 1