How to use one interface in multiple class in java

2020-07-22 18:23发布

问题:

I have one activity and 2 fragment.

I want when in activity fire listener.receivePreview(obj) then

  1. execute : OneFragment -> receivePreview .
  2. 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) {

    }
}

回答1:

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)


回答2:

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) {

        }
    }


回答3:

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