Not notify Fragment when remote Realm (on Realm Object Server) was changed - android

When I start Android app I login to Realm Object Server and download (sync) data from Realm Server Object.
OK.
Now I got to Fragment that show list of persons.
Here code:
public class PersonsFragment extends Fragment {
private ListView notEmptytsListView;
private Realm realm;
private RealmResults<Person> personsRealmResults;
private PersonsAdapter personsAdapter; // RealmBaseAdapter<Organization>
private RealmChangeListener realmChangeListener;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.persons_fragment, container, false);
init(rootView);
return rootView;
}
private void init(View view) {
realm = Realm.getDefaultInstance();
notEmptytsListView = (ListView) view.findViewById(R.id.notEmptytsListView);
personsRealmResults = realm.where(Person.class).findAllSorted(Person.NAME);
personsAdapter = new PersonsAdapter(personsRealmResults);
notEmptytsListView.setAdapter(personsAdapter);
// NOT CALL WHEN DATA ON REALM OBJECT SERVER WAS CHANGED
realmChangeListener = new RealmChangeListener() {
#Override
public void onChange(Object object) {
personsAdapter.notifyDataSetChanged();
}
};
personsRealmResults.addChangeListener(realmChangeListener);
}
#Override
public void onDestroy() {
super.onDestroy();
realm.removeChangeListener(realmChangeListener);
realm.close();
}
}
If I stay on Fragment and data changed on Realm Object Server (remote Realm) the local data is not sync. Not call method onChanged().
How I can fix this?

public class MyFragment extends Fragment {
RealmResults<Person> personsRealmResults; // <--
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.persons_fragment, container, false);
notEmptytsListView = (ListView) view.findViewById(R.id.notEmptytsListView);
realm = Realm.getDefaultInstance();
personsRealmResults = realm.where(Person.class).findAllSorted(Person.NAME);
personsAdapter = new PersonsAdapter(personsRealmResults);
notEmptytsListView.setAdapter(personsAdapter);
realmChangeListener = new RealmChangeListener() {
#Override
public void onChange(Object object) {
// call when data on Realm Object Server was changed
}
};
personsRealmResults.addChangeListener(realmChangeListener);
return rootView;
}
#Override
public void onDestroyView() {
super.onDestroyView();
realm.removeChangeListener(realmChangeListener);
realm.close();
}
}
Although it'd probably be easier if PersonsAdapter was a RealmBaseAdapter. (see docs)

Related

Callback with two methods is not working between NonActivity class and a Fragment

I have created a callback via interface with two methods. The callback is between a NonActivity class and a Fragment. The problem is that only one interface method invisible is being called. And the other interface method visible is not called. I have copied the code of interface and both classes. MY OBJECTIVE IS THAT BOTH CALLBACK METHODS INVISIBLE() AND VISIBLE() SHOULD BE CALLED AT DIFFERENT TIMES WHEN TRIGGERED. I am somewhat confused about not getting the particular functionality.
public interface MyCustomListener {
void invisible();
void visible();
}
The NonActivity class code is as follows:
public class Operations {
private Context context;
private RecyclerView recyclerView;
private RecyclerView.Adapter adapter;
private MyCustomListener listener;
public void setMyCustomListener(MyCustomListener listener) {
this.listener = listener;
}
public Operations(Context context, RecyclerView recyclerView) {
this.context = context;
this.recyclerView = recyclerView;
}
public void getView(int number) {
Perform pa = new Perform(context);
Long count = pa.count(number);
if (count > 0) {
ArrayList arrayList = pa.getAllList(number);
adapter = new AdapterMovie(context, arrayList, recyclerView, number);
recyclerView.setAdapter(adapter);
if (listener != null)
listener.invisible();
}
else if (count < 1) {
recyclerView.setAdapter(null);
if (listener != null)
listener.visible();
}
}
}
The Fragment class code is as follows:
public class Frag extends Fragment {
private int fragmentNumber = 0;
private Operations fo;
private RecyclerView recyclerView;
private TextView message;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag, container, false);
fo = new Operations(getActivity(), recyclerView);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
fo.setMyCustomListener(new MyCustomListener() {
#Override
public void invisible() {
Toast.makeText(getActivity(), "invisible", Toast.LENGTH_SHORT).show();
}
#Override
public void visible() {
Toast.makeText(getActivity(), "visible", Toast.LENGTH_SHORT).show();
}
});
}
}
If you want get callback in fragment, you should implements your fragment from MyCustomListener. then you pass fragment to constructor of Operations.
fragment such as below:
public class Frag extends Fragment implements MysCustomListener{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag, container, false);
fo = new Operations(this, recyclerView);
return view;
}
#override
void invisible(){
}
#override
void visible(){
}
}

How to calling Firestore Database in Fragment using FirebaseUi?

