I'm quite busy, but I'll drop you some hints here to help you move forwards.
I'm not touching your adapters to make it more simple but consider unifying as much as you can, if both lists are almost the same but with different
getView()
methods, use a common base abstract class for both adapters and implement each different getView(). This is just an example.Beware of that Context that you pass. Don't pass the activity to your adapter. In this particular case there doesn't seem to be any harm, but, the fragment is handled by the FragmentManager, and the Adapter lives in the fragment, so you are potentially leaking memory for a while until the fragment gets really destroyed. Instead pass getActivity().getApplicationContext(); (or better yet, in your adapter's constructor do:
this.context = context.getApplicationContext();
(this way you always reference that).It's really long to put in code here (and I have to go back to work!) but think of the problem this way:
- Your Activity is hosting two (or more) Fragments.
- In your fragment(s) you perform an action that modifies the same data as another Fragment
- You need to notify everyone who is interested that the data has been changed so they can do whatever is needed (update the UI, reload, etc.).
How would I do this
- Have a "DataController" class that contains the list of talks.xml already parsed. Anyone could do:
DataController.getInstance(context).getListOfTalks();
- DataController would check if the list is null and proceed to create/parse then return the value. If the list is not null, then it will return it. Now your consumers of the data have no idea where it comes from and it always comes from the same place.
- Have your Adapters fetch the data from the DataController as outlined in #2.
- Now that the data is in a central repository, have your data controller implement methods to modify/persist the data (i.e. if you use SQL that code should be in that controller).
- Have DataController implement a Listener/Observer pattern or similar so interested parties can subscribe and be notified.
- When a fragment/onclick needs to check a box, it tells the DataController, which in turns saves this new data, then proceeds to fire a notification to its listeners.
- Each fragment subscribes to the DataController upon startup (and removes itself during onStop() for example).
- When the fragments receive this "notification" they proceed to tell the adapter to update the data.
It sounds like a lot but you'd be gaining a lot of good things. Separating the data from the view, unifying places, establishing a common communication pattern, etc.
Some pseudo code of this DataController would be…
public class DataController {
private static DataController sDataController;
private final Context mAppContext;
private final List<DataChangeListener> mListeners = new ArrayList<DataChangeListener>();
private List<Talks> mData;
private DataController(final Context appContext) {
mAppContext = appContext;
}
public static DataController get(Context context) {
if (sDataController == null) {
if (context != null) {
sDataController = new DataController(context.getApplicationContext());
} else {
sDataController = new DataController(YourAppClass.getInstance().getApplicationContext());
}
}
return sDataController;
}
/**
* {@link DataChangeListener} listeners will be notified when certain requests have been made.
*
* @param listener - a valid DataChangeListener. If null, nothing is added.
*/
public void addDataChangeListener(DataChangeListener listener) {
if (listener != null && !mListeners.contains(listener)) {
mListeners.add(listener);
}
}
/**
* Remove a {@link DataChangeListener} from the list.
*
* @param listener - a valid DataChangeListener. If null, nothing is removed.
*/
public void addDataChangeListener(DataChangeListener listener) {
if (listener != null) {
mListeners.remove(listener);
}
}
// INTERESTING METHODS YOU HAVE TO IMPLEMENT
public List<Talks> getData(){
if ( mData == null ) {
parseData();// implement this
}
return mData;
}
public void checkBoxChanged(final somedatatype somedata) {
// pass the appropriate values you need and save them to your sql, update the list of talks
// talks should contain the value of the checkbox, add it to your Talks object if it's not there.
updateSQL();
notifyDataChnged();
}
public void notifyDataChnged(){
if (mListeners != null) {
for (DataChangeListener listener : mListeners) {
listener.onDataSetChanged();
}
}
}
}
This is the interface:
public interface DataChangeListener {
void onDataSetChanged();
}
Now your Fragments would do something like:
@Override
public void onResume() {
super.onResume();
DataController.getInstance(context).addDataChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
DataController.getInstance(context).removeDataChangeListener(this);
}
And of course they implement the interface…
public class PapersFragment extends Fragment implements DataChangeListener {
and the obliged method…
@Override
public void onDataSetChanged(){
// Data has changed, do something about it, like telling the adapter and doing anything you see fit.
}
I think this is a good starting point that will lead you to better architecture.
Good luck!