Can I have one recycleview that loads different datasets - java

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.

Related

Something goes wrong with my startAt and endAt search data in range, its show all my data inside of firebase

so i write a code for searching some range of data in my realtime firebase and when i did that, the data that shown up its not only in range, but all data that i have in firebase is out to my cardview(fragment)
this is my main code that work for searching data
public class SearchListView extends AppCompatActivity {
private RecyclerView recView;
MyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_search_list_view);
String tanggalawal = getIntent ( ).getStringExtra ("tanggalawal");
String tanggalakhir = getIntent ( ).getStringExtra ("tanggalakhir");
DatabaseReference db = FirebaseDatabase.getInstance().getReference();
DatabaseReference pendingRef = db.child("Users").child("Pending");
Query queryByKey = pendingRef.orderByKey()
.startAt("*" + tanggalawal)
.endAt("*"+ tanggalakhir + "\uf8ff");
recView = (RecyclerView)findViewById (R.id.recview);
recView.setLayoutManager (new LinearLayoutManager (this));
FirebaseRecyclerOptions<Model> options =
new FirebaseRecyclerOptions.Builder<Model>()
.setQuery(queryByKey, Model.class)
.build();
adapter = new MyAdapter (options);
recView.setAdapter (adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
and my firebase look like this
Firebase Database
and this is my adapter code
public class MyAdapter extends FirebaseRecyclerAdapter <Model,MyAdapter.myViewHolder>{
public MyAdapter(#NonNull FirebaseRecyclerOptions<Model> options) {
super (options);
}
#Override
protected void onBindViewHolder(#NonNull myViewHolder myViewHolder, int i, #NonNull Model model) {
myViewHolder.currentDate.setText (model.getCurrentDate ());
myViewHolder.fullName.setText (model.getFullName ());
myViewHolder.currentDateandTime.setText (model.getCurrentDateandTime ());
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from (parent.getContext ()).inflate (R.layout.item,parent,false);
return new myViewHolder (view);
}
class myViewHolder extends RecyclerView.ViewHolder{
TextView currentDate, fullName, currentDateandTime;
public myViewHolder(#NonNull View itemView) {
super (itemView);
currentDate = (TextView)itemView.findViewById (R.id.tvTanggalPengajuan);
fullName = (TextView)itemView.findViewById (R.id.tvNama);
currentDateandTime = (TextView)itemView.findViewById (R.id.tvNomorkontrak);
}
}
public interface OnNoteListener{
void OnNoteListener(int position);
}
}
i've following this method using "*" that look like this, but still failed
Search firebase realtime database base on 6 digit in front of the child data, i want to query data between two numbers (dates)

Replace Instead Of Adding Item To Arraylist

I building an app to practice in arraylist and recyclerView.
In the main activity I have "Add" button than I can add things to the arraylit to display in the recyclerView,However,the first time I add new line its working fine,but when I try to add another one,its replacing the first line I added with the new line.
I will be glad if you can point what am I doing wrong,Thank you.
Add Line Activity:
public void AddButton(View view){
if (imageUri != null && !mEditText.getText().toString().isEmpty()){
Intent intent = new Intent(AddCompany.this,MainActivity.class);
intent.putExtra("isAddNewCompany", true);
intent.putExtra("CompanyImage", imageUri.toString());
intent.putExtra("CompanyName", mEditText.getText().toString());
startActivity(intent);
}
}
MainActivity OnCreate with the views:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
ArrayList<String> listTitle = new ArrayList<>();
ArrayList<String> listPicture = new ArrayList<>();
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
listTitle.add(companyName);
listPicture.add(CompanyImage);
}
// set up the RecyclerView
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
RecyclerAdapter adapter = new RecyclerAdapter(this,listPicture,listTitle);
adapter.setClickListener(new RecyclerAdapter.ItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.e("Position Number - ", String.valueOf(position));
Toast.makeText(MainActivity.this, adapter.getItem(position), Toast.LENGTH_SHORT).show();
}
});
recyclerView.setAdapter(adapter);
}
RecyclerView Adapter:
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private final ArrayList<String> mData;
private final ArrayList<String> mImageView;
private final LayoutInflater mInflater;
private ItemClickListener mClickListener;
// data is passed into the constructor
RecyclerAdapter(Context context, ArrayList<String> imageView, ArrayList<String> data) {
this.mInflater = LayoutInflater.from(context);
this.mData = data;
this.mImageView = imageView;
}
// inflates the row layout from xml when needed
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.recyclerview_row, parent, false);
return new ViewHolder(view);
}
// binds the data to the TextView in each row
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
String animal = mData.get(position);
String picture = mImageView.get(position);
Picasso.get().load(picture).into(holder.myImageView);
holder.myTextView.setText(animal);
}
// total number of rows
#Override
public int getItemCount() {
return mData.size();
}
// stores and recycles views as they are scrolled off screen
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView myTextView;
ImageView myImageView;
ViewHolder(View itemView) {
super(itemView);
myTextView = itemView.findViewById(R.id.tvAnimalName);
myImageView = itemView.findViewById(R.id.imageView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
// convenience method for getting data at click position
String getItem(int id) {
return mData.get(id);
}
// allows clicks events to be caught
void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
// parent activity will implement this method to respond to click events
public interface ItemClickListener {
void onItemClick(View view, int position);
}
}
When you start activity ,every time new list instance will be created that's why you got only one value.if you want already added value, use same list instance.
List<String> listTitle;
List<String> listPicture;
public List<String> getLisPictureInstance(){
if(listPicture ==null)
listPicture = new ArrayList<>();
return listPicture ;
}
public List<String> getListTitleInstance(){
if(listTitle ==null)
listTitle = new ArrayList<>()
return listTitle ;
}
if (intent.getBooleanExtra("isAddNewCompany",false)){
String CompanyImage = intent.getStringExtra("CompanyImage");
String companyName = intent.getStringExtra("CompanyName");
getListTitleInstance().add(companyName);
getLisPictureInstance().add(CompanyImage);
}

PDF Dowload or Intent

I made a RecyclerView with CardViews that retrieve two TextViews from the Cloud Firestore and whenever I click on the card, I want it, based on the pdfUrl stored in my Firestore database, that an activity be opened with the pdf or donwload the pdf to the phone. But I don't know how to achieve that.
Here's my firestore structure
My code:
public class RecylerViewTestsActivity extends AppCompatActivity {
RecyclerView recyclerView;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private FirestoreRecyclerAdapter<uploadTests, TestesViewHolder> adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recyler_view_tests);
RecyclerView recyclerView = findViewById(R.id.recyclerViewTests);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
Query query = rootRef.collection("FilterPDFUploads");
FirestoreRecyclerOptions<uploadTests> options = new FirestoreRecyclerOptions.Builder<uploadTests>()
.setQuery(query, uploadTests.class)
.build();
adapter = new FirestoreRecyclerAdapter<uploadTests,TestesViewHolder >(options) {
#Override
protected void onBindViewHolder(#NonNull TestesViewHolder holder, int position, #NonNull uploadTests model) {
holder.setTestesDesc(model.getDescription());
holder.setTestesName(model.getUsername());
}
#NonNull
#Override
public TestesViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.pdf_tests_items, parent, false);
return new TestesViewHolder(view);
}
};
recyclerView.setAdapter(adapter);
}
//////////////////////////VIEW HOLDER////////////////////////////////////////////
private class TestesViewHolder extends RecyclerView.ViewHolder {
private View view;
private CardView itemsCard;
TestesViewHolder(final View itemView) {
super(itemView);
view = itemView;
}
void setTestesDesc (String descri) {
TextView desc = view.findViewById(R.id.teste_description);
desc.setText(descri);
}
void setTestesName (String username) {
TextView user = view.findViewById(R.id.name_id);
user.setText(username);
}
void setPdfUrl(final String url){
}
}
//////////////////////////VIEW HOLDER////////////////////////////////////////////
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
if (adapter != null) {
adapter.stopListening();
}
}
}
whenever I click on the card, I want it, based on the pdfUrl stored in my firestore database, that an activity be opened with the pdf or donwload the pdf to the phone
To solve this, you should use setOnClickListener() on your TestesViewHolder object. Inside the click listener, please add the following lines of code:
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
Where url is the actual url that is stored in your database. That's it!

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

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*/
}
}

