Reputation: 399
I'm working on an Android application that features a shopping cart. The Cart
object extends java.lang.Observable
so if there are any changes, they are saved to the disk immediately and also so that the badge icon can be updated.
public class Cart extends Observable{
private Set<Product> products;
public Cart(){
products = new HashSet<>();
}
public Cart(Collection<Product> products){
this.products = new HashSet<>(products);
}
public int getTotalItems() {
return products.size();
}
public void clear(){
products.clear();
setChanged();
notifyObservers();
}
public void addProduct(Product product){
products.add(product);
setChanged();
notifyObservers();
}
public void removeProduct(Product product){
products.remove(product);
setChanged();
notifyObservers();
}
public void updateProduct(Product product){
products.remove(product);
products.add(product);
setChanged();
notifyObservers();
}
public List<Product> getProducts() {
return new ArrayList<>(products);
}
}
Example usage
public class MainActivity extends BaseActivity implements Observer {
Cart mCart;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
getApp().getCart().addObserver(this);
setCartItemsCount(getApp().getCart().getTotalItems());
//...
}
@Override
protected void onDestroy() {
super.onDestroy();
if (getApp().getCart() != null) {
getApp().getCart().deleteObserver(this);
}
}
@Override
public void update(Observable observable, Object data) {
if (observable instanceof Cart) {
setCartItemsCount(((Cart) observable).getTotalItems());
}
}
}
I'd like to migrate this code to RxJava but i don't have a clear idea on how to go about it. From what I read, I'm supposed to use BehavioralSubject
but I don't know how to adapt the examples I've read to my scenario.
I would appreciate if some guidance or an example.
Upvotes: 0
Views: 254
Reputation: 410
I made some small example that can help you catch the idea. I have used this library https://github.com/trello/RxLifecycle, I also recommend you to use this http://google.github.io/dagger/
public class MainActivity extends RxActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CartPresenter cartPresenter = new CartPresenter();
final TextView counterTextView = (TextView) findViewById(R.id.counter);
final Button button = (Button) findViewById(R.id.button2);
RxView.clicks(button)
.subscribe(new Action1<Void>() {
@Override
public void call(Void aVoid) {
cartPresenter.getCardModel().addProduct(new Random().nextInt(100));
}
});
cartPresenter.getCardObservable()
.compose(this.<CartPresenter.CardModel>bindToLifecycle())
.subscribe(new Action1<CartPresenter.CardModel>() {
@Override
public void call(CartPresenter.CardModel cardModel) {
counterTextView.setText(String.valueOf(cardModel.getProducts().size()));
}
});
}
}
One solution simpler to understand for a beginner
public class CartPresenter {
private final PublishSubject<CardModel> dataChangedSubject = PublishSubject.create();
private final Observable<CardModel> cardObservable;
private final CardModel cardModel;
public CartPresenter() {
cardModel = new CardModel();
this.cardObservable = dataChangedSubject.startWith(cardModel)
.flatMap(new Func1<CardModel, Observable<CardModel>>() {
@Override
public Observable<CardModel> call(CardModel cardModel) {
return Observable.just(cardModel);
}
});
}
public CardModel getCardModel() {
return cardModel;
}
@NonNull
public Observable<CardModel> getCardObservable() {
return cardObservable;
}
class CardModel {
final private Set<Integer> products;
public CardModel() {
this.products = new HashSet<>();
}
public void addProduct(Integer integer) {
products.add(integer);
dataChangedSubject.onNext(this);
}
public Set<Integer> getProducts() {
return products;
}
}
}
And for some more advanced users
public class CartPresenter {
private final PublishSubject<CardModel> dataChangedSubject = PublishSubject.create();
private final Observable<CardModel> cardObservable;
private final CardModel cardModel;
public CartPresenter() {
cardModel = new CardModel();
this.cardObservable = Observable.just(cardModel)
.compose(new Observable.Transformer<CardModel, CardModel>() {
@Override
public Observable<CardModel> call(final Observable<CardModel> cardModelObservable) {
return dataChangedSubject.switchMap(new Func1<Object, Observable<? extends CardModel>>() {
@Override
public Observable<? extends CardModel> call(Object o) {
return cardModelObservable;
}
});
}
});
}
public CardModel getCardModel() {
return cardModel;
}
@NonNull
public Observable<CardModel> getCardObservable() {
return cardObservable;
}
class CardModel {
final private Set<Integer> products;
public CardModel() {
this.products = new HashSet<>();
}
public void addProduct(Integer integer) {
products.add(integer);
dataChangedSubject.onNext(null);
}
public Set<Integer> getProducts() {
return products;
}
}
}
Upvotes: 1