Migrating from java.lang.Observable to RxJava - java

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.

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

Related

I got the following error while pulling data from android studio Firebase

I could not understand the problem. It gave such an error when trying to pull the information from the Realtime Database or code.firebasteki to the screen, what is the problem?
Book
public class Book {
private String isim;
private String soyad;
private String numara;
public Book() {
}
public Book(String isim, String soyad, String numara) {
this.isim = isim;
this.soyad = soyad;
this.numara = numara;
}
public String getIsim() {
return isim;
}
public void setIsim(String isim) {
this.isim = isim;
}
public String getSoyad() {
return soyad;
}
public void setSoyad(String soyad) {
this.soyad = soyad;
}
public String getNumara() {
return numara;
}
public void setNumara(String numara) {
this.numara = numara;
}
MainActivity
public class MainActivity extends AppCompatActivity {
private RecyclerView mrecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mrecyclerView=(RecyclerView) findViewById(R.id.recyclerview_books);
new FirebaseDatabaseHelper().readBooks(new FirebaseDatabaseHelper.DataStatus() {
#Override
public void DataIsLoaded(List<Book> books, List<String> keys) {
new RecyclerView_Config().setConfig(mrecyclerView,MainActivity.this,books,keys);
}
#Override
public void DataIsInserted() {
}
#Override
public void DataIsUpdated() {
}
#Override
public void DataIsDeleted() {
}
});
}
RecyclerView_Config
public class RecyclerView_Config {
private Context mContext;
private BookAdapter mbookAdapter;
public void setConfig(RecyclerView recyclerView,Context context,List<Book> books,List<String>
keys){
mContext=context;
mbookAdapter=new BookAdapter(books,keys);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setAdapter(mbookAdapter);
}
class BookItemView extends RecyclerView.ViewHolder{
private TextView misim;
private TextView msoyad;
private TextView mnumara;
private String key;
public BookItemView(ViewGroup parent){
super(LayoutInflater.from(mContext).
inflate(R.layout.book_list_item,parent,false));
misim=(TextView) itemView.findViewById(R.id.isim_textView);
msoyad=(TextView) itemView.findViewById(R.id.soyad_textView);
mnumara=(TextView) itemView.findViewById(R.id.numara_textView);
}
public void bind(Book book,String key){
misim.setText(book.getIsim());
msoyad.setText(book.getSoyad());
mnumara.setText(book.getNumara());
this.key=key;
}
}
class BookAdapter extends RecyclerView.Adapter<BookItemView>{
private List<Book> mbookList;
private List<String> mkeys;
public BookAdapter(List<Book> mbookList, List<String> mkeys) {
this.mbookList = mbookList;
this.mkeys = mkeys;
}
#NonNull
#Override
public BookItemView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new BookItemView(parent);
}
#Override
public void onBindViewHolder(#NonNull BookItemView holder, int position) {
holder.bind(mbookList.get(position),mkeys.get(position));
}
#Override
public int getItemCount() {
return mbookList.size();
}
}
}
FirebaseDatabaseHelper
public class FirebaseDatabaseHelper {
private FirebaseDatabase mDatabase;
private DatabaseReference mReferenceBook;
private List<Book> books=new ArrayList<>();
public interface DataStatus{
void DataIsLoaded(List<Book> books,List<String> keys);
void DataIsInserted();
void DataIsUpdated();
void DataIsDeleted();
}
public FirebaseDatabaseHelper() {
mDatabase=FirebaseDatabase.getInstance();
mReferenceBook=mDatabase.getReference("Kullanicilar");
}
public void readBooks(final DataStatus dataStatus){
mReferenceBook.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
books.clear();
List<String> keys=new ArrayList<>();
for(DataSnapshot keyNode:snapshot.getChildren()){
keys.add(keyNode.getKey());
Book book=keyNode.getValue(Book.class);
books.add(book);
}
dataStatus.DataIsLoaded(books,keys);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
firebase
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.phonebook, PID: 14998
com.google.firebase.database.DatabaseException: Failed to convert value of type java.lang.Long to String
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertString(CustomClassMapper.java:426)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:217)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:179)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(CustomClassMapper.java:48)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:593)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:563)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
at com.example.phonebook.FirebaseDatabaseHelper$1.onDataChange(FirebaseDatabaseHelper.java:38)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
The field called numara is present in your Book class as a String while inside your database holds a number. That's the reason why you get that error. To solve this, simply change the declaration of your class like this:
public class Book {
private String isim;
private String soyad;
//👇
private long numara;
public Book() {
}
//👇
public Book(String isim, String soyad, long numara) {
this.isim = isim;
this.soyad = soyad;
this.numara = numara;
}
public String getIsim() {
return isim;
}
public void setIsim(String isim) {
this.isim = isim;
}
public String getSoyad() {
return soyad;
}
public void setSoyad(String soyad) {
this.soyad = soyad;
}
//👇
public long getNumara() {
return numara;
}
//👇
public void setNumara(long numara) {
this.numara = numara;
}
}