So I'm gonna calling my database from Firestore using Recycler View with FirebaseUi in my fragment but somehow every time I opened my app, the app stop working.
Here's my Fragment Contains Firestore Database.
public class Fragment_HomeSpot extends Fragment {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference spotRef = db.collection("Spot");
private SpotAdapter adapter;
#SuppressLint("ResourceType")
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.id.recyclerview_layout,container,false);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setUpRecyclerView();
}
private void setUpRecyclerView() {
Query query = spotRef.orderBy("",Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Spot> options = new FirestoreRecyclerOptions.Builder<Spot>()
.setQuery(query, Spot.class)
.build();
adapter = new SpotAdapter(options);
RecyclerView recyclerView = Objects.requireNonNull(getView()).findViewById(R.id.recyclerview_layout);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
onCreate() happens before onCreateView(), so when you call getView() in setUpRecyclerView(), you get null back - you haven't inflated the view yet.
Instead, you should put your setUpRecyclerView() method within onViewCreated(), at which time getView() will return the view you inflated in onCreateView():
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
setUpRecyclerView();
}

unable to retrieve data from Firebase using Fragments in Android Studio

Hy! I am trying to retrieve data from Firebase but unable to show the pictures and names of categories on the fragment layout. I can't understand whether its Firebase error or Layout error because on selecting fragment imageview or textview are also not been shown. This is the code from categories fragment in which recyclerview is used in fragment layout XML file.
public class CategoriesFragment extends Fragment {
View myfragment;
RecyclerView listCategory;
RecyclerView.LayoutManager layoutManager;
FirebaseRecyclerAdapter<Category,CategoryViewHolder> adapter;
FirebaseDatabase database;
DatabaseReference categories;
public static CategoriesFragment newInstance(){
CategoriesFragment categoriesFragment = new CategoriesFragment();
return categoriesFragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = FirebaseDatabase.getInstance();
categories = database.getReference("Category");
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
myfragment = inflater.inflate(R.layout.fragment_categories,container,false);
listCategory = (RecyclerView)myfragment.findViewById(R.id.listcategory);
listCategory.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(container.getContext());
listCategory.setLayoutManager(layoutManager);
loadCategories();
return myfragment;
}
private void loadCategories() {
adapter = new FirebaseRecyclerAdapter<Category, CategoryViewHolder>(
Category.class,
R.layout.category_layout,
CategoryViewHolder.class,
categories
) {
#Override
protected void populateViewHolder(CategoryViewHolder viewHolder, final Category model, int position) {
viewHolder.category_name.setText(model.getName());
Picasso.with(getActivity())
.load(model.getImage())
.into(viewHolder.category_image);
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Toast.makeText(getActivity(),String.format("%s|%s",adapter.getRef(position).getKey(),model.getName()),Toast.LENGTH_LONG).show();
}
});
}
};
adapter.notifyDataSetChanged();
listCategory.setAdapter(adapter);
}`

Displaying data getting fetched asynchronously in a RecyclerView in Fragment

I am trying to load the data list asynchronously and showing it on RecyclerView in fragments. However, the same implementation works for Activity class but fails for Fragment:
public class ItemThreeFragment extends Fragment {
String email;
private CompositeSubscription mSubscriptions;
HistoryAdapter historyAdapter;
RecyclerView recyclerView;
public static ItemThreeFragment newInstance() {
ItemThreeFragment fragment = new ItemThreeFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
email = ((BaseApplication) getActivity().getApplication()).getEmail();
mSubscriptions = new CompositeSubscription();
getUserHistory(email);
}
private void getUserHistory(String email) {
mSubscriptions.add(NetworkUtil.generic().getUserCheckinInfo(email)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::handleCheckInInfoResponse,this::handleError));
}
private void handleCheckInInfoResponse(List<Checkin> checkins) {
System.out.println(checkins);
historyAdapter = new HistoryAdapter(this.getActivity(), checkins);
recyclerView.setAdapter(historyAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
private void handleError(Throwable throwable) {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_three, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.historyList);
return rootView;
}
}
Any kind of suggestions will be highly appreciated.
try to set the adapter in onCreateView() instead of onCreate.
Check for data
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(historyAdapter);
Use these two lines onCreateView after you have fetched the data.

How to wait until Callback has data?

I'm trying to use Retrofit and OkHttp to make request to a server. I have the next class "AutomaticRequest.java" which has a request to get videos from a server.
public class AutomaticRequest {
public void getVideos(final AutomaticCallback callback){
MediaproApiInterface service = ApiClient.getClient();
Call<List<AutomaticVideo>> call = service.getAllVideos();
call.enqueue(new Callback<List<AutomaticVideo>>() {
#Override
public void onResponse(Call<List<AutomaticVideo>> call, Response<List<AutomaticVideo>> response) {
List<AutomaticVideo> automaticVideoList = response.body();
callback.onSuccessGettingVideos(automaticVideoList);
}
#Override
public void onFailure(Call<List<AutomaticVideo>> call, Throwable t) {
callback.onError();
}
});
}
}
I've created the next class "AutomaticCallback.java" to retrieve data.
public interface AutomaticCallback {
void onSuccessGettingVideos(List<AutomaticVideo> automaticVideoList);
void onError();
}
I'm calling the request from a fragment like the next way:
public class AllVideosFragment extends Fragment {
...
AutomaticCallback callback;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_allvideos, container, false);
new AutomaticRequest().getVideos(callback);
return view;
}
...
}
How I can wait until the callback has data to update the UI?? Thank you.
Just implement the AutomaticCallback interface on your fragment like:
public class AllVideosFragment extends Fragment implements AutomaticCallback {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_allvideos, container, false);
new AutomaticRequest().getVideos(this);
return view;
}
#Override
void onSuccessGettingVideos(List<AutomaticVideo> automaticVideoList){
// use your data here
}
#Override
void onError(){
// handle the error
}
}

Categories

Resources