Get Data with Retrofit and Sugar ORM (make bookmark button) - java

Hello everyone I am doing a news app for university and I have kind of problem with displaying saved data to another activity. Im using retrofit to get data from internet and Sugar ORM to save data localy. So, news are displaying great and I created a CardView where it has a button "Read Later". The method to save data into database s working (at least on log it shows that it is working) but I cant get saved data to read_later activity. Alos I have an Adapter which contains onBindViewHolder.
#Override
public void onBindViewHolder(#NonNull MainArticalAdapter.ViewHolder viewHolder, int position) {
final Article articleModel = articleArrayList.get(position);
if(!TextUtils.isEmpty(articleModel.getTitle())){
viewHolder.titleText.setText(articleModel.getTitle());
}
if(!TextUtils.isEmpty(articleModel.getDescription())) {
viewHolder.descriptionText.setText(articleModel.getDescription());
}
if(!TextUtils.isEmpty(articleModel.getUrlToImage())){
Picasso.get().load(articleModel.getUrlToImage())
.resize(700,500)
.centerInside()
.into(viewHolder.imgView);
}
viewHolder.artilceAdapterParentLinear.setTag(articleModel);
Button btn = viewHolder.btn_read_later;
btn.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
Article art = new Article();
art.setAuthor("Harun Shaban");
art.save();
}
}
);
}
and viewholder which extends RecyclerView.ViewHolder
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView titleText, descriptionText;
private LinearLayout artilceAdapterParentLinear;
private ImageView imgView;
private Button btn_read_later;
public ViewHolder(#NonNull View view) {
super(view);
btn_read_later = view.findViewById(R.id.button_read_later);
imgView = view.findViewById(R.id.article_adapter_image_view);
titleText = view.findViewById(R.id.article_adapter_tv_title);
descriptionText = view.findViewById(R.id.article_adapter_tv_description);
artilceAdapterParentLinear = view.findViewById(R.id.article_adapter_ll_parent);
artilceAdapterParentLinear.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
if(onRecyclerViewItemClickListener != null){
onRecyclerViewItemClickListener.onItemClick(getAdapterPosition(),view);
}
}
}
);
}
}
and this is in my MainActivity class which contains a method to display all data received from internet by retrofit
private void showData(){
// Second step to create the recycler view to show the data taken
final RecyclerView mainRecycler = findViewById(R.id.activity_main_tv);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mainRecycler.setLayoutManager(linearLayoutManager);
// First step to create the response
final APIInterface apiService = ApiClient.getClient().create(APIInterface.class);
Call<ResponeModel> call = apiService.getLatestNews("techcrunch", API_KEY);
//third step
call.enqueue(new Callback<ResponeModel>() {
#Override
public void onResponse(Call<ResponeModel> call, Response<ResponeModel> response) {
if(response.body().getStatus().equals("ok")){
List<Article> articleList = response.body().getArticles();
if(articleList.size()>0){
final MainArticalAdapter mainArticalAdapter = new MainArticalAdapter(articleList);
mainArticalAdapter.setOnRecyclerViewItemClickListener(MainActivity.this);
mainRecycler.setAdapter(mainArticalAdapter);
}
}
}
#Override
public void onFailure(Call<ResponeModel> call, Throwable t) {
Log.e("on Fail", t.toString());
}
});
}
I tried to work with same logic in Read_later_Activity but it crashes.
This is my Read_later_activity…
public void getDatafromDB() {
List <Article> savedArticles = Article.listAll(Article.class);
final RecyclerView read_later_recView = findViewById(R.id.activity_read_later_tv);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
read_later_recView.setLayoutManager(linearLayoutManager);
if(savedArticles.size()>0){
final MainArticalAdapter mainArticalAdapter = new MainArticalAdapter(savedArticles);
mainArticalAdapter.setOnRecyclerViewItemClickListener((OnRecyclerViewItemClickListener) ReadLaterActivity.this);
read_later_recView.setAdapter(mainArticalAdapter);
//to retrieve the data from DB, by id (crashes)
//Article art = Article.findById(Article.class, 0);
//titleText_readLater.setText(art.getTitle());
/*Don`t know what to do*/
}
}

Related

How to implement Pagination in RecyclerView with retrofit?

