I understand there are a lot of information about it out there, but I haven't found one that matches my case yet.
I have a recycleview on a fragment that is always open, so the fragment basically never re-creates itself.
This is my code to load the adapter.
reLoad(); //method shown below
mRecycler.setAdapter(new SolicitationAdapter(myRealm.where(SolicitationDatabase.class).findAllAsync()));
And this is the logic I came up with:
public void reLoad() {
if (!myRealm.where(SolicitationDatabase.class).findAll().isEmpty()) {
mNothingHere.setVisibility(View.GONE);
mRecycler.setVisibility(View.VISIBLE);
} else {
mNothingHere.setVisibility(View.VISIBLE);
mRecycler.setVisibility(View.GONE);
}
}
It works great the first time the user opens the app.
The trouble starts when the user creates a record, since the fragment doesn't re-create itself it never reloads.
The reason I haven't been able to reload after user adds something is because the method to add a new record is on a singleton being called from a different activity. Which means when I try to do it I get a nullpointerexception when declaring the the recycleview and the textview.
I have a class called PostHelper, this class is in charge of posting a new record.
This is the constructor:
public PostHelper(Context context, Activity activity) {
this.mContext = context;
this.mActivity = activity; //I call this in order to use "findViewById"
This is where the post happens:
public String addSolicitation(File _file, boolean fromQueue) {
//loading view
TextView nothingHere = (TextView) mActivity.findViewById(R.id.nothing_here);
RecyclerView recycler = (RecyclerView) mActivity.findViewById(R.id.recycler);
...so on until after the post:
SolicitationAdapter n = new SolicitationAdapter(myRealm.where(SolicitationDatabase.class).findAll());
n.notifyDataSetChanged();
nothingHere.setVisibility(View.GONE);
recycler.setVisibility(View.VISIBLE);
And this is the stacktrace:
06-01 21:43:37.511 9122-9122/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.ga.realm3, PID: 9122
io.reactivex.exceptions.OnErrorNotImplementedException: Attempt to invoke virtual method 'void android.widget.TextView.setVisibility(int)' on a null object reference
mPostHelper = new PostHelper(this, PostSolicitationActivity.this);
You're supposed to make sure that SolicitationAdapter
is a RealmRecyclerViewAdapter
, like so:
public class SolicitationAdapter extends RealmRecyclerViewAdapter<SolicitationDatabase, SolicitationViewHolder> {
public SolicitationAdapter(OrderedRealmCollection<SolicitationDatabase> results) {
super(results, true);
}
...
}
And then what you need to do is that you put the RealmResults as a field reference in your Activity:
public class PostSoliticiationActivity extends AppCompatActivity {
RealmResults<Solicitation> results;
Realm realm;
RealmChangeListener<RealmResults<Solicitiation> realmChangeListener = (results) -> {
if(results.isLoaded() && results.isValid()) {
if(results.isEmpty()) {
mNothingHere.setVisibility(View.GONE);
mRecycler.setVisibility(View.VISIBLE);
} else {
mNothingHere.setVisibility(View.VISIBLE);
mRecycler.setVisibility(View.GONE);
}
}
}
SolicitationAdapter adapter;
@Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.soliticiation_activity);
// bind views
realm = Realm.getDefaultInstance();
results = realm.where(SolicitationDatabase.class).findAllSortedAsync("id");
// .sort("id").findAllAsync(); in 4.3.0+
results.addChangeListener(realmChangeListener);
adapter = new SoliticiationAdapter(results);
mRecycler.setAdapter(adapter);
// layout manager as well
}
@Override
public void onDestroy() {
results.removeChangeListener(realmChangeListener);
realm.close();
super.onDestroy();
}
}
So things you don't need:
1.) reLoad()
method
2.) onPostAdded
callback
3.) PostActionListener
As long as you just add the SoliticiationDatabase
to the Realm in a transaction, it'll all work without manually syncing ui.