I have one main activity with 2 fragments. Both fragments have a ListView
. I want to update the list in MainActivity
. Is there any way to access fr
Is there any way to access fragment list adapter in activity with out making adapter as static adapter.
Yes. Design guidelines for Fragments
allow them to expose public
methods which can be called from the Activity
they're attached to. Simply create a method in each Fragment
and call whichever one you need to.
The Activity
should be holding references to any Fragments
it has created. Just have the Fragment
methods update their own adapters.
Don't use the static adapter. There are better (safer) ways to access your fragments from it's parent Activity
.
I'm assuming you add your fragment dynamically by using something like this:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager
.beginTransaction()
.add(R.id.fragment_container, new FragmentOne())
.commit();
And same for fragment two.
In order to have a reference to those Fragment
you need to add a tag when you create them. Very simple, just add one line to your existing code:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager
.beginTransaction()
.add(R.id.fragment_container, new FragmentOne(), "fragmentOneTag")
.commit();
And then whenever you want to get your fragment do this:
FragmentManager fragmentManager = getFragmentManager();
FragmentOne fragmentOne = fragmentManager.getFragmentByTag("fragmentOneTag");
fragmentOne.refreshList(); //Define this method in your class and from there refresh your list
That's it
You could do the following with Otto event bus:
public class UpdateListEvent {
private int fragmentState;
public UpdateListEvent(int fragmentState) {
this.fragmentState = fragmentState;
}
}
public class MainActivity extends ActionBarActivity {
...
public void updatelist() {
SingletonBus.INSTANCE.getBus().post(new UpdateListEvent(fragmentState));
}
}
public class FragmentA extends Fragment {
@Override
public void onResume() {
super.onResume();
SingletonBus.INSTANCE.getBus().register(this);
}
@Override
public void onPause() {
SingletonBus.INSTANCE.getBus().unregister(this);
super.onPause();
}
@Subscribe
public void onUpdateListEvent(UpdateListEvent e) {
if(e.getFragmentState() == 0) { //is this even necessary?
this.adapter.notifyDataSetChanged();
}
}
}
public class FragmentB extends Fragment {
@Override
public void onResume() {
super.onResume();
SingletonBus.INSTANCE.getBus().register(this);
}
@Override
public void onPause() {
SingletonBus.INSTANCE.getBus().unregister(this);
super.onPause();
}
@Subscribe
public void onUpdateListEvent(UpdateListEvent e) {
if(e.getFragmentState() != 0) { //is this even necessary?
this.adapter.notifyDataSetChanged();
}
}
}
And a revised version of the Singleton Bus
public enum SingletonBus {
INSTANCE;
private static String TAG = SingletonBus.class.getSimpleName();
private Bus bus;
private volatile boolean paused;
private final Vector<Object> eventQueueBuffer = new Vector<>();
private Handler handler = new Handler(Looper.getMainLooper());
private SingletonBus() {
this.bus = new Bus(ThreadEnforcer.ANY);
}
public <T> void postToSameThread(final T event) {
bus.post(event);
}
public <T> void postToMainThread(final T event) {
try {
if(paused) {
eventQueueBuffer.add(event);
} else {
handler.post(new Runnable() {
@Override
public void run() {
try {
bus.post(event);
} catch(Exception e) {
Log.e(TAG, "POST TO MAIN THREAD: BUS LEVEL");
throw e;
}
}
});
}
} catch(Exception e) {
Log.e(TAG, "POST TO MAIN THREAD: HANDLER LEVEL");
throw e;
}
}
public <T> void register(T subscriber) {
bus.register(subscriber);
}
public <T> void unregister(T subscriber) {
bus.unregister(subscriber);
}
public boolean isPaused() {
return paused;
}
public void setPaused(boolean paused) {
this.paused = paused;
if(!paused) {
Iterator<Object> eventIterator = eventQueueBuffer.iterator();
while(eventIterator.hasNext()) {
Object event = eventIterator.next();
postToMainThread(event);
eventIterator.remove();
}
}
}
}
If you just want to update lists on fragments, you don't have to access the adpaters. You can register local broadcast on fragments, and send local broadcast message from MainActivity.
From frgments,
LocalBroadcastManager.getInstance(getContext()).registerReceiver(...);
From MainActivity,
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(...)