Reputation: 2349
I'm trying to have a listview linked with a Realm table, so when a item is added to the table, the listview should be updated. The problem is that RealmChangeListener is not called when the item is added.
Realm real = RealmController.getInstance(getContext()); // Singleton
RealmResults<Friend> friends = real.where(Friend.class).findAllAsync();
friends.addChangeListener(callback);
RealmChangeListener<RealmResults<Friend>> callback=new RealmChangeListener<RealmResults<Friend>>() {
@Override
public void onChange(RealmResults<Friend> element) {
// This is only called on async completed but not later
}
};
The saving process is done in a retrotif response:
new MyService(context).userService().getFriends().enqueue(new Callback<FriendResponse>() {
@Override
public void onResponse(Call<FriendResponse> call, Response<FriendResponse> response) {
Realm realm = RealmController.getInstance(context); // singleton
realm.beginTransaction();
realm.copyToRealmOrUpdate(response.body().friends);
realm.commitTransaction();
}
@Override
public void onFailure(Call<AllInfoResponse> call, Throwable t) {
}
});
Do you know what is happening? Any suggestion?
Upvotes: 3
Views: 724
Reputation: 3909
I have experienced some issues with your exact situation (Retrofit call and UI refreshed via RealmChangeListener) and I was about to post a new question but I just figured it out.
In my case, I implemented the RealmChangeListener
inside my ArrayAdapter
, which I find cleaner:
public class ListAdapter extends ArrayAdapter<Item> implements
RealmChangeListener<RealmResults<Item>> {
private final List<Item> items;
public ListAdapter(Context context, RealmResults<Item> items) {
super(context, R.layout.listitem_item);
this.items = items;
items.addChangeListener(this);
}
@Override
public void onChange(RealmResults<Restaurant> element) {
notifyDataSetChanged();
}
...
}
In another situation, I was initialising the views and calling my Retrofit
service in the activity's onCreate
and somehow the listener was not being attached before receiving the response. So, another thing I did was calling Retrofit
in the onPostCreate
method, ensuring the listener is ready.
public class ItemListActivity BaseActivity implements
RealmChangeListener<RealmResults<Item>>,
Callback<GetItemsResponse> {
private long id;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_list);
RealmResults<Item> items = getRealm()
.where(Item.class)
.findAll();
items.addChangeListener(this);
setupUI(items);
}
@Override
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
MyRetrofitClient
.getInstance(this)
.getItems()
.enqueue(this);
}
@Override
public void onResponse(Call<GetItemsResponse> call, final Response<GetItemsResponse> response) {
getRealm().executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
List<Item> newItems = response.body().getNewItems();
realm.copyToRealmOrUpdate(newItems);
}
});
}
@Override
public void onChange(RealmResults<Item> items) {
updateUI();
}
...
}
Hope any of this helps!
Upvotes: 1