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)
Related
It's a chatting application where i only wanted to display the users from database those whose numbers are available on the users device contact list.
I have got the list of contact list but i don't know how to query the database or i even tried a work around where it displays the user information who are present but those who are not present it shows a default itemview. You can check image link for reference
package com.example.myapplication;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
/**
* A simple {#link Fragment} subclass.
* Use the {#link Fragment1#newInstance} factory method to
* create an instance of this fragment.
*/
public class Fragment1 extends Fragment {
private FirebaseFirestore firebaseFirestore;
LinearLayoutManager linearLayoutManager;
private FirebaseAuth firebaseAuth;
ImageView imageViewOfUser;
FirestoreRecyclerAdapter<firebasemodel, NoteViewHolder> chatAdapter;
RecyclerView recyclerView;
ArrayList<String> contactList;
ArrayList<String> getcontactList;
public Fragment1() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_1, container, false);
firebaseAuth = FirebaseAuth.getInstance();
firebaseFirestore = FirebaseFirestore.getInstance();
recyclerView = view.findViewById(R.id.recyclerview);
contactList = new ArrayList<String>();
getcontactList = getContactList();
Query query = firebaseFirestore.collection("Users").whereNotEqualTo("uid", firebaseAuth.getUid());
FirestoreRecyclerOptions<firebasemodel> allusername = new FirestoreRecyclerOptions.Builder<firebasemodel>().setQuery(query, firebasemodel.class).build();
chatAdapter = new FirestoreRecyclerAdapter<firebasemodel, NoteViewHolder>(allusername) {
#Override
protected void onBindViewHolder(#NonNull NoteViewHolder noteViewHolder, int i, #NonNull firebasemodel firebasemodel) {
for (String m : getcontactList) {
if (firebasemodel.getContact().equals(m)) {
noteViewHolder.particularusername.setText(firebasemodel.getName());
String uri = firebasemodel.getImage();
Picasso.get().load(uri).into(imageViewOfUser);
if (firebasemodel.getStatus().equals("Online")) {
noteViewHolder.statusofuser.setText(firebasemodel.getStatus());
noteViewHolder.statusofuser.setTextColor(Color.rgb(66, 133, 244));
} else {
noteViewHolder.statusofuser.setText(firebasemodel.getStatus());
}
noteViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(), "Clicked on particular user", Toast.LENGTH_SHORT).show();
}
});
} else {
//else code?
}
}
}
#NonNull
#Override
public NoteViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chatviewlayout, parent, false);
return new NoteViewHolder(view);
}
};
recyclerView.setHasFixedSize((true));
linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(chatAdapter);
return view;
}
public class NoteViewHolder extends RecyclerView.ViewHolder{
private TextView particularusername;
private TextView statusofuser;
public NoteViewHolder(#NonNull View itemView) {
super(itemView);
particularusername = itemView.findViewById(R.id.nameofuser);
statusofuser = itemView.findViewById(R.id.statusofuser);
imageViewOfUser = itemView.findViewById(R.id.imageviewofuser);
}
}
//-----------------------------------------------------------------------------------------------//
#Override
public void onStart() {
super.onStart();
chatAdapter.startListening();
}
#Override
public void onStop() {
super.onStop();
if(chatAdapter!=null){
chatAdapter.stopListening();
}
}
//-----------------------------------------------------------------------------------------//
private ArrayList<String> getContactList(){
Cursor phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
while (phones.moveToNext()){
String phone = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NORMALIZED_NUMBER));
contactList.add(phone);
}
return contactList;
}
}
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 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);
I try to passing data from cardview when clicked to DetailFragment, in this case I try to use interface in my adapter, but I get an error a null object reference in mOnItemClickListener.onClick(i).
I try to passing data from cardview when clicked to DetailFragment, in this case I try to use interface in my adapter.
I want to passing data to DetailMoviesFragment Class.
this is my CardviewMovieAdapter Class
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import java.util.ArrayList;
public class CardviewMovieAdapter extends RecyclerView.Adapter<CardviewMovieAdapter.CardViewViewHolder> {
private ArrayList<Movie> listMovie;
Context context;
OnItemClickListener mOnItemClickListener;
public void setListMovie(ArrayList<Movie> listMovie) {
this.listMovie = listMovie;
}
public ArrayList<Movie> getListMovie() {
return listMovie;
}
public interface OnItemClickListener {
void onClick(int position);
}
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mOnItemClickListener = mItemClickListener;
}
public CardviewMovieAdapter(ArrayList<Movie> listMovie, Context context) {
this.listMovie = listMovie;
this.context = context;
}
#NonNull
#Override
public CardviewMovieAdapter.CardViewViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_movie, viewGroup,false);
return new CardViewViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final CardviewMovieAdapter.CardViewViewHolder cardViewViewHolder, final int i) {
final Movie movie = listMovie.get(i);
Glide.with(cardViewViewHolder.itemView.getContext())
.load(movie.getImageMovie())
.apply(new RequestOptions().override(350, 550))
.into(cardViewViewHolder.imgPhoto);
cardViewViewHolder.tvTitle.setText(movie.getTitleMovie());
cardViewViewHolder.tvDesc.setText(movie.getDescription());
cardViewViewHolder.btnDetail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(cardViewViewHolder.itemView.getContext(), "Detail "+
listMovie.get(cardViewViewHolder.getAdapterPosition()).getTitleMovie(), Toast.LENGTH_SHORT).show();
}
});
cardViewViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(cardViewViewHolder.itemView.getContext(), "Kamu Memilih "+movie.getTitleMovie(), Toast.LENGTH_SHORT).show();
mOnItemClickListener.onClick(i);
}
});
// cardViewViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View v) {
// Toast.makeText(cardViewViewHolder.itemView.getContext(), "Kamu Memilih "+movie.getTitleMovie(), Toast.LENGTH_SHORT).show();
// }
// });
}
#Override
public int getItemCount() {
return listMovie.size();
}
public class CardViewViewHolder extends RecyclerView.ViewHolder {
ImageView imgPhoto;
TextView tvTitle, tvDesc;
Button btnDetail;
public CardViewViewHolder(#NonNull View itemView) {
super(itemView);
imgPhoto = itemView.findViewById(R.id.img_item_photo);
tvTitle = itemView.findViewById(R.id.tv_title);
tvDesc = itemView.findViewById(R.id.tv_desc);
btnDetail = itemView.findViewById(R.id.btn_detail);
}
}
}
This is my MoviesFragment Class
import android.content.Intent;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.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.ListView;
import java.util.ArrayList;
/**
* A simple {#link Fragment} subclass.
*/
public class MoviesFragment extends Fragment implements View.OnClickListener{
private RecyclerView rvMovie;
private String[] dataMovieTitle;
private String[] dataDescription;
private TypedArray dataPhoto;
private ArrayList<Movie> movies;
Button btnDetail;
private CardviewMovieAdapter adapter;
View view;
final static String KEY = "KEY";
public MoviesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_movies, container, false);
//adapter = new CardviewMovieAdapter(movies,getContext());
rvMovie = view.findViewById(R.id.rv_movies);
prepare();
addItem();
showRecyclerCardView();
adapter = new CardviewMovieAdapter(movies, getContext());
adapter.setOnItemClickListener(new CardviewMovieAdapter.OnItemClickListener() {
#Override
public void onClick(int position) {
final Movie movie = movies.get(position);
DetailMoviesFragment detailMoviesFragment = new DetailMoviesFragment();
// Bundle mBundle = new Bundle();
// mBundle.putString(detailMoviesFragment.EXTRA_TITLE, movie.getTitleMovie());
// mBundle.putString(detailMoviesFragment.EXTRA_DESCRIPTION, movie.getDescription());
// mBundle.putInt(detailMoviesFragment.EXTRA_PHOTO, movie.getImageMovie());
// detailMoviesFragment.setArguments(mBundle);
MoviesFragment.newInstance(movie.getTitleMovie(), movie.getDescription(), movie.getImageMovie());
FragmentManager mFragmentManager = getFragmentManager();
if (mFragmentManager!= null) {
FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.replace(R.id.containterFragment, detailMoviesFragment, DetailMoviesFragment.class.getSimpleName());
mFragmentTransaction.addToBackStack(null);
mFragmentTransaction.commit();
}
}
});
return view;
}
public static MoviesFragment newInstance(String title, String desc, int image) {
MoviesFragment moviesFragment = new MoviesFragment();
Bundle args = new Bundle();
args.putInt("image", image);
args.putString("title", title);
args.putString("desc", desc);
moviesFragment.setArguments(args);
return moviesFragment;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
private void showRecyclerCardView(){
rvMovie.setLayoutManager(new LinearLayoutManager(getActivity()));
CardviewMovieAdapter adapter = new CardviewMovieAdapter(movies,getActivity());
rvMovie.setAdapter(adapter);
}
private void prepare() {
dataMovieTitle = getResources().getStringArray(R.array.data_movie_name);
dataDescription = getResources().getStringArray(R.array.data_desc_movie);
dataPhoto = getResources().obtainTypedArray(R.array.data_photo_movie);
}
private void addItem(){
movies = new ArrayList<>();
for (int i=0; i < dataMovieTitle.length; i++){
Movie movie = new Movie();
movie.setImageMovie(dataPhoto.getResourceId(i, -1));
movie.setTitleMovie(dataMovieTitle[i]);
movie.setDescription(dataDescription[i]);
movies.add(movie);
}
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.card_view){
}
}
}
and this is DetailMoviesActivity Class
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
public class DetailMovieActivity extends AppCompatActivity {
Movie movie;
TextView tvTitle, tvDesc;
ImageView ivMovie;
Button btnDetail;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail_movie);
initView();
}
private void initView() {
movie = (Movie) getIntent().getSerializableExtra("informasi");
String judul = movie.getTitleMovie();
String desc = movie.getDescription();
int img = movie.getImageMovie();
tvTitle.setText(judul);
tvDesc.setText(desc);
Picasso.get().load(img).into(ivMovie);
}
}
You can try with delete the setOnItemClickListener and call intent from cardViewViewHolder.itemView.setOnClickListener
I am trying to implement the custom list view in tabbed activity for youtube video playing app. I could not able to call custom listview adapter in fragment java class. I have tried to pass getActivity() to custom adapter but the app crashes. If any one know the solution please help me.
The java class are as follows:
HomeFragment.java
package layout;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
import in.testapp.app1.R;
public class HomeFragment extends Fragment {
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList();
private final List<String> mFragmentTitleList = new ArrayList();
public Adapter(FragmentManager manager) {
super(manager);
}
public Fragment getItem(int position) {
return (Fragment) this.mFragmentList.get(position);
}
public int getCount() {
return this.mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
this.mFragmentList.add(fragment);
this.mFragmentTitleList.add(title);
}
public CharSequence getPageTitle(int position) {
return (CharSequence) this.mFragmentTitleList.get(position);
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
ViewPager viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
((TabLayout) view.findViewById(R.id.tablayout)).setupWithViewPager(viewPager);
return view;
}
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getChildFragmentManager());
adapter.addFragment(new YouTubeFragment(), "Tab 1");
adapter.addFragment(new SecondFragment(), "Tab 2");
viewPager.setAdapter(adapter);
}
}
YouTubeFragment.java
package layout;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings.PluginState;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import in.testapp.app1.AppUtils;
import in.testapp.app1.ChannelActivity;
import in.testapp.app1.CustomListAdapter;
import in.testapp.app1.R;
import in.testapp.app1.VideoDetails;
public class YouTubeFragment extends Fragment {
String TAG="MainActivity2";
ListView lvVideo;
ArrayList<VideoDetails> videoDetailsArrayList;
CustomListAdapter customListAdapter;
//{youtube_api_key} is replaced by actual key
String URL="https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=UC5Eg6bkwsdCd-ZlcB3nt1dg&maxResults=25&key={youtube_api_key}";
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_you_tube, container, false);
lvVideo=(ListView)view.findViewById(R.id.videoList);
videoDetailsArrayList=new ArrayList<>();
//App crashes here in the beolw line
customListAdapter=new CustomListAdapter(getActivity(),videoDetailsArrayList);
//App crashes here in the above line
showVideo();
return view;
}
private void showVideo() {
RequestQueue requestQueue= Volley.newRequestQueue(getContext());
StringRequest stringRequest=new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject=new JSONObject(response);
JSONArray jsonArray=jsonObject.getJSONArray("items");
for(int i=1;i<jsonArray.length();i++){
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
JSONObject jsonVideoId=jsonObject1.getJSONObject("id");
JSONObject jsonsnippet= jsonObject1.getJSONObject("snippet");
JSONObject jsonObjectdefault = jsonsnippet.getJSONObject("thumbnails").getJSONObject("medium");
VideoDetails videoDetails=new VideoDetails();
String videoid=jsonVideoId.getString("videoId");
Log.e(TAG," New Video Id" +videoid);
videoDetails.setURL(jsonObjectdefault.getString("url"));
videoDetails.setVideoName(jsonsnippet.getString("title"));
videoDetails.setVideoDesc(jsonsnippet.getString("description"));
videoDetails.setVideoId(videoid);
videoDetailsArrayList.add(videoDetails);
}
lvVideo.setAdapter(customListAdapter);
customListAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
int socketTimeout = 30000;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy);
requestQueue.add(stringRequest);
}
}
CustomListAdapter.java
package in.testapp.app1;
import android.app.Activity;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.NetworkImageView;
import java.util.ArrayList;
public class CustomListAdapter extends BaseAdapter {
Activity activity;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
private LayoutInflater inflater;
ArrayList<VideoDetails> singletons;
public CustomListAdapter(Activity activity, ArrayList<VideoDetails> singletons) {
this.activity = activity;
this.singletons = singletons;
}
public int getCount() {
return this.singletons.size();
}
public Object getItem(int i) {
return this.singletons.get(i);
}
public long getItemId(int i) {
return (long) i;
}
public View getView(int i, View convertView, ViewGroup viewGroup) {
if (this.inflater == null) {
this.inflater = (LayoutInflater) this.activity.getLayoutInflater();
// getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
if (convertView == null) {
convertView = this.inflater.inflate(R.layout.videolist, null);
}
if (this.imageLoader == null) {
this.imageLoader = AppController.getInstance().getImageLoader();
}
NetworkImageView networkImageView = (NetworkImageView) convertView.findViewById(R.id.video_image);
final TextView imgtitle = (TextView) convertView.findViewById(R.id.video_title);
final TextView imgdesc = (TextView) convertView.findViewById(R.id.video_descriptio);
final TextView tvURL=(TextView)convertView.findViewById(R.id.tv_url);
final TextView tvVideoID=(TextView)convertView.findViewById(R.id.tv_videoId);
((LinearLayout) convertView.findViewById(R.id.asser)).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent=new Intent(view.getContext(), VideoActivity.class);
intent.putExtra("videoId",tvVideoID.getText().toString());
view.getContext().startActivity(intent);
}
});
VideoDetails singleton = (VideoDetails) this.singletons.get(i);
networkImageView.setImageUrl(singleton.getURL(), this.imageLoader);
tvVideoID.setText(singleton.getVideoId());
imgtitle.setText(singleton.getVideoName());
imgdesc.setText(singleton.getVideoDesc());
return convertView;
}
}
VideoDeatils.java
package in.testapp.app1;
public class VideoDetails {
String VideoName;
String VideoDesc;
String URL;
String VideoId;
public void setVideoName(String VideoName){
this.VideoName=VideoName;
}
public String getVideoName(){
return VideoName;
}
public void setVideoDesc(String VideoDesc){
this.VideoDesc=VideoDesc;
}
public String getVideoDesc(){
return VideoDesc;
}
public void setURL(String URL){
this.URL=URL;
}
public String getURL(){
return URL;
}
public void setVideoId(String VideoId){
this.VideoId=VideoId;
}
public String getVideoId(){
return VideoId;
}
}