在活动中访问片段?
Posted
技术标签:
【中文标题】在活动中访问片段?【英文标题】:Access Fragment in Activity? 【发布时间】:2015-04-13 09:06:38 【问题描述】:我有一个包含 2 个片段的主要活动。两个片段都有一个ListView
。我想更新MainActivity
中的列表。有没有办法在不将适配器设置为静态适配器的情况下访问活动中的片段列表适配器。
目前我在Mainactivity.java
做这样的事情@
public void updatelist()
if(fragmentstate=0)
Fragment1.adapter.notifyDataSetChanged();
else
Fragment2.adapter.notifyDataSetChanged();
【问题讨论】:
How to get the fragment instance from the FragmentActivity? 的可能重复项 @Spity 它将如何与片段实例重复。即使我在片段的代码中使用单例。但适配器制作问题 【参考方案1】:您可以使用 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();
以及单例总线的修订版
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();
【讨论】:
但是,如果这只是一个跟踪哪个片段当前处于活动状态的问题,那么这是矫枉过正的。或者至少,fragmentState
是否必要?我不这么认为。毕竟,片段只有在它们处于活动状态时才会收到事件。
我希望我可以使用 otto。但我不能。
哦。太糟糕了。 LocalBroadcastManager
可以作为穷人的奥托。
请注意,Otto
在您发布活动的同一线程上提供活动。
在onPause()
中调用setPaused(true)
并在onPostCreate()
中调用setPaused(false)
【参考方案2】:
不要使用静态适配器。有更好(更安全)的方法可以从它的父级 Activity
访问您的片段。
我假设您使用以下方式动态添加片段:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager
.beginTransaction()
.add(R.id.fragment_container, new FragmentOne())
.commit();
片段二也一样。
为了引用那些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
就是这样
【讨论】:
我想知道getFragmentByTag("fragmentOneTag")
是否会比使用static
访问适配器更影响性能
refreshList()
不是静态的。 getFragmentByTag
返回对请求片段的引用,以便您可以访问它的公共方法【参考方案3】:
如果您只想更新片段列表,则不必访问 adpaters。您可以在 Fragment 上注册本地广播,并从 MainActivity 发送本地广播消息。
来自片段,
LocalBroadcastManager.getInstance(getContext()).registerReceiver(...);
来自 MainActivity,
LocalBroadcastManager.getInstance(getContext()).sendBroadcast(...)
【讨论】:
你为什么要这样做?所有Fragments
必须附加到一个Activity
,它首先创建并添加了Fragments
。所有Activity
所要做的就是在相关的Fragment
引用上调用public
方法。
@Benrad Kim 你是对的。一切都进入单一活动。我为什么要广播?【参考方案4】:
有没有办法在不将适配器设置为静态适配器的情况下访问活动中的片段列表适配器。
是的。 Fragments
的设计指南允许他们公开public
方法,这些方法可以从他们所附加的Activity
中调用。只需在每个 Fragment
中创建一个方法,然后调用您需要的任何一个。
Activity
应该持有对其创建的任何Fragments
的引用。只需让 Fragment
方法更新它们自己的适配器即可。
【讨论】:
以上是关于在活动中访问片段?的主要内容,如果未能解决你的问题,请参考以下文章