访问活动中的片段?

时间:2015-02-12 14:58:46

标签: android android-fragments android-listview

我有一个包含2个片段的主要活动。两个片段都有ListView。我想更新MainActivity中的列表。有没有办法在活动中访问片段列表适配器而不将适配器作为静态适配器。 目前我在Mainactivity.java

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

}

4 个答案:

答案 0 :(得分:4)

您可以使用Otto事件总线执行以下操作:

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

修订版的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();
            }
        }
    }
}

答案 1 :(得分:2)

如果您只想更新片段上的列表,则无需访问adpaters。您可以在片段上注册本地广播,并从MainActivity发送本地广播消息。

来自frgments,

LocalBroadcastManager.getInstance(getContext()).registerReceiver(...);

来自MainActivity,

LocalBroadcastManager.getInstance(getContext()).sendBroadcast(...)

答案 2 :(得分:1)

不要使用静态适配器。有更好(更安全)的方法可以从其父级Activity访问您的片段。

我假设您使用以下内容动态添加片段:

FragmentManager fragmentManager = getFragmentManager();
fragmentManager
              .beginTransaction()
              .add(R.id.fragment_container, new FragmentOne())
              .commit();

对于片段2也是如此。

为了引用那些Fragment,您需要在创建标记时添加标记。非常简单,只需在现有代码中添加一行:

FragmentManager fragmentManager = getFragmentManager();
fragmentManager
              .beginTransaction()
              .add(R.id.fragment_container, new FragmentOne(), "fragmentOneTag")
              .commit();

然后,只要你想让你的片段做到这一点:

FragmentManager fragmentManager = getFragmentManager();
FragmentOne fragmentOne = fragmentManager.getFragmentByTag("fragmentOneTag");

fragmentOne.refreshList();      //Define this method in your class and from there refresh your list

那是

答案 3 :(得分:0)

  

有没有办法在活动中访问片段列表适配器而不将适配器作为静态适配器。

是。 Fragments的设计指南允许他们公开可以从他们所附加的public调用的Activity方法。只需在每个Fragment中创建一个方法,然后调用您需要的方法。

Activity应该保留对其创建的任何Fragments的引用。只需让Fragment方法更新自己的适配器。