I have one activity and 2 fragment.
I want when in activity fire listener.receivePreview(obj)
then
- execute : OneFragment -> receivePreview .
- execute : TwoFragment -> receivePreview .
public class MainAct extends AppCompatActivity {
public interface OnReceiveListener {
// This can be any number of events to be sent to the activity
void receivePreview(Object... obj);
}
private OnReceiveListener listener;
}
public class OneFragment extends Fragment implements OnReceiveListener{
@Override
public void receivePreview(Object... obj) {
}
}
public class TwoFragment extends Fragment implements OnReceiveListener{
@Override
public void receivePreview(Object... obj) {
}
}
I think you can use Observer Pattern that is a good practice in you situation.
As described by GoF:
"Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically".
Read more at http://www.java2blog.com/2013/02/observer-design-pattern-in-java.html#TLio7G2ruqxvfZUR.99
In your situation you have such relation (one-to-many) and when an event occurred in the activity you want to aware that two fragment.
Fragments are implement observer class and your activity has the role of subject as illustrate in above figure.
I hope this could help you to implements your code in a very nice way.
some tutorial can be find in the following links :
https://dzone.com/articles/observer-pattern-java
http://www.tutorialspoint.com/design_pattern/observer_pattern.htm
Edit: in the given situation:
public interface OnReceiveListener { // this is your observer interface !
// This can be any number of events to be sent to the activity
void receivePreview(Object... obj);
}
Fragment are in correct definition with this design pattern so I do not change their code :
public class OneFragment extends Fragment implements OnReceiveListener{
@Override
public void receivePreview(Object... obj) {
}
}
public class TwoFragment extends Fragment implements OnReceiveListener{
@Override
public void receivePreview(Object... obj) {
}
you need to have references to the fragments in the activity (as observer).
ArrayList< OnReceiveListener > observers = new ArrayList< OnReceiveListener>();
indeed an observer can subscribe or register itself to a subject ( fragment hold a reference to the activity (better to use singleton pattern ! :D). like this :
public class MainAct extends AppCompatActivity {
private static MainAct instance;
public static MainAct getInstance() {
if(instance != null)
return instance;
}
// I think it is better to create the instance variable in the onCreate() method of the MainAct activity
onCreate(...)
{
.
.
.
instance = this;
...
}
public void registerObserver(OnReceiveListener observer){
observers.add(observer)
}
/* To avoid memory leaks, remember to unregister receivers when no longer observing */
public void unregisterObserver(OnReceiveListener observer) {
observers.remove(observer);
}
notifyObservers(){
// call this method in the listener you want
for( Observer obser : observers)
obser. receivePreview(param )
}
...
//in fragment initialization:
MainAct.getInstance().registerObserver(this)
I use answer Sirvan Paraste.It seems that this useful solution.
public class MainAct extends AppCompatActivity {
static List<OnReceiveListener> onReceiveList = new ArrayList<OnReceiveListener>();
public void attachOnReceiveListener(OnReceiveListener listener) {
if (!onReceiveList.contains(listener)) {
onReceiveList.add(listener);
}
}
public interface OnReceiveListener {
// This can be any number of events to be sent to the activity
void receivePreview(Object... obj);
}
public onReceivePreview(Object... obj) {
for (OnReceiveListener listener : onReceiveList) {
listener.receivePreview(obj);
}
}
}
public class OneFragment extends Fragment implements OnReceiveListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainAct mainAct = new MainAct();
mainAct.attachOnReceiveListener(this);
}
@Override
public void receivePreview(Object... obj) {
}
}
public class TwoFragment extends Fragment implements OnReceiveListener{
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainAct mainAct = new MainAct();
mainAct.attachOnReceiveListener(this);
}
@Override
public void receivePreview(Object... obj) {
}
}
Try to create one function in each fragment which returns the interface instance
public OnReceiveListener getListener() {
mListener = this;
return mListener
}
and in your activity when you call the method write following code
fragmentInstance.getListener().receivePreview();