Access Fragment in Activity?

谁说胖子不能爱 提交于 2020-01-27 04:20:26

问题


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();

}

回答1:


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();
            }
        }
    }
}



回答2:


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




回答3:


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(...)



回答4:


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.



来源:https://stackoverflow.com/questions/28480704/access-fragment-in-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!