2015-06-14 2 views
1

Я начинаю изучать RxJava. У меня есть массив Views, который я хочу установить OnClickListener каждому из них, используя ViewObservable.clicks(). Реализация OnClickListener вызовет только метод, который зависит от положения представления в массиве (например: populate(viewPositionInTheArray)).Получение индекса элемента из наблюдаемого

императив раствор, будет это одна:

for (int i = 0; i < views.length; i++) { 
    final int finalI = i; 
    view[i].setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      populate(finalI); 
     } 
    }); 
} 

Для того, чтобы сделать это с помощью RxJava, я думаю, мне нужно сделать какой-то поток цепочки. Тем не менее, я понятия не имею, какие функции я должен использовать в элегантном, FRP-способе делать это. Какие-либо предложения?

Благодаря

+0

не уверен, что я вас понимаю. Если вы ищете позицию представления, я не вижу, как это относится к Rx? – njzk2

+0

ваше решение не будет работать, потому что 'i' не является окончательным и не может использоваться в onClick. Вам нужен способ получить индекс из представления. Как правило, помещаем его в тег. 'view [i] .setTag (i)' then' .map (view -> (Integer) view.getTag()). map (this :: populate) 'или' .map (view -> populate ((Integer) view.getTag())) '(это использует retrolambda для выполнения). – njzk2

+0

Уверен, что это не сработает, я просто набрал его прямо здесь, на SO, чтобы проиллюстрировать, о чем я думал. Использование тегов - хорошая идея, но ваш ответ подсказывает, что мне придется проходить через массив, чтобы установить тег в любом случае. Я ищу решение (не уверен, если возможно, хотя), чтобы избежать любой итерации. –

ответ

1

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

Observable.range(0,views.length) 
       .subscribe(new Action1<Integer>() { 
      @Override 
      public void call(Integer integer) { 
       views[index].setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         populate(index); 
        } 
       }); 
      } 
     }); 
1

Это может работать:

private void gotTheList() { 
    for (int i = 0; i < mViews.length; i++) { 
     setClick(mViews[i], i); 
    } 
} 

private void setClick(View item, int index) { 
    ViewObservable.clicks(item) 
      .subscribe(onClickEvent -> { 
       populate(index); 
      }); 
} 

private void populate(int index) { 
    // do something on mViews[index] 
} 
Смежные вопросы