Access Fragment in Activity?
Asked Answered
C

4

5

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 fragment list adapter in activity with out making adapter as static adapter. Currently I am doing like this in Mainactivity.java

public void updatelist() {
  if(fragmentstate=0)
    Fragment1.adapter.notifyDataSetChanged();
  else
    Fragment2.adapter.notifyDataSetChanged();

}
Choi answered 12/2, 2015 at 14:58 Comment(2)
possible duplicate of How to get the fragment instance from the FragmentActivity?Lara
@Spity how it will be come duplicate of fragment instance.even i am using singleton in my code for fragment.but adapter making propblemChoi
A
5

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();
            }
        }
    }
}
Angloindian answered 12/2, 2015 at 15:9 Comment(5)
But if this is just a question of keeping track of which fragment is currently active, then this is overkill. Or at least, is the fragmentState even necessary? I don't think so. The fragments receive the event only if they are active, after all.Angloindian
i wish i could use otto.but i can't.Choi
Oh. That sucks. The LocalBroadcastManager can work as poor man's Otto.Angloindian
Please note that Otto delivers events on the same thread as on which you post the event.Angloindian
call setPaused(true) in onPause() and call setPaused(false) in onPostCreate()Angloindian
A
1

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

Anteversion answered 12/2, 2015 at 15:11 Comment(2)
I wonder that if getFragmentByTag("fragmentOneTag") will affect perfromance more than accessing adapter using staticGonophore
refreshList() is not static. getFragmentByTag returns a reference to the requested fragment so you can access it's public methodsAnteversion
T
1

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(...)
Tripody answered 12/2, 2015 at 15:16 Comment(2)
Why would you do this? All Fragments must be attached to an Activity which has created and added the Fragments in the first place. All the Activity has to do is call a public method on the relevant Fragment reference.Deviation
@Benrad Kim you are right.everything coming into single activity.why should i broadcast?Choi
D
0

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.

Deviation answered 12/2, 2015 at 15:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.