This problem has been beaten a million times, but unfortunately, no answer on SO has helped solve my issue.
Fundamentally, my question is that, in a RecyclerView with a CardView in a Fragment, when and where should the following tasks be performed:
- Fetching data from a server to the local database on the user's device
- Processing the so-fetched local data
- Instantiating and setting the
RecyclerView's adapter - Calling the
RecyclerView'snotifyfDataSetChanged()
The RecyclerView in my implementation presently calls back only getItemCount(). onCreateViewHolder() and onBindViewHolder() are never getting called back.
(I have seen this answer and a gazillion more.)
Here is the sequence of how its being done:
- An
AppCompatActivityinstantiates aFragment The
Fragment's layout contains aRelativeLayoutwith a toolbar and anincludetag for aViewPager. TheViewPagerlayout contains anotherincludetag that sets a layout with aRecyclerViewin aLinearLayout. The layout XML with theCardViewis set in theRecyclerView's adapter:public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { Log.wtf(LOG_TAG, "Inside onCreateViewHolder()"); View myView; LayoutInflater inflater; inflater = LayoutInflater.from(parent.getContext()); myItemView = inflater.inflate(R.layout.my_row_layout, parent, false); MyViewHolder myViewHolderItem = new MyViewHolder(myItemView); return myViewHolderItem; }There's no
ScrollViewin any layout- The
Fragment'sonCreate()calls a method to fetch data from a server
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Some cache processing
args = getArguments();
myDBHelper = MyDBHelper.getInstance(getActivity());
Intent intent = getActivity().getIntent();
// Search comes from search intent
if (intent.getBooleanExtra(MyContract.MY_SEARCH_REQUEST, false))
{
...
getDataFromCloud("", true);
getDataFromLocalDB(false, item);
} // of if search intent
// Plain intent
else
{
getDataFromCloud("item", false);
getDataFromLocalDB(true, item);
}
} // of onCreate()
- This data gets populated into a local database on the user's device
- Another method in the
Fragment'sonCreate()filters the local data into anArrayList - This
ArrayListis presented in theRecyclerView-CardViewcombo finally to the user. notifyDataSetChanged()is called in the Fragment'sonActivityCreated(). But the fact is, its not making a difference anywhere it is called from. Also, the adapter is instantiated in theonPostExecute()of theAsyncTaskthat creates theArrayListfor theCardViewfrom the local database.
Here's the log that results on running the app:
01-03 08:47:34.546 13489-14033/com.my A/MyDBHelper class: Create View-1 query: CREATE VIEW
01-03 08:47:34.562 13489-13489/com.my A/MyFragment: getItemCount: 0
01-03 08:47:34.584 13489-14033/com.my A/MyDBHelper class: Create View-2 query: CREATE TABLE
01-03 08:47:34.638 13489-13489/com.my A/MyFragment: getItemCount: 0
01-03 08:47:34.722 13489-13489/com.my A/MyFragment: getItemCount: 2
01-03 08:47:34.743 13489-13489/com.my A/MyFragment: getItemCount: 2
In the above log, the View-1 query fetches server data and the View-2 query processes the so-fetched local data.
I have log statements in the onCreateViewHolder() and onBindViewHolder(). As evident above, these methods are just not being invoked, despite a positive return from getItemCount(), which is the size of the ArrayList. The app just shows the toolbar, and an empty white card, despite there being two records or items to be shown.
Been staring at these logs for the past couple of days with no progress or clues. Many thanks in advance for your expert advice or pointers (and for saving what's left of my sanity)!