对象到片段通信
Object to Fragment Communication
我可能错过了接口的概念,因为出于某种原因,这似乎让我难以理解。这是我的场景:
期望的结果
我想要一个非片段/非activity Java class Routines.java
当后台线程在Routines.java
完成。
当前行为
我目前从 Routines.java
内部通过广播 FragmentA
已注册并正在侦听的意图与 FragmentA
通信。虽然这个解决方案有效,但我不禁觉得这不是正确的做法。
问题
我想知道是否可以实现一个接口以便我可以摆脱广播意图,或者通常是否有更好的方式从 non-fragment/activity classes 进行通信至 fragments/activities.
实现从片段到 activity 的接口的解决方案不是我正在寻找的,因为我已经知道该怎么做,但如果通信的一侧我似乎无法让它工作不是 activity 或片段。
我试过的
//in Routines.java
public class Routines implements FragmentA.OnRoutineFinishedListener
public void finished(int position){
...
}
//in FragmentA
public interface OnRoutineFinishedListener {
public void finished(int position);
}
我的主要问题是,当我不能使用像这样的 onAttach(Activity activity){ ... set up callback here by casting activity as the interface}
方法的典型方法时,我不确定如何调用这些方法:
public void onAttach(Activity activity){
super.onAttach(activity);
try {
mCallback = (SomeFragment.SomeListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement SomeListener");
}
}
当它是 activity 的片段时,上面的代码使 mCallback
对我可用,这样我就可以自由调用实现方法,但我没有那么奢侈,因为我正在尝试获得触发片段内函数的非片段。
始终是问题是如何实际触发 Routines
最终触发 FragmentA
中的 finished
方法的条件。如果能帮助我理解如何实现这一点,我将不胜感激。
你看过观察者模式了吗?我认为这是可行的方法。
祝你好运。
看一个例子here
如您所见,您可以将它用于一个或多个观察者。
在片段上调用代码的最简单方法是保存对片段的引用。仅仅因为你的对象不是 activity 并不意味着你不能将 Fragment 引用传递给 Routines 对象,只是要小心,不要因为持有引用的时间超过你需要的时间而浪费内存。
FragmentA fragment = (FragmentA) getFragmentManager().findFragmentById(R.id.example_fragment);
fragment.finished(myInt);
Calling a Fragment method from a parent Activity
您是否考虑过使用事件总线系统 ala otto?
您可以 post 在您的 Routines.java class
中举办活动
bus.post(new FinishedEvent(position));
然后你可以在你的片段中订阅接收事件
bus.register(this);
@Subscribe public void OnRoutineFinished(FinishedEvent event) {
// TODO: React to the event somehow!
}
在查看@gatunox 的建议("observer pattern")后,我对该模式进行了一些研究,发现它确实可以满足我的需要。我喜欢可以通知多个对象状态更改的想法。我实施了以下措施来实现我的目标:
片段A
public class FragmentA extends Fragment implements Observer{
...
@Override
public void update(Observable observable, Object data) {
Logging.log("FragmentA observed the following from Routines: "+data);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
routines = new Routines(getActivity().getApplicationContext());
((MainActivity)getActivity()).actionObserver.addObserver(this);
Routines.java
((MyApp)appContext).actionObserver.updateStatus("Routine finished!!");
ActionObserver.java
public class ActionObserver extends Observable {
public void updateStatus(String message){
setChanged();
notifyObservers(message);
}
}
MainActivity.java
MyApp bApp = (MyApp) getApplication();
actionObserver = bApp.getObserver();
现在当 Routines.java
执行那行时 FragmentA
的 update
方法被触发。
我相信你应该有不同的想法。让我们先问谁启动后台任务工作?如果片段是调用者,那么 interface/listener 方法将像 :
//inside fragment
Routines.doTaskInbackground(new TaskListener(){
onComplete(){ // task completed }
//do your work here
});
//inside routines
public static void doTaskInbackground(TaskListener listener){
//on complete
listener.onComplete();
}
您还可以使用线程和处理程序通过将处理程序传递给 class 例程并在 class post 消息中传递给此处理程序来执行此操作。
如果片段不是启动后台任务的部分,并且您没有来自片段的实例或侦听器或 activity 将其保存在例程 class 中,那么广播意图应该没问题.
我可能错过了接口的概念,因为出于某种原因,这似乎让我难以理解。这是我的场景:
期望的结果
我想要一个非片段/非activity Java class Routines.java
当后台线程在Routines.java
完成。
当前行为
我目前从 Routines.java
内部通过广播 FragmentA
已注册并正在侦听的意图与 FragmentA
通信。虽然这个解决方案有效,但我不禁觉得这不是正确的做法。
问题
我想知道是否可以实现一个接口以便我可以摆脱广播意图,或者通常是否有更好的方式从 non-fragment/activity classes 进行通信至 fragments/activities.
实现从片段到 activity 的接口的解决方案不是我正在寻找的,因为我已经知道该怎么做,但如果通信的一侧我似乎无法让它工作不是 activity 或片段。
我试过的
//in Routines.java
public class Routines implements FragmentA.OnRoutineFinishedListener
public void finished(int position){
...
}
//in FragmentA
public interface OnRoutineFinishedListener {
public void finished(int position);
}
我的主要问题是,当我不能使用像这样的 onAttach(Activity activity){ ... set up callback here by casting activity as the interface}
方法的典型方法时,我不确定如何调用这些方法:
public void onAttach(Activity activity){
super.onAttach(activity);
try {
mCallback = (SomeFragment.SomeListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement SomeListener");
}
}
当它是 activity 的片段时,上面的代码使 mCallback
对我可用,这样我就可以自由调用实现方法,但我没有那么奢侈,因为我正在尝试获得触发片段内函数的非片段。
始终是问题是如何实际触发 Routines
最终触发 FragmentA
中的 finished
方法的条件。如果能帮助我理解如何实现这一点,我将不胜感激。
你看过观察者模式了吗?我认为这是可行的方法。 祝你好运。
看一个例子here
如您所见,您可以将它用于一个或多个观察者。
在片段上调用代码的最简单方法是保存对片段的引用。仅仅因为你的对象不是 activity 并不意味着你不能将 Fragment 引用传递给 Routines 对象,只是要小心,不要因为持有引用的时间超过你需要的时间而浪费内存。
FragmentA fragment = (FragmentA) getFragmentManager().findFragmentById(R.id.example_fragment);
fragment.finished(myInt);
Calling a Fragment method from a parent Activity
您是否考虑过使用事件总线系统 ala otto?
您可以 post 在您的 Routines.java class
中举办活动bus.post(new FinishedEvent(position));
然后你可以在你的片段中订阅接收事件
bus.register(this);
@Subscribe public void OnRoutineFinished(FinishedEvent event) {
// TODO: React to the event somehow!
}
在查看@gatunox 的建议("observer pattern")后,我对该模式进行了一些研究,发现它确实可以满足我的需要。我喜欢可以通知多个对象状态更改的想法。我实施了以下措施来实现我的目标:
片段A
public class FragmentA extends Fragment implements Observer{
...
@Override
public void update(Observable observable, Object data) {
Logging.log("FragmentA observed the following from Routines: "+data);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
routines = new Routines(getActivity().getApplicationContext());
((MainActivity)getActivity()).actionObserver.addObserver(this);
Routines.java
((MyApp)appContext).actionObserver.updateStatus("Routine finished!!");
ActionObserver.java
public class ActionObserver extends Observable {
public void updateStatus(String message){
setChanged();
notifyObservers(message);
}
}
MainActivity.java
MyApp bApp = (MyApp) getApplication();
actionObserver = bApp.getObserver();
现在当 Routines.java
执行那行时 FragmentA
的 update
方法被触发。
我相信你应该有不同的想法。让我们先问谁启动后台任务工作?如果片段是调用者,那么 interface/listener 方法将像 :
//inside fragment
Routines.doTaskInbackground(new TaskListener(){
onComplete(){ // task completed }
//do your work here
});
//inside routines
public static void doTaskInbackground(TaskListener listener){
//on complete
listener.onComplete();
}
您还可以使用线程和处理程序通过将处理程序传递给 class 例程并在 class post 消息中传递给此处理程序来执行此操作。
如果片段不是启动后台任务的部分,并且您没有来自片段的实例或侦听器或 activity 将其保存在例程 class 中,那么广播意图应该没问题.