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
AppCompatActivity
instantiates aFragment
The
Fragment
's layout contains aRelativeLayout
with a toolbar and aninclude
tag for aViewPager
. TheViewPager
layout contains anotherinclude
tag that sets a layout with aRecyclerView
in aLinearLayout
. The layout XML with theCardView
is 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
ScrollView
in 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
ArrayList
is presented in theRecyclerView
-CardView
combo 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 theAsyncTask
that creates theArrayList
for theCardView
from 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)!