I have api call request with parameters: (page,pageSize:the maximum number of items desired(default 25,Maximum 100.From reddit api documentation)),and i want to use pagination in RecyclerView.My data is loading successfully but the problem how do i request to server for the next page.How i can perform pagination with method addOnScrollListener
WebService Class
public interface RedditWebService {
#GET("top.json")
Observable<Response> getTopPublication(#Query("count")int count,
#Query("limit")int pageSize);
}
Adapter Class
public class RedditAdapter extends RecyclerView.Adapter<RedditAdapter.RedditViewHolder> {
private List<Child> childList;
private Context context;
public RedditAdapter(Context context, List<Response.Data.Child> childList) {
this.childList = childList;
this.context = context;
}
#NonNull
#Override
public RedditViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_layout, parent, false);
return new RedditViewHolder(view);
}
#SuppressLint("DefaultLocale")
#Override
public void onBindViewHolder(#NonNull RedditViewHolder holder, int position) {
final Child child = childList.get(position);
holder.txtAuthor.setText(child.getmData().getmAuthor());
String timeAgo = TimeAgo.getTimeAgo(child.getmData().getmCreated());
Log.d("Time", "" + timeAgo);
holder.txtDate.setText(timeAgo);
holder.txtComment.setText(String.format("Comments: %d", child.getmData().getmNumComments()));
Picasso.get().load(child.getmData().getmThumbnail()).placeholder(R.drawable.placeholder).
transform(ImageTransformation.getTransformation(holder.imageView)).into(holder.imageView);
if (!child.getmData().getmThumbnail().equals("")) {
holder.imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context.getApplicationContext(), SecondActivity.class);
intent.putExtra("extraImage", child.getmData().getmThumbnail());
context.startActivity(intent);
}
});
}
}
#Override
public int getItemCount() {
return (childList == null) ? 0 : childList.size();
}
public class RedditViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView;
private TextView txtDate, txtAuthor, txtComment;
public RedditViewHolder(#NonNull View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.image_view);
txtDate = itemView.findViewById(R.id.txt_date);
txtAuthor = itemView.findViewById(R.id.txt_author);
txtComment = itemView.findViewById(R.id.txt_comments_num);
}
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private ProgressBar progressBar;
private RedditAdapter adapter;
private List<Child> redditList = new ArrayList<>();
private CompositeDisposable disposable = new CompositeDisposable();
private int page = 0;
private int pageSize = 50;
#Inject
RedditWebService webService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((BaseApplication) getApplication()).getComponent().inject(this);
setContentView(R.layout.activity_main);
progressBar = findViewById(R.id.progress_bar);
recyclerView = findViewById(R.id.recycler_view);
layoutManager = new LinearLayoutManager(this);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
fetchData();
}
private void fetchData() {
progressBar.setVisibility(View.VISIBLE);
disposable.add(webService.getTopPublication(page,pageSize)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<Response>() {
#Override
public void accept(Response response) throws Exception {
adapter = new RedditAdapter(MainActivity.this, response.getData().getChildren());
recyclerView.setAdapter(adapter);
progressBar.setVisibility(View.GONE);
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(MainActivity.this, throwable.toString(), Toast.LENGTH_LONG).show();
}
}));
}
Thanks in advance
Use EndlessRecyclerViewScrollListener.java, it will provide very easy way to do load more call.
Maintain one global variable "page" initialize by 1, and increase it by 1 on every API call or load more call.
EndlessRecyclerViewScrollListener scrollListener = new EndlessRecyclerViewScrollListener(linearLayoutManager) {
#Override
public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
// Triggered only when new data needs to be appended to the list
// Add whatever code is needed to append new items to the bottom of the list
page++;
loadMoreCall(page);
}
};
inside loadMoreCall() you need to add your api call, and after successfull api call, you need to set data to your list and then you need to notify your adaper. thats it only.
reference: https://guides.codepath.com/android/endless-scrolling-with-adapterviews-and-recyclerview
here how to call, api using retrofit:
https://demonuts.com/android-recyclerview-retrofit/
Consider using the new paging library. Here's a sample and the documentation. It performs better and you don't have to manually keep track where you are in the scrolling. By following the sample I found it fairly easy to implement this, although it is a lot of boilerplate code.

Can I have one recycleview that loads different datasets