How to pass List<E> from RecyclerView Adapter to RecyclerView Holder?

I've been trying to find the answer to my question above but no post seems to help. I have a RecyclerView Adapter where I get the data as List from a database:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.RecyclerViewHolder> {
public List<Note> noteList;
private View.OnLongClickListener longClickListener;
private Context context;
public RecyclerViewAdapter(List<Note> noteList, View.OnLongClickListener longClickListener, Context context) {
this.noteList = noteList;
this.longClickListener = longClickListener;
this.context = context;
}
And a ViewHolder where I have an onClickListener to find the position of the view clicked using getLayoutPosition():
static class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView noteTitleText;
private TextView noteDescriptionText;
private TextView dateText;
private TextView weekText;
RecyclerViewHolder(View view) {
super(view);
noteTitleText = (TextView) view.findViewById(R.id.noteTitleText);
noteDescriptionText = (TextView) view.findViewById(R.id.noteDescriptionText);
dateText = (TextView) view.findViewById(R.id.dateText);
weekText = (TextView) view.findViewById(R.id.weekText);
view.setOnClickListener(this);
}
#Override
public void onClick(View view) {
int position = getLayoutPosition();
// I want the noteList from the RecyclerViewAdapter here.
Note note = noteList.get(position);
Log.d("Item Clicked", String.valueOf(position));
}
}
The purpose is that I need the noteList with all the notes from the RecyclerViewAdapter in the onClick() method to populate an Activity using an intent. How should I go about this?
After trying out solutions for an hour, here's what I settled on. Instead of implementing OnClickListener in ViewHolder, I implemented it in RecyclerViewAdapter in onBindViewHolder() method, as:
#Override
public void onBindViewHolder(final RecyclerViewHolder holder, final int position) {
final Note note = noteList.get(position);
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// The note and noteList can be accessed here.
}
});
}

Categories