Waiting for two onChange to trigger with MediatorLiveData

I'm currently trying to learn how to use MediatorLiveData as described here:
https://developer.android.com/reference/androidx/lifecycle/MediatorLiveData
What I want to do is wait for two livedata object to get an update then do some logic on both.
So in my activity i currently got this. While this works I'm currently only getting Orders while i would like to wait for Orders AND Orderrows to finish and then make some change.
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button myButt;
private MainViewModel mvw;
private TextView myView;
private MediatorLiveData data;
#Override
protected void onCreate(Bundle savedInstanceState) {
mvw = new ViewModelProvider(this).get(MainViewModel.class);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myButt = findViewById(R.id.button);
myView = findViewById(R.id.textview);
myButt.setOnClickListener(this);
data = new MediatorLiveData<>();
data.addSource(mvw.getAllOrders(), new Observer<Orders>() {
#Override
public void onChanged(Orders orders) {
data.setValue(orders);
}
});
data.addSource(mvw.getAllOrderRows(), new Observer<OrderRows>() {
#Override
public void onChanged(OrderRows orderRows) {
data.setValue(orderRows);
}
});
data.observe(this, new Observer<Orders>() { //this observers Orders but how do i get orders AND orderrows?
#Override
public void onChanged(Orders order) {
myView.setText(mvw.extractDate(order));
//Here i want to manipulate order and orderrows
Log.i("livedata" , order.getOrders().toString());
}
});
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.button:
Log.i("button","clicked");
mvw.updateOrderData(); // calls for new values to be fetched
mvw.updateOrderRowData();
}
}
}
in my viewmodel:
public class MainViewModel extends ViewModel {
private GetOrder getOrderRepo;
private MutableLiveData<Orders> allOrders;
private MutableLiveData<OrderRows> allOrderRows;
public MainViewModel(){
getOrderRepo = new GetOrder();
}
public MutableLiveData<Orders> getAllOrders() {
if(allOrders == null){
allOrders = new MutableLiveData<>();
allOrders = getOrderRepo.getAllOrders();
}
return allOrders;
}
public MutableLiveData<OrderRows> getAllOrderRows() {
if(allOrderRows == null){
allOrderRows = new MutableLiveData<>();
allOrderRows = getOrderRepo.getAllOrderRows();
}
return allOrderRows;
}
public void updateOrderData(){
Log.i("updating","updating data");
Orders orders = getOrderRepo.getAllOrders().getValue();
allOrders.setValue(orders);
}
public void updateOrderRowData(){
Log.i("updating","updating data");
OrderRows orderRows = getOrderRepo.getAllOrderRows().getValue();
allOrderRows.setValue(orderRows);
}
public String extractDate(Orders orders){
ArrayList<Order> listOfOrders = orders.getOrders();
Log.i("extractDate", ""+(listOfOrders.size()-1));
String date = listOfOrders.get(listOfOrders.size()-1).getOrderTime();
return date;
}
}
In the repostiory.
public class GetOrder {
private ApiService mAPIService;
MutableLiveData<Orders> allOrders;
MutableLiveData<OrderRows> allOrderRows;
public GetOrder(){
mAPIService = ApiUtils.getAPIService();
allOrders = new MutableLiveData<Orders>();
allOrderRows = new MutableLiveData<OrderRows>();
}
public MutableLiveData<Orders> getAllOrders(){
Log.i("func","starting func");
mAPIService.getOrders().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Orders>() {
#Override
public void onCompleted() {
Log.i("func","onComplete");
}
#Override
public void onError(Throwable e) {
Log.i("onError",e.toString());
}
#Override
public void onNext(Orders orders) {
Log.i("Repo",orders.toString());
allOrders.setValue(orders);
}
});
return allOrders;
}
public MutableLiveData<OrderRows> getAllOrderRows(){
Log.i("func","starting func");
mAPIService.getOrderRows().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<OrderRows>() {
#Override
public void onCompleted() {
Log.i("func","onComplete");
}
#Override
public void onError(Throwable e) {
Log.i("onError",e.toString());
}
#Override
public void onNext(OrderRows orderRows) {
Log.i("Repo",orderRows.toString());
allOrderRows.setValue(orderRows);
}
});
return allOrderRows;
}
}