I am working on mobile app which is for books.
I have recyclerview that has all categories - Romance, History etc.This RV is taking the data from Firebase.
What I want to do is following:
When the user clicks on Romance for example, a new activity needs to be opened. In that activity I want to have one RV loading the data-set with all books from that type.
Then, If the user opens History I want that data-set to be loaded into the same RV.
I want to avoid code repeating and what I am asking is - can I have 1 class with If statements that can handle the user choice and load the data-sets into one RV?
Would you be able to tell me how, if its possible?
Thank you !
Edit: Here is my code. What I did so far is Adapter, GetAndSet class, 2 Activities. To show categories into one RV I use 1 adapter and 1 GetAndSet class,1 XML file. I created 2 separate classes for romance and Comedy and inside them I do the connection to firebase.
Adapter:
public class CategoriesAdapter extends RecyclerView.Adapter {
Context mContext;
List<Categories> mData;
public CategoriesAdapter(Context mContext, List<Categories> mData) {
this.mContext = mContext;
this.mData = mData;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View row = LayoutInflater.from( mContext ).inflate( R.layout.row_attractions, parent, false );
return new MyViewHolder( row );
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.DesName.setText( mData.get( position ).getName() );
Glide.with( mContext ).load( mData.get( position ).getImage() ).into( holder.DesImage );
}
#Override
public int getItemCount() {
return mData.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView DesName;
ImageView DesImage;
public MyViewHolder(#NonNull View itemView) {
super( itemView );
itemView.setClickable( true );
mContext = itemView.getContext();
DesName = itemView.findViewById( R.id.DesName );
DesImage = itemView.findViewById( R.id.DesImage );
DesImage.setOnClickListener( this );
}
#Override
public void onClick(View v) {
final Intent intent;
Toast.makeText(itemView.getContext(),"Test",Toast.LENGTH_LONG ).show();
switch (getAdapterPosition()) {
case 0:
intent = new Intent( mContext, Romance.class );
break;
case 1:
intent = new Intent( mContext, Comedy.class );
break;
// case 2:
// intent = new Intent( mContext, RegentsPark.class );
// break;
default:
intent = new Intent( mContext, Home.class );
break;
}
mContext.startActivity( intent );
}
}
}
Romance class (Same as Comedy class,except the line with Firebase where I reffer to the dataset:
public class Romance extends AppCompatActivity {
RecyclerView categoriesRecyclerView ;
CategoriesAdapter categoriesAdapter ;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference ;
List<Categories> categoriesList;
private EditText mSearchField;
private ImageButton mSearchBtn;
private RecyclerView mResultList;
private DatabaseReference mUserDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_romance);
categoriesRecyclerView = findViewById(R.id.BookRV);
categoriesRecyclerView.setLayoutManager(new LinearLayoutManager(Romance.this));
categoriesRecyclerView.setHasFixedSize(true);
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference("ListParks");
// mUserDatabase = FirebaseDatabase.getInstance().getReference("Categories");
mSearchField = (EditText) findViewById(R.id.search_field);
mSearchBtn = (ImageButton) findViewById(R.id.search_btn);
mResultList = (RecyclerView) findViewById(R.id.result_list);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
mSearchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String searchText = mSearchField.getText().toString();
firebaseUserSearch(searchText);
}
});
}
private void firebaseUserSearch(String searchText) {
Toast.makeText(Romance.this, "Started Search", Toast.LENGTH_LONG).show();
Query firebaseSearchQuery = mUserDatabase.orderByChild("name").startAt(searchText).endAt(searchText + "\uf8ff");
FirebaseRecyclerAdapter<Users, UsersViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Users, UsersViewHolder>(
Users.class,
R.layout.list_layout,
UsersViewHolder.class,
firebaseSearchQuery
) {
#Override
protected void populateViewHolder(UsersViewHolder viewHolder, Users model, int position) {
viewHolder.setDetails(getApplicationContext(), model.getName(), model.getImage());
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
// View Holder Class
public static class UsersViewHolder extends RecyclerView.ViewHolder {
View mView;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(Context ctx, String userName, String userImage){
TextView user_name = (TextView) mView.findViewById(R.id.name_text);
ImageView user_image = (ImageView) mView.findViewById(R.id.profile_image);
user_name.setText(userName);
Glide.with(ctx).load(userImage).into(user_image);
}
}
#Override
protected void onStart() {
super.onStart();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
categoriesList = new ArrayList<>();
for (DataSnapshot catsnap: dataSnapshot.getChildren()) {
Categories post = catsnap.getValue(Categories.class);
categoriesList.add(post) ;
}
//set Adapter
categoriesAdapter = new CategoriesAdapter(Romance.this,categoriesList);
categoriesRecyclerView.setAdapter(categoriesAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Can I avoid creating different classes for each type of books?
If you want to know what category the user selected on the first RecyclerView:
Pass the category name/identifier to the activity you want to open when user clicks on the RecyclerView item. And then from the second activity get your data-set object according to the category you got from the previous activity and pass it to the adapter.
You can make a custom RecyclerView.Adapter.
Here is a good example:
Android Developers Documentation Example
When the adapter is initiated, you pass the data-set. This is the constructor of your custom RecyclerView.Adapter class:
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
So every time you create the activity which is listing the books, you can create new RecyclerView.Adapter instance passing your data-set.
Put this somewhere in your onCreate method of the activity:
MyAdapter myAdapter = new MyAdapter(myDataset);
recyclerView.setAdapter(myAdapter);
When your activity is created, your RecyclerView will be loaded with the new data-set you provided the RecyclerView.Adapter with.
P.S.
If you are actually resuming the activity and have never destroyed it and want to change the adapter of already existing RecyclerView and refresh new items, you can do this in your onResume method
MyAdapter myAdapter = new MyAdapter(myDataset);
recyclerView.setAdapter(myAdapter);
myAdapter.notifyDataSetChanged();
Another way would be, again, if you are resuming (not creating) the activity and really don't want to create new Adapter and set it every time the activity resumes, then you will have to edit manually the data-set object you passed earlier to your custom adapter and call:
myAdapter.notifyDataSetChanged();
By saying edit I don't mean reassigning the variable! If you reassign the variable with another object, the adapter will loose the reference to that object and it will not work.

RecyclerView Not Showing Items on Second Click

I have a RecyclerView that I am using to display a list that I obtain from making a request to remote api. The list is shown on the first time that the activity appears but when I go back and come back to activity again, the list doesn't show. How can I solve this?
This is the activity that I call the recyclerview.
public class DisplayMessage extends AppCompatActivity {
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.language_selection);
recyclerView = (RecyclerView) findViewById(R.id.recylerview);
LanguageAdapter languageAdapter = new LanguageAdapter(this);
recyclerView.setAdapter(languageAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
}
}
This is the Adapter class.
public class LanguageAdapter extends RecyclerView.Adapter<LanguageAdapter.MyViewHolder> {
ArrayList<Language> languageArrayList;
public LanguageAdapter(Context context) {
this.languageArrayList = new ArrayList<Language>();
RequestQueue queue = Volley.newRequestQueue(context);
String url ="https://api.bounswe2019group9.tk/contents/languages";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray data = (JSONArray) response.get("data");
for(int i=0; i<data.length();i++){
Language lang = new Language((String) data.get(i));
languageArrayList.add(lang);
Log.i("api", ""+lang.getLanguageName());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("language_selection", "Error on request to get language list");
}
});
queue.add(jsonObjectRequest);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.languages, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.languageName.setText(languageArrayList.get(position).getLanguageName());
}
#Override
public int getItemCount() {
return languageArrayList.size();
}
class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView languageName;
public RelativeLayout relativeLayout;
public MyViewHolder(View itemView) {
super(itemView);
this.languageName = (TextView) itemView.findViewById(R.id.language);
this.relativeLayout = (RelativeLayout) itemView.findViewById(R.id.relativeLayout);
}
#Override
public void onClick(View v) {
}
}
}
OnCreate() method gets called only once when activity is created. You have set the adapter with the language list in OnCreate() and that it why it gets set only at the first time. When you reenter on the same screen then OnCreate won't get called again.
You have to set the adapter in the OnResume() method because this method will get called every time when you visit this screen.
In your Activity class, override an onResume method, and inside that also declare the following codes-
LanguageAdapter languageAdapter = new LanguageAdapter(this);
recyclerView.setAdapter(languageAdapter);
This is probably too late. But I had this problem as well. For me, the problem was my data binding. I used a custom delegation function to bind my views after they were inflated.
The problem was solved when I changed my delegation to inflate the view instead of binding the current inflated view.

How to dismiss a dialog fragment from a recyclerview adapter

A silly question but I am new to Android and I’ve spent a few hours looking around but can’t find the answer.
I have a dialog fragment with a recyclerview in it. I want the dialog to close when the user clicks a recyclerview item. How do I call dismiss() from the listener in recyclerview adapter?
I've tried a listener for the recyclerview in the dialog fragment but it does nothing. please help.
This is the dialog fragment. At the bottom onClick dismisses it:
public class EvMySchedDlg extends DialogFragment implements View.OnClickListener {
View view;
String eventId;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.event_my_sched, container, false);
ImageView closeButton = view.findViewById(R.id.closeButton3);
closeButton.setOnClickListener(this);
final TextView eventNameBox = view.findViewById(R.id.eventNameBox);
eventNameBox.setOnClickListener(this);
TextView coNameBox = view.findViewById(R.id.coNameBox);
Bundle extraData = getArguments();
eventId = extraData.getString("eventId");
String coName = extraData.getString("coName");
String eventName = extraData.getString("eventName");
coNameBox.setText(coName);
eventNameBox.setText(eventName);
//get list of days from server
String userId = ((DrawerActivity)getContext()).getUserData("userId");
final String[] cred = new String[]{"user_id", userId, "event_id", eventId};
VolleyCalls.postRequest(this.getContext(), "getEventDays", cred, new VolleyCalls.ServerReply() {
#Override
public void onSuccess(String theReply){
final List<EvMySchedData> dayList = new ArrayList<>();
EvMySchedAdapter tAdapter = new EvMySchedAdapter(dayList);
RecyclerView recyclerView = view.findViewById(R.id.schedRecycler);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(recyclerView.getContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(tAdapter);
tAdapter.emptyRecycler();
try {
JSONObject jsonServerReply = new JSONObject(theReply);
int evCount = jsonServerReply.getInt("recCount");
EvMySchedData thisLine;
if (evCount > 0) {
JSONObject cRec =null;
for (int thisRec=0; thisRec<evCount; thisRec++ ) {
cRec = jsonServerReply.getJSONObject(String.valueOf(thisRec));
thisLine = new EvMySchedData(cRec.getString("day_date"), cRec.getString("day_times"), cRec.getString("role"), cRec.getString("room"), view.getContext());
dayList.add(thisLine);
}
}
} catch (Exception e) {
}
}
public void onError(String error) {
}
});
return view;
} // end onCreateView
public void onClick(View v) {
this.dismiss();
}
}
The recyclerview has the picture of an eye on each line. I want to load a new fragment and close the dialog fragment when the eye is clickd. This is the adapter code:
public class EvMySchedAdapter extends RecyclerView.Adapter<EvMySchedAdapter.EventViewHolder> {
private List<EvMySchedData> dayList;
public EvMySchedAdapter(List<EvMySchedData> dayList) {
this.dayList = dayList;
}
#Override
public EvMySchedAdapter.EventViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
final View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.event_my_sched_row, parent, false);
ImageView eye = itemView.findViewById(R.id.dayOverviewButton);
try {
eye.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Load a new fragment
//dismiss the dialog
}
});
} catch (Exception e) {
}
return new EvMySchedAdapter.EventViewHolder(itemView);
}
#Override
public void onBindViewHolder(EvMySchedAdapter.EventViewHolder holder, int position) {
holder.dayDateBox.setText(dayList.get(position).getDayDate());
holder.dayTimeBox.setText(dayList.get(position).getDayTime());
holder.dayRoleBox.setText(dayList.get(position).getDayRole());
holder.dayRoomBox.setText(dayList.get(position).getDayRoom());
} // end onBindViewHolder
#Override
public int getItemCount() {
return dayList.size();
}
public class EventViewHolder extends RecyclerView.ViewHolder {
public TextView dayDateBox;
public TextView dayTimeBox;
public TextView dayRoleBox;
public TextView dayRoomBox;
public Context context;
public EventViewHolder(View view) {
super(view);
dayDateBox = view.findViewById(R.id.dateBox);
dayTimeBox = view.findViewById(R.id.timeBox);
dayRoleBox = view.findViewById(R.id.roleBox);
dayRoomBox = view.findViewById(R.id.roomBox);
}
}
public void emptyRecycler() {
final int size = dayList.size();
dayList.clear();
notifyItemRangeRemoved(0, size);
}
}
Thanks
Add to the adapter a constructor that receive DialogFragment and save it as a field.
When you create the Adapter do new EvMySchedAdapter(dayList, EvMySchedDlg.this);
Inside the onClick call dialgFragment.dismiss();
for Kotlin Users
class SomeAdapter(private val dialog: BottomSheetDialog):RecyclerView.Adapter<SomeAdapter.ViewHolder>()
holder.itemView.setOnClickListener{
dialog.dismiss()
}

