2015-06-07 5 views
3

наблюдаемых Мой вопрос является Каков наилучший способ для адаптера, чтобы подписаться на несколько наблюдаемыхадаптер Подписавшись на несколько

У меня есть адаптер, который имеет заголовок и регулярные типы элементов. Информация для адаптера поступает из базы данных с использованием Sqlbrite. Используя Sqlbrite, я хочу обновить заголовок и список, подписав адаптер на наблюдаемый.

Не проблема для первого наблюдаемого. В OnResume моего фрагмента:

mSubscription = TrackerDbUtils.getListSubmissionObservable(db) 
      .map(Submission.MAP) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(mAdapter); 

Тем не менее, я затем попытаться добавить второй Observable к фрагменту

mHeaderSubscription = TrackerDbUtils.getSummaryObservable(db) 
      .map(Summary.MAP) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .subscribe(mAdapter); 

Итак, мне нужно реализовать ДЕЙСТВИЙ1 в моем адаптере:

public class MileageTrackerAdapter extends HeaderRecyclerViewAdapter 
    implements Action1<List<Submission>>, Action1<Summary> { 
    . 
    . 
    . 

} 

Однако я получаю дублируемую ошибку класса. Так что я пытался реализовать обобщенный тип:

public class MileageTrackerAdapter extends HeaderRecyclerViewAdapter 
    implements Action1<Object> { 
    . 
    . 
    . 
    @Override 
    public void call(Object o) { 
     if(o instanceof Summary){ 
       // Logic 
     } else { 
       // Logic 
     } 
    } 
} 

Но я получаю сообщение об ошибке выполнения, что я не в состоянии Карты Резюме для представления. Даже тогда я не уверен, что отличное обобщение - лучший подход к проблеме.

На основе обратной связи от dwursteisen:

Я изменил мое резюме класс для сопоставления представления. Я также создал новое поле под названием «isSummary». Я изменил свое наблюдение на следующее, как было предложено:

TrackerDbUtils.getListSubmissionObservable(db) 
    .map(Submission.MAP) 
    .mergeWith(TrackerDbUtils.getSummaryObservable(db) 
           .map(Summary.MAP)) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(mAdapter); 

Это создает Наблюдаемое, которое будет стрелять дважды; один раз для массового списка заявок, а другой - как Список с размером 1. Этот список на самом деле является сводкой. В моем адаптере:

@Override 
public void call(List<Submission> mSubmissions) { 

    if(mSubmissions.size() == 1 && mSubmissions.get(0).isSummary()){ 
     mSummary = mSubmissions.get(0); 
    } else { 
     mArray = new ArrayList<>(mSubmissions); 
    } 

    notifyDataSetChanged(); 

} 

ответ

2

Вам следует избегать использования одного и того же адаптера для двух разных потоков, так как это будет иметь дело с одновременной проблемой, что вы можете избежать использования RxJava.

Почему бы не попытаться объединить потоки в один, а затем использовать только один адаптер?

TrackerDbUtils.getListSubmissionObservable(db) 
     .map(Submission.MAP) 
     .mergeWith(TrackerDbUtils.getSummaryObservable(db) 
            .map(Summary.MAP)) 
     .subscribeOn(Schedulers.io()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(mAdapter); 

Вам может понадобиться карта List<Submission> и Summary одному и тому же общему типу, или иметь дело с объектом в адаптер

+0

Не могли бы вы подробнее остановиться на попутной вопрос? Я новичок в RxJava, поэтому у меня сложилось впечатление, что подписка на несколько наблюдаемых была перком RxJava. Разве это не так? – Tykin

+0

Метод onNext вашего абонента/наблюдателя может вызываться одновременно с тем, что наблюдаемые наблюдатели могут наблюдать один и тот же подписчик/наблюдатель в разных контекстах потока. – dwursteisen

1

Может кто-то даст лучший ответ, но в подобных ситуациях, я обычно создаю публичный окончательный анонимный экземпляр этих интерфейсов. Таким образом, код выглядит примерно так:

public class Adapter extends HeaderRecyclerViewAdapter { 

    public final Action1<Summary> summary = new Action1<Summary> { ... } 
    public final Action1<List<Submission>> submissions = new Action1<List<Submission>> { ... } 

} 

Таким образом, методы внутри обеих реализаций ДЕЙСТВИЙ1 могут получить доступ все в классе адаптера, как если бы они были нормальными методами, и я могу различить между ними, в то же время с помощью mAdapter .summary или mAdapter.submissions

Смежные вопросы