Retrofit response success but null result

Interface:
public interface BabService {
#GET("bab.php")
Call<Respon> tampil(#Query("imam") String imam);
}
Respon:
public class Respon {
private String value;
private List<BabResult> resultBab;
public String getValue() {
return value;
}
public List<BabResult> getResultBab() { return resultBab; }
}
Result:
public class BabResult {
private String id_bab;
private String id_kitab;
private String bab;
public String getId_bab() { return id_bab; }
public String getId_kitab() {
return id_kitab;
}
public String getBab() {
return bab;
}
}
Adapter:
public class BabAdapter extends RecyclerView.Adapter<BabAdapter.ViewHolder>
{
private Context context;
private List<BabResult> results;
private String idBab, judulBab;
private int no;
public BabAdapter(Context context, List<BabResult> results) {
this.context = context;
this.results = results;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_bab, parent, false);
ViewHolder holder = new ViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
if(position % 2 != 0){
holder.vBab.setBackgroundResource(R.color.ijo);
}else{
holder.vBab.setBackgroundResource(R.color.oren);
}
no = position + 1;
BabResult result = results.get(position);
idBab = result.getId_bab();
judulBab = result.getBab();
holder.tvNo.setText(no);
holder.tvBab.setText(judulBab);
}
#Override
public int getItemCount() {
if(results == null){
return 4;
}
return results.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private View vBab;
private TextView tvBab, tvNo;
public ViewHolder(View itemView) {
super(itemView);
vBab = (View) itemView.findViewById(R.id.v_bab);
tvNo = (TextView) itemView.findViewById(R.id.tv_no);
tvBab = (TextView) itemView.findViewById(R.id.tv_bab);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(context, HadisList.class);
i.putExtra("id", idBab);
i.putExtra("bab", judulBab);
i.putExtra("no", no);
context.startActivity(i);
}
});
}
}
}
Activity:
public class MenuBab extends AppCompatActivity {
public static final String URL = "http://mi3bpolinema.000webhostapp.com/";
private List<BabResult> results = new ArrayList<>();
private BabAdapter babAdapter;
private ProgressBar pbLoading;
private RecyclerView rvBab;
private TextView tvImam;
private String imam, namaImam;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu_bab);
if(getSupportActionBar() != null){
getSupportActionBar().hide();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
Intent intent = getIntent();
if(intent != null){
if(intent.getStringExtra("imam") != null){
imam = intent.getStringExtra("imam");
namaImam = intent.getStringExtra("nama");
}
}
pbLoading = (ProgressBar) findViewById(R.id.pb_loading);
rvBab = (RecyclerView) findViewById(R.id.rv_bab);
tvImam = (TextView) findViewById(R.id.tv_imam);
tvImam.setText(namaImam);
babAdapter = new BabAdapter(this, results);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
rvBab.setLayoutManager(mLayoutManager);
rvBab.setItemAnimator(new DefaultItemAnimator());
rvBab.setAdapter(babAdapter);
loadDataBab();
}
#Override
protected void onResume() {
super.onResume();
loadDataBab();
}
private void loadDataBab() {
Retrofit retrofit = new Retrofit
.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
BabService api = retrofit.create(BabService.class);
Call<Respon> call = api.tampil(imam);
call.enqueue(new Callback<Respon>() {
#Override
public void onResponse(Call<Respon> call, Response<Respon> response) {
String value = response.body().getValue();
pbLoading.setVisibility(View.GONE);
if (value.equals("1")) {
results = response.body().getResultBab();
babAdapter = new BabAdapter(MenuBab.this, results);
rvBab.setAdapter(babAdapter);
}
}
#Override
public void onFailure(Call<Respon> call, Throwable t) {
}
});
}
}
On retrofit get result null, but when I run in website get result like this:
{"value":1,"result":[{"id_bab":"4","id_kitab":"1","bab":"Wudhu"},
{"id_bab":"8","id_kitab":"1","bab":"Shalat"},
{"id_bab":"15","id_kitab":"1","bab":"Puasa"}]}
using this link.
You need to use Model class in this way
now you can get API Result
Response Model Class
import com.google.gson.annotations.SerializedName;
import java.io.Serializable;
import java.util.ArrayList;
public class Response implements Serializable{
#SerializedName("value")
private String value;
#SerializedName("result")
private ArrayList<BabResult> resultBab;
public String getValue() {
return value;
}
public ArrayList<BabResult> getResultBab() {
return resultBab;
}
public void setValue(String value) {
this.value = value;
}
public void setResultBab(ArrayList<BabResult> resultBab) {
this.resultBab = resultBab;
}
public class BabResult {
#SerializedName("id_bab")
private String id_bab;
#SerializedName("id_kitab")
private String id_kitab;
#SerializedName("bab")
private String bab;
public String getId_bab() {
return id_bab;
}
public void setId_bab(String id_bab) {
this.id_bab = id_bab;
}
public String getId_kitab() {
return id_kitab;
}
public void setId_kitab(String id_kitab) {
this.id_kitab = id_kitab;
}
public String getBab() {
return bab;
}
public void setBab(String bab) {
this.bab = bab;
}
}
}
Respon class
public class Respon
{
private ArrayList<Result> result;
private String value;
public ArrayList<Result> getResult ()
{
return result;
}
public void setResult ( ArrayList<Result> result)
{
this.result = result;
}
public String getValue ()
{
return value;
}
public void setValue (String value)
{
this.value = value;
}
#Override
public String toString()
{
return "ClassPojo [result = "+result+", value = "+value+"]";
}
public class Result
{
private String id_kitab;
private String bab;
private String id_bab;
public String getId_kitab ()
{
return id_kitab;
}
public void setId_kitab (String id_kitab)
{
this.id_kitab = id_kitab;
}
public String getBab ()
{
return bab;
}
public void setBab (String bab)
{
this.bab = bab;
}
public String getId_bab ()
{
return id_bab;
}
public void setId_bab (String id_bab)
{
this.id_bab = id_bab;
}
#Override
public String toString()
{
return "ClassPojo [id_kitab = "+id_kitab+", bab = "+bab+", id_bab =
"+id_bab+"]";
}
}
}
Check this way data null or not and add arraylist
private void loadDataBab() {
Retrofit retrofit = new Retrofit
.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
BabService api = retrofit.create(BabService.class);
Call<Respon> call = api.tampil(imam);
call.enqueue(new Callback<Respon>() {
#Override
public void onResponse(Call<Respon> call, Response<Respon> response) {
if (response.isSuccessful())
if (response.body() != null)
pbLoading.setVisibility(View.GONE);
if (response.body().getValue().equalsIgnoreCase("1")) {
results.addAll(response.body().getResult());
babAdapter = new BabAdapter(MenuBab.this, results);
rvBab.setAdapter(babAdapter);
}
}
#Override
public void onFailure(Call<Respon> call, Throwable t) {
}
});
}
Pass the array in your Respon class like this ..
public class Respon {
private String value;
private BabResult [] result;
public String getValue() {
return value;
}
public BabResult [] getResultBab() { return result; }
}
and in your loadDataBab method ..
private List<BabResult> results = new ArrayList<>();
private void loadDataBab() {
Retrofit retrofit = new Retrofit
.Builder()
.baseUrl(URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface api = retrofit.create(RequestInterface.class);
Call<Respon> call = api.tampil("1");
call.enqueue(new Callback<Respon>() {
#Override
public void onResponse(Call<Respon> call, Response<Respon> response) {
String value = response.body().getValue();
if (value.equals("1")) {
results = new ArrayList<>(Arrays.asList(response.body().getResultBab()));
}
}
#Override
public void onFailure(Call<Respon> call, Throwable t) {
}
});
}
I change Respon to :
public class Respon {
private String value;
private List<BabResult> result;
public String getValue() { return value; }
public List<BabResult> getResult() { return result; }
}
and it works. Thx :))