showing RecyclerView on fragment with data from Firebase

I'm having a problem with making a RecycleView in a fragment with data from Firebase. I expect the app to show the RecycleView after I clicked on a button to change from one fragment to the RecycleView fragment, but it does change the showed fragment but it does not show anything.
I know there are plenty of questions like this but I don't seem to find the correct solution to this problem.
I've made everything needed for a Firebase RecyclerView, and also tried to build it inside an activity instead fragment and it did work, but not with the fragment.
I've tried to initialize the adapter and recyclerview inside the onCreateView method, onActivityCreated, and onViewCreated method and none of them seem to be working.
Here's my fragment code:
private KidAdapter adapter;
private RecyclerView recyclerView;
Button button;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.uangsaku_menu_fragment, container, false);
button = view.findViewById(R.id.btn_add);
button.setOnClickListener(this);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
setUpRecyclerView();
return view;
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.btn_add){
Intent intent = new Intent(getActivity(), Register.class);
startActivity(intent);
}
}
public void setUpRecyclerView(){
Query query = FirebaseDatabase.getInstance().getReference("kids");
FirebaseRecyclerOptions<kidData> options = new FirebaseRecyclerOptions.Builder<kidData>()
.setQuery(query, kidData.class)
.build();
adapter = new KidAdapter(options);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
}
#Override
public void onStart() {
super.onStart();
if (adapter != null) {
adapter.startListening();
}
}
#Override
public void onStop() {
super.onStop();
if (adapter != null) {
adapter.stopListening();
}
}
}
The adapter class
public class KidAdapter extends FirebaseRecyclerAdapter<kidData, KidAdapter.KidViewHolder> {
public KidAdapter(#NonNull FirebaseRecyclerOptions<kidData> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull KidViewHolder holder, int position, #NonNull kidData model) {
holder.nama.setText(model.getKidName());
holder.balance.setText(model.getKidBalance());
holder.limit.setText("Limit: "+model.getKidLimit());
holder.spending.setText("Spending xxx.xxx");
}
#NonNull
#Override
public KidViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.kids_card,
viewGroup, false);
return new KidViewHolder(v);
}
public class KidViewHolder extends RecyclerView.ViewHolder {
TextView nama, balance, limit, spending;
public KidViewHolder(#NonNull View itemView) {
super(itemView);
nama = itemView.findViewById(R.id.tv_nama);
balance = itemView.findViewById(R.id.tv_balance);
limit = itemView.findViewById(R.id.tv_dailylimit);
spending = itemView.findViewById(R.id.tv_dailyspending);
}
}
}
The kidData model class
public class kidData {
String kidName, kidEmail, kidDoB, kidLimit, kidBalance;
public kidData(){
}
public kidData(String kidName, String kidEmail, String kidDoB, String kidLimit, String kidBalance) {
this.kidName = kidName;
this.kidEmail = kidEmail;
this.kidDoB = kidDoB;
this.kidLimit = kidLimit;
this.kidBalance = kidBalance;
}
public String getKidName() {
return kidName;
}
public String getKidEmail() {
return kidEmail;
}
public String getKidDoB() {
return kidDoB;
}
public String getKidLimit() {
return kidLimit;
}
public String getKidBalance() {
return kidBalance;
}
}
The problem in your code is the use of the following line of code:
recyclerView.setHasFixedSize(true);
And this is because when using the latest version of Firebase-UI library, there is no need to set the size of the RecyclerView as fixed. The solution for solving this problem is to simply remove/comment the above line of code. That's it!

Categories