I'm having some issues referencing a particular collection that is nested (I think that the term) I have attached an image of my database structure below:
EDIT: image of Foods collection
I basically have multiple documents that have a collection within them with the same name. Is there a way I can dynamically select the "Foods" collection depending on the restaurant ID that a user has clicked on the previous page. ie if the user selects a restaurant with ID 01, it should Load "Foods" from a document with ID 01, etc.
here is my code for the fragment loading the foods:
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.hostapp.Adapters.FoodAdapter;
import com.example.hostapp.Models.FoodModel;
import com.example.hostapp.R;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
public class MainsFragment extends Fragment {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference menuref = db.collection("Foods");
private FoodAdapter adapter;
String restaurantid = "";
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mains, container, false);
Query query = menuref.whereEqualTo("menuid", restaurantid).orderBy("name");
FirestoreRecyclerOptions<FoodModel> options = new FirestoreRecyclerOptions.Builder<FoodModel>().
setQuery(query, FoodModel.class)
.build();
adapter = new FoodAdapter(options);
RecyclerView recyclerView = view.findViewById(R.id.recycler_mains);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity()));
recyclerView.setAdapter(adapter);
return view;
}
private void setUpRecyclerView() {
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
for the previous page on click:
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.RelativeLayout;
import com.example.hostapp.Adapters.RestaurantAdapter;
import com.example.hostapp.Adapters.categoryCardAdapter;
import com.example.hostapp.Models.Restaurant;
import com.example.hostapp.Models.categoryCard;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
public class RestaurantList extends AppCompatActivity {
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference restaurantref = db.collection("restaurants");
private RestaurantAdapter adapter;
String categoryid="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_restaurant_list);
setUpRecyclerView();
}
private void setUpRecyclerView(){
//Get intent
if(getIntent() != null)
categoryid = getIntent().getStringExtra("categoryid");
if(!categoryid.isEmpty() && categoryid != null)
{
Query query = restaurantref.whereEqualTo("categoryid", categoryid).orderBy("name");
final FirestoreRecyclerOptions<Restaurant> options = new FirestoreRecyclerOptions.Builder<Restaurant>().setQuery(query, Restaurant.class).build();
adapter = new RestaurantAdapter(options);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.restaurant_recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
adapter.setOnItemClickListerner(new RestaurantAdapter.OnItemClickListener() {
#Override
public void onItemClick(DocumentSnapshot documentSnapshot, int position) {
Restaurant restaurant = documentSnapshot.toObject(Restaurant.class);
Intent foodlist = new Intent(RestaurantList.this, Foodlist.class);
foodlist.putExtra("restaurantid", documentSnapshot.getId());
startActivity(foodlist);
}
});
}
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
}
According to your comments, to get all Food documents that exist in all sub-collections according to the menuid property, a Firestore collection group query is needed. This query looks like this:
Query menuIdQuery = db.collectionGroup("Foods").whereEqualTo("menuid", yourMenuId);
Related
I am creating a notes app with java, i added room database to my app and when user saves a notes it adds it to database but doesn't shows in recyclerView immediately, when i reloads the app then it shows up, how and where should i insert notifyiteminserted so that recyclerView changes immediately
I have tried onResume Method but that results in app crash.
This is my MainActivity.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
#SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
This is my add_Activity.
package com.example.keepnotes;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import java.util.Objects;
public class addActivity extends AppCompatActivity {
MainActivity mainActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
Toolbar toolbar_add = findViewById(R.id.toolbar_add_activity);
setSupportActionBar(toolbar_add);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
toolbar_add.setNavigationIcon(R.drawable.back_button);
toolbar_add.setNavigationOnClickListener(view -> onBackPressed());
EditText titleText = findViewById(R.id.add_activity_title);
EditText bodyText = findViewById(R.id.add_activity_text);
Button saveBtn = findViewById(R.id.button);
DatabaseHelper database = DatabaseHelper.getDatabase(this);
saveBtn.setOnClickListener(view -> {
String titleBody = titleText.getText().toString();
String textBody = bodyText.getText().toString();
if (titleBody.equals("") && textBody.equals("")) {
Toast.makeText(addActivity.this, "Fields can't be empty",
Toast.LENGTH_LONG).show();
} else {
database.notesDao().addNotes(new Notes(titleBody, textBody));
finish();
}
});
}
}
How can i notify adapter the changes on each item add in database.
Here is my MainActivity after update to liveData.
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
static ArrayList<Notes> arrNotes;
#SuppressLint("StaticFieldLeak")
RecyclerViewAdapter adapter;
RecyclerView.LayoutManager layoutManager;
notesModelView modelView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DatabaseHelper dbHelper = DatabaseHelper.getDatabase(this);
modelView = new ViewModelProvider(this).get(notesModelView.class);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
#Override
public void onChanged(List<Notes> notes) {
arrNotes = (ArrayList<Notes>) notes;
}
});
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
adapter = new RecyclerViewAdapter(this, arrNotes);
recyclerView.setAdapter(adapter);
//setting up recycler view
layoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
//Setting custom Toolbar
Toolbar toolbar1 = findViewById(R.id.toolbar);
setSupportActionBar(toolbar1);
//Moving from MainActivity to add_Notes Activity
Button button = findViewById(R.id.floatingActionButton);
button.setOnClickListener(view -> {
Intent intent = new Intent(MainActivity.this, addActivity.class);
startActivity(intent);
});
}
}
this is Dao.
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
#Dao
public interface NotesDao {
#Query("SELECT * FROM notesTable")
List<Notes> getAllNotes();
#Query("SELECT * FROM notesTable")
LiveData<List<Notes>> findAllNotes();
#Insert
void addNotes(Notes note);
#Update
void updateNotes(Notes note);
#Delete
void deleteNotes(Notes note);
}
And here is my ViewModel
package com.example.keepnotes;
import android.app.Application;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class notesModelView extends AndroidViewModel {
DatabaseHelper databaseHelper;
public notesModelView(#NonNull Application application) {
super(application);
databaseHelper = DatabaseHelper.getDatabase(application.getApplicationContext());
}
public LiveData<List<Notes>> getAllNotes() {
return databaseHelper.notesDao().findAllNotes();
}
}
Here is my RecyclerView adapter
package com.example.keepnotes;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
Context context;
ArrayList<Notes> arrNotes;
DatabaseHelper databaseHelper;
RecyclerViewAdapter(Context context, ArrayList<Notes> arrNotes, DatabaseHelper databaseHelper) {
this.context = context;
this.arrNotes = arrNotes;
this.databaseHelper = databaseHelper;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.single_view, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, #SuppressLint("RecyclerView") int position) {
holder.title.setText(arrNotes.get(position).title);
holder.body.setText(arrNotes.get(position).text);
holder.index.setText(String.valueOf(position + 1));
holder.llView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
AlertDialog.Builder alert = new AlertDialog.Builder(context)
.setTitle("Delete view")
.setMessage("Are you sure to delete")
.setIcon(R.drawable.ic_baseline_delete_24)
.setPositiveButton("yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
databaseHelper.notesDao().deleteNotes(new Notes(arrNotes.get(position).id,arrNotes.get(position).title,arrNotes.get(position).text));
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrNotes.size());
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alert.show();
return true;
}
});
}
#Override
public int getItemCount() {
return arrNotes.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title, body, index;
CardView llView;
public ViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.text_title_view);
body = itemView.findViewById(R.id.text_text_view);
index = itemView.findViewById(R.id.index);
llView = itemView.findViewById(R.id.card_View);
databaseHelper = DatabaseHelper.getDatabase(context);
}
}
}
It deletes the selected notes but also crashes immediately after confirming delete.
and it throws following error
java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid view holder adapter positionViewHolder{535e3b3 position=5 id=-1, oldPos=4, pLpos:4 scrap [attachedScrap] tmpDetached not recyclable(1) no parent} androidx.recyclerview.widget.RecyclerView{11f4816 VFED..... ......ID 31,171-689,1048 #7f090165 app:id/recycler_view}, adapter:com.example.keepnotes.RecyclerViewAdapter#fd652a0, layout:androidx.recyclerview.widget.StaggeredGridLayoutManager#32e1e59, context:com.example.keepnotes.MainActivity#286bccd
Remove this two line
notifyItemRemoved(position);
notifyItemRangeChanged(position, arrNotes.size());
OLD ANSWER
First, if you use liveData you don't need to call the method
arrNotes = (ArrayList<Notes>) dbHelper.notesDao().getAllNotes();
just keep a reference to the adapter instance and whenever there is a change from liveData call the notifyDataSetChanged method.
adapter = new RecyclerViewAdapter(this,new List<Notes>());
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(adapter);
modelView.getAllNotes().observe(this, new Observer<List<Notes>>() {
#Override
public void onChanged(List<Notes> notes) {
arrNotes.clear();
arrNotes.addAll(notes);
adapter.notifyDataSetChanged()
}
});
observe a LiveData object as it is not a LifecycleOwner
Use observeForever() on the LiveData, manually unregistering via removeObserver() when appropriate (onDestroy() of the service, if not sooner).
Bear in mind that standard service limitations apply here (e.g., services run for ~1 minute on Android 8.0+ unless they are foreground services), so it may be that you need to consider other approaches anyway. 🤞
Also you can read more in original post in here -> Link
I am trying to retrieve images from Firebase Firestore. I am able to retrieve text in RecyclerView successfully however I'm not sure how to retrieve the images.
I had a look at similar questions unfortunately none helped.
My MainClass
package com.harsh.preacher.ui.HomeToDestination;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.util.Log;
import com.google.firebase.firestore.DocumentChange;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.QuerySnapshot;
import com.harsh.preacher.R;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class MustHaveEquipment extends AppCompatActivity {
DocumentSnapshot documentSnapshot;
RecyclerView recyclerView;
ArrayList<ProductModel> productModelArrayList ;
ProductAdapter productAdapter;
FirebaseFirestore db;
ProgressDialog progressDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_must_have_equipment);
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("Loading Products");
progressDialog.show();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
db = FirebaseFirestore.getInstance();
productModelArrayList = new ArrayList<ProductModel>();
productAdapter = new ProductAdapter(MustHaveEquipment.this,productModelArrayList);
recyclerView.setAdapter(productAdapter);
EventChangeListner();
}
private void EventChangeListner() {
db.collection("Products")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable #org.jetbrains.annotations.Nullable QuerySnapshot value, #Nullable #org.jetbrains.annotations.Nullable FirebaseFirestoreException error) {
if(error!=null){
if(progressDialog.isShowing())
progressDialog.dismiss();
Log.e("No Internet Connection",error.getMessage());
}
for (DocumentChange dc : value.getDocumentChanges()){
if(dc.getType() == DocumentChange.Type.ADDED){
productModelArrayList.add(dc.getDocument().toObject(ProductModel.class));
}
productAdapter.notifyDataSetChanged();
if(progressDialog.isShowing())
progressDialog.dismiss();
}
}
});
}
}
My Adapter Class
package com.harsh.preacher.ui.HomeToDestination;
import android.content.Context;
import android.os.Build;
import android.transition.AutoTransition;
import android.transition.TransitionManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.FirebaseAppLifecycleListener;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.harsh.preacher.R;
import com.squareup.picasso.Picasso;
import org.jetbrains.annotations.NotNull;
import org.w3c.dom.Document;
import java.util.ArrayList;
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
DocumentSnapshot documentSnapshot;
Context context;
ArrayList<ProductModel> productModelArrayList;
public ProductAdapter(Context context, ArrayList<ProductModel> productModelArrayList) {
this.context = context;
this.productModelArrayList = productModelArrayList;
}
#NonNull
#NotNull
#Override
public ProductAdapter.ProductViewHolder onCreateViewHolder(#NonNull #NotNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.epupiment_design,parent,false);
return new ProductViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull #NotNull ProductAdapter.ProductViewHolder holder, int position) {
ProductModel productModel = productModelArrayList.get(position);
holder.productName.setText(productModel.ProductName);
holder.aboutProduct.setText(productModel.AboutProduct);
holder.productDescription.setText(productModel.ProductUse);
}
#Override
public int getItemCount() {
return productModelArrayList.size();
}
public static class ProductViewHolder extends RecyclerView.ViewHolder {
TextView aboutProduct,productName,productDescription;
RelativeLayout expandable,card;
ImageView showmore,productImage;
public ProductViewHolder(#NonNull #NotNull View itemView) {
super(itemView);
aboutProduct = itemView.findViewById(R.id.productDescription);
productName = itemView.findViewById(R.id.productName);
productDescription = itemView.findViewById(R.id.aboutProduct);
productImage = itemView.findViewById(R.id.productImage);
expandable = itemView.findViewById(R.id.expandable);
card = itemView.findViewById(R.id.cardeshwar);
showmore = itemView.findViewById(R.id.showMore);
showmore.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
public void onClick(View view) {
if (expandable.getVisibility() == View.VISIBLE) {
TransitionManager.beginDelayedTransition(card,
new AutoTransition());
expandable.setVisibility(View.GONE);
showmore.setImageResource(R.drawable.showmore);
} else {
TransitionManager.beginDelayedTransition(card,
new AutoTransition());
expandable.setVisibility(View.VISIBLE);
showmore.setImageResource(R.drawable.showless);
}
}
});
}
}
}
My model class
package com.harsh.preacher.ui.HomeToDestination;
import android.widget.ImageView;
public class ProductModel {
String ProductName, ProductUse, AboutProduct;
ImageView ProductImage;
public ProductModel(){}
public ProductModel(String productName, String productUse, String aboutProduct,ImageView productImage){
ProductName = productName;
ProductUse = productUse;
AboutProduct = aboutProduct;
ProductImage = productImage;
}
public String getProductName() {
return ProductName;
}
public void setProductName(String productName) {
ProductName = productName;
}
public String getProductUse() {
return ProductUse;
}
public void setProductUse(String productUse) {
ProductUse = productUse;
}
public String getAboutProduct() {
return AboutProduct;
}
public void setAboutProduct(String aboutProduct) {
AboutProduct = aboutProduct;
}
public ImageView getProductImage() {
return ProductImage;
}
public void setProductImage(ImageView productImage) {
ProductImage = productImage;
}
}
Here is the structure of my database
Follow these steps to show images in RecyclerView
Remove ImageView from ProductModel
Add String imageUrl to ProductModel and set its value with the image URL from Firestore (I see from the screenshot that it is named "Image").
In onBindViewHolder from the ProductAdapter, use the position provided to retrieve the appropriate ProductModel from productModelArrayList and pass its imageUrl value to ProductViewHolder.
In ProductViewHolder, use the imageUrl to load the image into the ImageView. (Glide and Picasso are two commonly used library to load images)
PS: Never add UI elements in your model. It will cause lifecycle issues in the future.
Let me know if you have any questions.
I'm getting an error E/RecyclerView: No adapter attached; skipping layout while using FirestoreRecylerAdapter INSIDE a FRAGMENT. After reading all answers to similar questions ,I'm not able to reach to a solution because most of them are for recylerAdapter inside activiy, i.e. they have an onCreate method where they can set up their adapter first. In fragments as you know,there is no view in onCreate method so I can't find my recyclerView there.Some answers are suggesting to setup an empty adapter and then notify for data change.
I'm not able to able to setup an empty adapter in onCreateView. Here's my code:
My adapter:
package com.example.XX;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
public class ProfileRecyclerAdapter extends FirestoreRecyclerAdapter<Profile,ProfileRecyclerAdapter.ProfileViewHolder> {
public ProfileRecyclerAdapter(#NonNull FirestoreRecyclerOptions<Profile> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull ProfileViewHolder holder, int position, #NonNull Profile profile) {
holder.Name_textView.setText(profile.getName());
holder.Sector_textView.setText(profile.getSector());
holder.Pincode_textView.setText(profile.getPincode());
}
#NonNull
#Override
public ProfileViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View view=layoutInflater.inflate(R.layout.profile_row_item,parent,false);
return new ProfileViewHolder(view);
}
class ProfileViewHolder extends RecyclerView.ViewHolder{
TextView Name_textView;
TextView Sector_textView;
TextView Pincode_textView;
public ProfileViewHolder(#NonNull View itemView) {
super(itemView);
Name_textView=itemView.findViewById(R.id.Name_textView);
Sector_textView=itemView.findViewById(R.id.Sector_textView);
Pincode_textView=itemView.findViewById(R.id.Pincode_textView);
}
}
}
My FRAGMENT where I want the data to be displayed:
package com.example.XX;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.List;
public class MainQueryFragment extends Fragment {
RecyclerView recyclerView;
ProfileRecyclerAdapter profileRecyclerAdapter;
TextView yourSector;
TextView yourPincode;
FirebaseFirestore db = FirebaseFirestore.getInstance();
String tuserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
String customerPincode;
String customerSector;
String sectorText;
String pincodeText;
String[] testArray;
String name;
String pincode;
String address;
String mobileNumber;
String sector;
String avgDeliveryTime;
String avgDeliveryTimeUrg;
Boolean item1;
Boolean item2;
Boolean item3;
Boolean item4;
Boolean item5;
Boolean item6;
Boolean item7;
Boolean item8;
Boolean item9;
Boolean item10;
String speciality;
String avgNumOrders;
String shopType;
String userID;
String avgPriceRange;
String education;
Button button;
public MainQueryFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main_query, container, false);
yourSector = view.findViewById(R.id.Sector_tv);
yourPincode = view.findViewById(R.id.Pincode_tv);
recyclerView = view.findViewById(R.id.recyclerView_Profile);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(profileRecyclerAdapter);
{ DocumentReference docRef = db.collection("customerUsers").document(tuserID);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
customerPincode = document.getString("pincode");
customerSector = document.getString("sector");
sectorText = "Sector : " + customerSector;
pincodeText = "Pincode : " + customerPincode;
yourSector.setText(sectorText);
yourPincode.setText(pincodeText);
Log.d("work", "onComplete: " + customerPincode);
} else {
Log.d("docref", "No such document");
}
} else {
Log.d("docref", "get failed with ", task.getException());
}
}
});
}//doc for sector,pincode loading
if (getArguments() != null) {
MainQueryFragmentArgs args = MainQueryFragmentArgs.fromBundle(getArguments());
testArray = args.getArrayCheckboxData();
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
button=view.findViewById(R.id.startQuery_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Query query = FirebaseFirestore.getInstance()
.collection("tUsers")
.whereEqualTo("pincode", customerPincode)
.whereEqualTo("sector", customerSector)
.whereEqualTo(testArray[0], true)
.whereEqualTo(testArray[1], true)
.whereEqualTo(testArray[2], true)
.whereEqualTo(testArray[3], true);
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter);
profileRecyclerAdapter.startListening();
}
});
}
}
Even if I comment out my button and onclicklistener and then run the app,I should be technically running an empty adapter. Still I'm getting the same error.
Please suggest what i should do,keeping in mind I CANNOT use onCreate
Edit Here is my edited code. Now I'm getting null Pointer exception and my app is crashing:
package com.example.XX;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.List;
public class MainQueryFragment extends Fragment {
RecyclerView recyclerView;
ProfileRecyclerAdapter profileRecyclerAdapter;
TextView yourSector;
TextView yourPincode;
FirebaseFirestore db = FirebaseFirestore.getInstance();
String tuserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
String customerPincode;
String customerSector;
String sectorText;
String pincodeText;
String[] testArray;
String name;
String pincode;
String address;
String mobileNumber;
String sector;
String avgDeliveryTime;
String avgDeliveryTimeUrg;
Boolean item1;
Boolean item2;
Boolean item3;
Boolean item4;
Boolean item5;
Boolean item6;
Boolean item7;
Boolean item8;
Boolean item9;
Boolean item10;
String speciality;
String avgNumOrders;
String shopType;
String userID;
String avgPriceRange;
String education;
Button button;
public MainQueryFragment() {
// Required empty public constructor
}
#Override
public void onStart() {
super.onStart();
profileRecyclerAdapter.startListening();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main_query, container, false);
yourSector = view.findViewById(R.id.Sector_tv);
yourPincode = view.findViewById(R.id.Pincode_tv);
{ DocumentReference docRef = db.collection("customerUsers").document(tuserID);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
customerPincode = document.getString("pincode");
customerSector = document.getString("sector");
sectorText = "Sector : " + customerSector;
pincodeText = "Pincode : " + customerPincode;
yourSector.setText(sectorText);
yourPincode.setText(pincodeText);
Log.d("work", "onComplete: " + customerPincode);
} else {
Log.d("docref", "No such document");
}
} else {
Log.d("docref", "get failed with ", task.getException());
}
}
});
}//doc for sector,pincode loading
if (getArguments() != null) {
MainQueryFragmentArgs args = MainQueryFragmentArgs.fromBundle(getArguments());
testArray = args.getArrayCheckboxData();
}
return view;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
button=view.findViewById(R.id.startQuery_button);
recyclerView = view.findViewById(R.id.recyclerView_Profile);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Query query = FirebaseFirestore.getInstance()
.collection("tUsers")
.whereEqualTo("pincode", customerPincode)
.whereEqualTo("sector", customerSector)
.whereEqualTo(testArray[0], true)
.whereEqualTo(testArray[1], true)
.whereEqualTo(testArray[2], true)
.whereEqualTo(testArray[3], true);
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter);
pailorProfileRecyclerAdapter.notifyDataSetChanged();
}
});
}
#Override
public void onStop() {
super.onStop();
profileRecyclerAdapter.stopListening();
}
}
When you first create your Adapter in onCreateView(), you are not initializing that adapter, instead, you are setting the adapter right from the property:
ProfileRecyclerAdapter profileRecyclerAdapter;
recyclerView.setAdapter(profileRecyclerAdapter);
You need to initialize your adapter to set that adapter to your RecyclerView.
Second, you should not have that asynchronous call inside your onCreateView(), instead, use onViewCreated() to handle your asynchronous calls after your view is created.
Then, you are also making your adapter instance in your onViewCreated() with:
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter);
profileRecyclerAdapter.startListening();
And you should do:
profileRecyclerAdapter.startListening();
In your onStart() and profileRecyclerAdapter.stopListening(); at your onStop()
Instead of using adapter.startListening and
adapter.stopListening use .setLifecycleOwner(this)
Check out this working code:
FirestoreRecyclerOptions<Profile> options = new FirestoreRecyclerOptions.Builder<Profile>()
.setQuery(query,Profile.class)
.setLifecycleOwner(this)
.build();
profileRecyclerAdapter = new ProfileRecyclerAdapter(options);
recyclerView.setAdapter(profileRecyclerAdapter)
can anyone explain to me how can I create a new recycle and add items to that recycle view staring from another recycle view inside another activity?
Basically I want to create a shopping cart, for now, I retrieved the data from Firebase dataset and displayed it inside a recycle view but now I would like to send this data to the shopping cart(the shopping cart is inside another activity), I'm able to send the data but I can't understand how to display the data inside the new recycle view of this new activity. I need this because I want to see the items that I added to the shopping list so then I can pay.
Below I will attach a photo to explain myself better.
My problem is that I can't understand how to add the sent data to a recycle view again in the new activity.
I'm new to android so it's the first time I'm doing this thing.
Thank you in advance for your help.
My code:
SearchItemsActivity :
package com.example.ipill;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.content.Intent;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import java.util.ArrayList;
import java.util.List;
public class FirebaseSearch extends AppCompatActivity {
private EditText mSearchField;
private ImageButton mSearchBtn;
private ImageButton AddToCart;
private ImageButton Cart;
String searchText="";
private RecyclerView mResultList;
private DatabaseReference mUserDatabase;
private static ArrayList<Users> arrayList = new ArrayList<>();
public static int cart_count = 0;
RecyclerView productRecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_firebasesearch);
mUserDatabase = FirebaseDatabase.getInstance().getReference("Users");
mSearchField = findViewById(R.id.search_field);
mSearchBtn = findViewById(R.id.search_btn);
mResultList = findViewById(R.id.result_list_cart);
AddToCart = findViewById(R.id.imageButton2);
Cart = findViewById(R.id.cartButton);
mResultList.setHasFixedSize(true);
mResultList.setLayoutManager(new LinearLayoutManager(this));
mSearchBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchText = mSearchField.getText().toString();
firebaseUserSearch(searchText);
}
});
Cart.setOnClickListener(new View.OnClickListener() {
private Object Tag="Activity";
#Override
public void onClick(View v) {
if (cart_count < 1) {
} else {
startActivity(new Intent(FirebaseSearch.this, CartActivity.class));
}
}
});
}
private void firebaseUserSearch(String searchText) {
Toast.makeText(FirebaseSearch.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.getDetails(model.getName(), model.getSurname(),model.getPrice());
viewHolder.setDetails(model.getName(), model.getSurname(),model.getPrice());
}
};
mResultList.setAdapter(firebaseRecyclerAdapter);
}
#Override
protected void onStart() {
super.onStart();
invalidateOptionsMenu();
}
// View Holder Class
public static class UsersViewHolder extends RecyclerView.ViewHolder {
View mView;
String nome;
String surname;
Long prezzo;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
ImageButton addToCart = (ImageButton)mView.findViewById(R.id.imageButton2);
addToCart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cart_count++;
Context context = v.getContext();
Intent intent = new Intent(context, CartActivity.class);
intent.putExtra("Name",nome);
intent.putExtra("Surname",surname);
intent.putExtra("Prezzo",Long.toString(prezzo));
context.startActivity(intent);
}
});
}
public void getDetails(String name,String cognome,Long price){
nome=name;
surname=cognome;
prezzo=price;
}
public void setDetails(String name, String surname, Long price) {
TextView user_name = (TextView) mView.findViewById(R.id.name_text);
TextView user_surname = (TextView)mView.findViewById(R.id.status_text);
TextView user_price = (TextView)mView.findViewById(R.id.price);
user_name.setText(name);
user_surname.setText(surname);
user_price.setText(Long.toString(price));
}
}
}
enter code here
The second activity where I receive the data and where I want to create the recycle view
package com.example.ipill;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.Collection;
public class CartActivity extends AppCompatActivity {
public static TextView grandTotal;
public static int grandTotalplus;
// create a temp list and add cartitem list
public static ArrayList<Users> temparraylist;
RecyclerView cartRecyclerView;
Button proceedToBook;
Context context;
String name,surname,price;
private static ArrayList<Users> arrayList2 = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cart);
context = this;
temparraylist = new ArrayList<>();
proceedToBook = findViewById(R.id.buyNow);
grandTotal = findViewById(R.id.TotalPrice);
cartRecyclerView=findViewById(R.id.cartList);
String passedArg = getIntent().getExtras().getString("Name");
name=passedArg;
String passedArg2 = getIntent().getExtras().getString("Surname");
surname=passedArg2;
String passedArg3 = getIntent().getExtras().getString("Price");
price=passedArg3;
System.out.println("DATA"+name+surname+price);
cartRecyclerView.setHasFixedSize(true);
cartRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}
you can re use the cart adapter just implement a recylerView into new Activity and make the cart adater object and set it into the new reyclerView and it done
I'm a beginner, try to make a RecycleView layout with some information retrieve from Firebase database (in MemberFragment.java). In my code RecycleView layout with retrieve information from fire base database is worked but I can't retrieve item list position and can't be used for different massage display with different item list selected / clicked by user can any one help me how can I do it.
my code is:-
package np.com.rotaractnepalapp;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Picasso;
import np.com.rotaractnepalapp.Interface.ItemClickListener;
import np.com.rotaractnepalapp.Model.Member;
import np.com.rotaractnepalapp.ViewHolder.MemberViewHolder;
public class MemberFragment extends Fragment {
View memFragment;
RecyclerView listofMembers;
RecyclerView.LayoutManager memLayoutManger;
FirebaseRecyclerAdapter<Member, MemberViewHolder> memAdapter;
FirebaseDatabase database;
DatabaseReference members;
public static MemberFragment newInstance(){
MemberFragment memberFragment = new MemberFragment();
return memberFragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = FirebaseDatabase.getInstance();
members = database.getReference("ClubKNE");
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
memFragment = inflater.inflate(R.layout.fragment_member,container,false);
TextView title = (TextView) memFragment.findViewById(R.id.txtClubNameTitle);
title.setText("RAC Kathmandu North-East");
listofMembers = (RecyclerView) memFragment.findViewById(R.id.memLists);
listofMembers.setHasFixedSize(true);
memLayoutManger = new LinearLayoutManager(container.getContext());
listofMembers.setLayoutManager(memLayoutManger);
loadMember();
return memFragment;
}
private void loadMember() {
memAdapter = new FirebaseRecyclerAdapter<Member, MemberViewHolder>(
Member.class,
R.layout.mem_layout,
MemberViewHolder.class,
members
) {
#Override
protected void populateViewHolder(MemberViewHolder viewHolder, Member model, int position) {
viewHolder.memDesignation.setText(model.getMemDesignation());
viewHolder.memName.setText(model.getMemName());
viewHolder.memProfession.setText(model.getMemProfession());
viewHolder.memEmail.setText(model.getMemEmail());
Picasso.with(getActivity())
.load(model.getMemImage())
.into(viewHolder.memImage);
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(view.getContext());
LayoutInflater factory = LayoutInflater.from(view.getContext());
view = factory.inflate(R.layout.member_info_layout, null);
alertDialog.setView(view);
alertDialog.setNegativeButton("Done", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
});
}
};
memAdapter.notifyDataSetChanged();
listofMembers.setAdapter(memAdapter);
}
}
To get the position of an item, there are two solutions. One would be:
Member member = listMemenbers.get(position);
If you are using a list of Member objects. And second:
Member member = memAdapter.getItem(position);
In which case you are getting the position of the item directly from the adapter.
You can simply use position variable i.e int position it will show the position of card or any other other value