Как использовать один интерфейс в нескольких классах в Java?

У меня есть одно действие и 2 фрагмента.

Я хочу, когда в действии срабатывает listener.receivePreview(obj), затем

  1. выполнить: OneFragment -> ReceivePreview.
  2. выполнить: 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) {

    }
}

person Ahmad Aghazadeh    schedule 27.05.2016    source источник
comment
Можете ли вы объяснить немного яснее, чего именно вы хотите достичь? Кроме того, если вам нужен единый интерфейс, почему вы реализуете его в обоих фрагментах?   -  person Abdul Fatir    schedule 27.05.2016
comment
Попробуйте библиотеку событий greenrobots andreas -schrade.de/2015/11/28/   -  person akhil Rao    schedule 27.05.2016


Ответы (3)


Я думаю, что вы можете использовать шаблон наблюдателя, который является хорошей практикой в ​​вашей ситуации.

Как описано GoF:

Определите зависимость «один ко многим» между объектами, чтобы при изменении состояния одного объекта все его зависимые объекты уведомлялись и обновлялись автоматически.

Подробнее читайте на http://www.java2blog.com/2013/02/observer-design-pattern-in-java.html#TLio7G2ruqxvfZUR.99

В вашей ситуации у вас есть такое отношение (один ко многим), и когда в действии произошло событие, вы хотите знать, что два фрагмента.

введите здесь описание изображения

Фрагменты реализуют класс наблюдателя, и ваша активность играет роль субъекта, как показано на рисунке выше.

Я надеюсь, что это может помочь вам очень красиво реализовать свой код. некоторые учебники можно найти по следующим ссылкам:

https://dzone.com/articles/observer-pattern-java http://www.tutorialspoint.com/design_pattern/observer_pattern.htm

Изменить: в данной ситуации:

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

Фрагмент имеет правильное определение с этим шаблоном проектирования, поэтому я не меняю их код:

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

}

вам нужно иметь ссылки на фрагменты в действии (как наблюдатель).

ArrayList< OnReceiveListener > observers =  new ArrayList< OnReceiveListener>();

действительно, наблюдатель может подписаться или зарегистрироваться в теме (фрагмент содержит ссылку на действие (лучше использовать шаблон singleton!: D). Вот так:

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)
person Sir1    schedule 27.05.2016
comment
Я согласен с вашей оценкой, может быть полезно привести пример того, как это можно использовать в данной ситуации. - person cyroxis; 27.05.2016
comment
Я согласен с вами, я думаю, что шаблоны проектирования — это концепция, которую следует использовать в соответствующей ситуации. но сначала нам нужно узнать, что такое шаблон проектирования и почему мы собираемся его использовать. в этой ситуации это достаточно ясно, но я отредактирую свой ответ, чтобы привести правильный пример. - person Sir1; 27.05.2016
comment
@ahmadaghazadeh Горбанат :)) - person Sir1; 27.05.2016
comment
Спасибо. Пожалуйста, посмотрите мое решение. - person Ahmad Aghazadeh; 27.05.2016

Я использую ответ Sirvan Paraste. Кажется, это полезное решение.

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

        }
    }
person Ahmad Aghazadeh    schedule 27.05.2016

Попробуйте создать одну функцию в каждом фрагменте, которая возвращает экземпляр интерфейса

public OnReceiveListener getListener() {
    mListener = this;
    return mListener
}

и в вашей деятельности, когда вы вызываете метод, напишите следующий код

fragmentInstance.getListener().receivePreview();
person mdDroid    schedule 27.05.2016