Общение между фрагментами на Android

Я пытаюсь создать приложение для Android с двумя вкладками: одну для текстового поля/кнопки и TreeMenu (где у каждого элемента есть связанный с ним флажок), а другую для списка. Я также использую ActionBarSherlock. Я уже успешно написал программу в одном основном действии, но мне трудно понять, как разделить это исходное действие, чтобы оно соответствовало двум новым экземплярам фрагмента, которые мне нужно создать для каждой вкладки. Более того, каждый раз, когда элемент добавляется на первую вкладку (независимо от того, был ли он отмечен или добавлен в текстовое поле), список во втором окне должен распознавать обновление.

Чтобы построить панель действий, я могу сделать это...

ActionBar actionbar = getSupportActionBar();
actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionbar.setTitle("AppName");

Чтобы создать вкладки..

 ActionBar.Tab Frag1Tab = actionbar.newTab().setText("InputTab");
 ActionBar.Tab Frag2Tab = actionbar.newTab().setText("ListTab");

Чтобы создать фрагменты и их слушателей, лежащих в основе каждой вкладки...

Fragment Fragment1 = new Fragment_1();
Fragment Fragment2 = new Fragment_2();
Frag1Tab.setTabListener(new MyTabsListener(Fragment1));
Frag2Tab.setTabListener(new MyTabsListener(Fragment2));

Чтобы добавить их на панель действий...

actionbar.addTab(Frag1Tab);
actionbar.addTab(Frag2Tab);

Все это появляется в моем MainActivity. Я хочу, например, чтобы переменная ArrayList была доступна для обоих фрагментов, поэтому, как я уже сказал, я могу обновить список. Я хотел бы услышать любую помощь, которую вы можете предоставить. Мне было бы интересно посмотреть, как Otto API может работать для чего-то подобного, но я не привередлив!


person NumenorForLife    schedule 11.06.2013    source источник


Ответы (5)


Одноэлементный класс может помочь решить вашу проблему.

public class GlobalApp {
    private static GlobalApp instance = new GlobalApp();

    private GlobalApp() {}

    public static GlobalApp getInstance() {
        return instance;
    }

    public ArrayList < ClassName > varName = new ArrayList < ClassName > ();

}

Затем используйте в своем классе вот так..

GlobalApp.getInstance().varName
person Thalaivar    schedule 11.06.2013

В некоторых ответах есть предложение поместить ArrayList в синглтон, но это на самом деле не решает вашу проблему, не так ли? Конечно, вы сможете получить к нему доступ откуда угодно, но это не поможет вам синхронизировать два разных фрагмента, использующих arraylist.

Начните с помещения ArrayList в синглтон, как было предложено, или в MainActivity. Как только это будет сделано, у вас есть как минимум два варианта синхронизации фрагментов с содержимым ArrayList:

  1. Сделайте ArrayList доступным для наблюдения (отметьте ObservableArrayList) и пусть фрагменты Наблюдайте за изменениями в ArrayList.

  2. Используйте шину событий (например, Otto) и позвольте singleton или MainActivity (в зависимости от того, где вы поместите ArrayList) публикуют события обновления на шине при изменении массива и подписывают фрагменты на эти события.

person britzl    schedule 11.06.2013
comment
Отто выглядит стоящим, но я его, к сожалению, пока не смог освоить. Спасибо за предложение, хотя - person NumenorForLife; 14.06.2013
comment
Тебе действительно стоит попробовать Отто. И если у вас проблемы с Отто, задайте еще вопрос. Для запуска и запуска требуется всего несколько строк кода. - person britzl; 14.06.2013

Недавно у меня была такая же проблема с ArrayList и другими данными. В конце концов я решил создать класс, который расширяет приложение и содержит все глобальные данные, и к которому можно получить доступ из любого места приложения. Хочешь и пример?

person john    schedule 11.06.2013
comment
Да, пожалуйста, я был бы очень признателен. - person NumenorForLife; 11.06.2013

Как сказал Джон, если вы хотите получить доступ к данным в нескольких действиях, просто создайте класс, расширяющий Application:

import android.app.Application;

/**
 * Application class used to share data between activities.
 * @author Longeanie Christophe
 *
 */

public class MyApplication extends Application {


    //Put your class members here

    @Override
    public void onCreate() {
        //initialize what's needed here
    }

    //Getters and setters...
}

Во всех своих действиях вы можете получить доступ к этому классу и его данным с помощью этой инструкции:

MyApplication myApp = (MyApplication) getApplication();
person Christophe Longeanie    schedule 11.06.2013
comment
У меня сложилось впечатление, что я использую одно основное действие и четыре фрагмента. Должен ли каждый фрагмент иметь свою собственную активность? - person NumenorForLife; 11.06.2013
comment
Это зависит от ситуации, но в целом, если нет связи... тогда каждое действие будет содержать фрагмент. - person Thalaivar; 12.06.2013

Вот и все: сначала убедитесь, что вы объявили это в своем AndroidManifest:

<application
 android:name="com.example.main.ApplicationClass" 
 etc..>

<!-- other activities, services etc: -->

</application>

и ваш класс:

public class ApplicationClass extends Application {
private static ApplicationClass THIS = null;
ArrayList<String> list = new ArrayList<String>();

public void onCreate() {
  super.onCreate();

  THIS = this;
}

public static ApplicationClass getThisInstance() {
    return THIS;
}
}
person john    schedule 11.06.2013