Adding Arraylist to custom object not updating values in android

In the below android activity, trying to display data in a view pager and it is working as expected.
But in loadItemsForSuppliers method, when i am adding SupplierAndItemList object to it's arraylist, value returned from getInventoriesByItemDetails method is not updating properly rather takes last value always.
Can some body assist me what's wrong here ?
public class ScreenSlidePagerActivity extends BaseActivity {
private ViewPager mPager;
private PagerAdapter mPagerAdapter;
private Dealer dealerObject;
private ArrayList<ItemDetail> itemDetails;
private List<Dealer> supplierList;
private ArrayList<SupplierAndItemList> supplierAndItemLists = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_slide);
dealerObject = getIntent().getParcelableExtra(UiConstants.DEALER_OBJECT);
itemDetails = getIntent().getParcelableArrayListExtra("itemDetails");
supplierList = dealerObject.getParentSalesPoints(this,dealerObject.getServerId());
loadItemsForSuppliers();
mPager = (ViewPager) findViewById(R.id.pager);
mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager(),supplierAndItemLists);
mPager.setAdapter(mPagerAdapter);
}
private void loadItemsForSuppliers() {
for (Dealer dealer : supplierList) {
ArrayList<ItemDetail> inventories = new ArrayList<>();
SupplierAndItemList supplierAndItem = new SupplierAndItemList();
supplierAndItem.setDealerName(dealer.getDealerName());
supplierAndItem.setSelectedItemList(getInventoriesByItemDetails(dealer, inventories));
supplierAndItemLists.add(supplierAndItem);
}
}
private ArrayList<ItemDetail> getInventoriesByItemDetails(Dealer dealer, ArrayList<ItemDetail> inventories) {
for (ItemDetail id : itemDetails) {
DealerInventory dealerInventory = new DealerInventory();
dealerInventory = dealerInventory.getLastModifiedInventory(this, id.getItemId(), dealer.getId());
if (dealerInventory != null) {
if (dealerInventory.getQuantity() >= 0) {
id.setParentSalesPointLastStock(String.valueOf(dealerInventory.getQuantity()));
id.setParentSalesPointLastStockTakingDate(dealerInventory.getStockTakingDate());
}
} else {
id.setParentSalesPointLastStock(UiConstants.NA);
id.setParentSalesPointLastStockTakingDate(UiConstants.NA);
}
inventories.add(id);
}
return inventories;
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
private final ArrayList<SupplierAndItemList> supplierAndItemList;
public ScreenSlidePagerAdapter(FragmentManager fm, ArrayList<SupplierAndItemList> supplierAndItemList) {
super(fm);
this.supplierAndItemList = supplierAndItemList;
}
#Override
public Fragment getItem(int position) {
SupplierAndItemList supplierAndItems = supplierAndItemList.get(position);
ScreenSlidePageFragment f = new ScreenSlidePageFragment();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("supplierAndItems",supplierAndItems.getSelectedItemList());
bundle.putString("supplierName",supplierAndItems.getDealerName());
f.setArguments(bundle);
return f;
}
#Override
public int getCount() {
return supplierAndItemList.size();
}
}
}
SupplierAndItemList class
public class SupplierAndItemList implements Parcelable {
public String dealerName;
public ArrayList<ItemDetail> selectedItemList;
public SupplierAndItemList() {
selectedItemList = new ArrayList<>();
}
public String getDealerName() {
return dealerName;
}
public void setDealerName(String dealerName) {
this.dealerName = dealerName;
}
public ArrayList<ItemDetail> getSelectedItemList() {
return selectedItemList;
}
public void setSelectedItemList(ArrayList<ItemDetail> itemList) {
this.selectedItemList = itemList;
}
protected SupplierAndItemList(Parcel in) {
dealerName = in.readString();
selectedItemList = in.readArrayList(ItemDetail.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(dealerName);
dest.writeList(selectedItemList);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<SupplierAndItemList> CREATOR = new Parcelable.Creator<SupplierAndItemList>() {
#Override
public SupplierAndItemList createFromParcel(Parcel in) {
return new SupplierAndItemList(in);
}
#Override
public SupplierAndItemList[] newArray(int size) {
return new SupplierAndItemList[size];
}
};
}
ItemDetail class
public class ItemDetail implements Parcelable {
public int itemId;
public String itemName;
public String salesPointLastStock;
public String salesPointLastStockTakingDate;
public String parentSalesPointLastStock;
public String parentSalesPointLastStockTakingDate;
public IDStockInput idStockInput;
public IDReturnInput idReturnInput;
public IDOrderInput idOrderInput;
public boolean isSelected;
public boolean isSelected() {
return isSelected;
}
public void setIsSelected(boolean isUpdated) {
this.isSelected = isUpdated;
}
public String getParentSalesPointLastStockTakingDate() {
return parentSalesPointLastStockTakingDate;
}
public void setParentSalesPointLastStockTakingDate(String parentSalesPointLastStockTakingDate) {
this.parentSalesPointLastStockTakingDate = parentSalesPointLastStockTakingDate;
}
public String getParentSalesPointLastStock() {
return parentSalesPointLastStock;
}
public void setParentSalesPointLastStock(String parentSalesPointLastStock) {
this.parentSalesPointLastStock = parentSalesPointLastStock;
}
#NonNull
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
#NonNull
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
#NonNull
public String getSalesPointLastStock() {
return salesPointLastStock;
}
public void setSalesPointLastStock(String salesPointLastStock) {
this.salesPointLastStock = salesPointLastStock;
}
#NonNull
public String getSalesPointLastStockTakingDate() {
return salesPointLastStockTakingDate;
}
public void setSalesPointLastStockTakingDate(String salesPointLastStockTakingDate) {
this.salesPointLastStockTakingDate = salesPointLastStockTakingDate;
}
public IDStockInput getIdStockInput() {
return idStockInput;
}
public void setIdStockInput(IDStockInput idStockInput) {
this.idStockInput = idStockInput;
}
public IDReturnInput getIdReturnInput() {
return idReturnInput;
}
public void setIdReturnInput(IDReturnInput idReturnInput) {
this.idReturnInput = idReturnInput;
}
public IDOrderInput getIdOrderInput() {
return idOrderInput;
}
public void setIdOrderInput(IDOrderInput idOrderInput) {
this.idOrderInput = idOrderInput;
}
public ItemDetail() {
idStockInput = new IDStockInput();
idReturnInput = new IDReturnInput();
idOrderInput = new IDOrderInput();
}
protected ItemDetail(Parcel in) {
itemId = in.readInt();
itemName = in.readString();
salesPointLastStock = in.readString();
salesPointLastStockTakingDate = in.readString();
parentSalesPointLastStock = in.readString();
parentSalesPointLastStockTakingDate = in.readString();
isSelected =in.readInt()==1;
idStockInput = (IDStockInput) in.readValue(IDStockInput.class.getClassLoader());
idReturnInput = (IDReturnInput) in.readValue(IDReturnInput.class.getClassLoader());
idOrderInput = (IDOrderInput) in.readValue(IDOrderInput.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(itemId);
dest.writeString(itemName);
dest.writeString(salesPointLastStock);
dest.writeString(salesPointLastStockTakingDate);
dest.writeString(parentSalesPointLastStock);
dest.writeString(parentSalesPointLastStockTakingDate);
dest.writeInt(isSelected ? 1 : 0);
dest.writeValue(idStockInput);
dest.writeValue(idReturnInput);
dest.writeValue(idOrderInput);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<ItemDetail> CREATOR = new Parcelable.Creator<ItemDetail>() {
#Override
public ItemDetail createFromParcel(Parcel in) {
return new ItemDetail(in);
}
#Override
public ItemDetail[] newArray(int size) {
return new ItemDetail[size];
}
};
}
I have go through your method I have found some assigning value issue
private void loadItemsForSuppliers() {
for (Dealer dealer : supplierList) {
ArrayList<ItemDetail> inventories = new ArrayList<>();
SupplierAndItemList supplierAndItem = new SupplierAndItemList();
supplierAndItem.setDealerName(dealer.getDealerName());
supplierAndItem.setSelectedItemList(getInventoriesByItemDetails(dealer, inventories));
supplierAndItemLists.add(supplierAndItem);
}
}
private ArrayList<ItemDetail> getInventoriesByItemDetails(Dealer dealer, ArrayList<ItemDetail> inventories) {
for (ItemDetail id : itemDetails) {
DealerInventory dealerInventory = new DealerInventory();
dealerInventory = dealerInventory.getLastModifiedInventory(this, id.getItemId(), dealer.getId());
if (dealerInventory != null) {
if (dealerInventory.getQuantity() >= 0) {
id.setParentSalesPointLastStock(String.valueOf(dealerInventory.getQuantity()));
id.setParentSalesPointLastStockTakingDate(dealerInventory.getStockTakingDate());
}
} else {
id.setParentSalesPointLastStock(UiConstants.NA);
id.setParentSalesPointLastStockTakingDate(UiConstants.NA);
}
inventories.add(id); // do this
}
return inventories; // you are not assigning value anywhere;
}
You are not assigning value to the inventories in getInventoriesByItemDetails. I think you should add item through inventories.add(id);
Check it , Hope this help
Set
mPager.setOffscreenPageLimit(1);

How to sort ArrayList while implementing Parcelable

I am trying to sort the category arraylist with Collections.sort method but have no luck with it.
Here is my code:
public class Categories implements Parcelable {
private ArrayList<Category> category;
private Recent recent;
public ArrayList<Category> getCategories() {
return this.category;
}
public void setCategory(ArrayList<Category> category) {
this.category = category;
}
public Recent getRecent() {
return this.recent;
}
public void setRecent(Recent recent) {
this.recent = recent;
}
protected Categories(Parcel in) {
if (in.readByte() == 0x01) {
category = new ArrayList<Category>();
in.readList(category, Category.class.getClassLoader());
} else {
category = null;
}
recent = (Recent) in.readValue(Recent.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
if (category == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeList(category);
}
dest.writeValue(recent);
}
public static final Parcelable.Creator<Categories> CREATOR = new Parcelable.Creator<Categories>() {
#Override
public Categories createFromParcel(Parcel in) {
return new Categories(in);
}
#Override
public Categories[] newArray(int size) {
return new Categories[size];
}
};
}
You can also use custom comparator:
public class CategoriesComparator implements Comparator<Category> {
#Override
public int compare(Category category1, Category category2) {
return category1.getSomeProperty().compareTo(category2.getSomeProperty());
}
}
When you want to compare call this:
Collections.sort(yourListCategories, new CategoriesComparator());
Hope it helps!
Collections.sort(yourListHere,new Comparator<Categories>() {
#Override
public int compare(Categories lhs, Categories rhs) {
//your sort logic here
return 0;
}
});
Hope this helps.

Categories