This is the code and this is the error message and i don't know what i do
so what can you do for it
so what is the error means i don't know.
That all i know and i dont know what should i do for this kind of problem so if it possible to fix it or someone know how can i run it correctly so go a head.
The error shown in image: https://i.stack.imgur.com/QJl7o.png
And this is the menuviewholder:
public class MenuViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView txtMenuName;
public ImageView imageView;
private ItemClickListener itemClickListener;
public MenuViewHolder(View itemView){
super(itemView);
txtMenuName = (TextView)itemView.findViewById(R.id.menu_name);
imageView = (ImageView)itemView.findViewById(R.id.menu_image);
itemView.setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public void onClick(View view)
{
itemClickListener.onClick(view,getAdapterPosition(),false);
}
}
https://i.stack.imgur.com/f6hEF.png
Here is the load part of it and the firbaserec:
Load menu
recycler_menu =(RecyclerView)findViewById(R.id.recycler_menu);
recycler_menu.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
recycler_menu.setLayoutManager(layoutManager);
loadMenu();
}
private void loadMenu()
{
FirebaseRecyclerAdapter<Category, MenuViewHolder>
adapter =new FirebaseRecyclerAdapter <Category, MenuViewHolder>(Category.class,menu_item,MenuViewHolder.class,categorys) {
#Override
protected void onBindViewHolder(#NonNull MenuViewHolder holder, int position, #NonNull Category model) {
holder.txtMenuName.setText(model.getName());
Picasso.get().load(model.getImage()).into(holder.imageView);
final Category clickItem = model;
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View viw, int position, boolean isLongClick) {
Toast.makeText(Home.this, ""+clickItem.getName(), Toast.LENGTH_SHORT).show();
}
});
}
#NonNull
#Override
public MenuViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return null;
}
};
recycler_menu.setAdapter(adapter);
}
The problem is that the latest version (3.x) of FirebaseUI implements a different method of initializing a FirebaseRecyclerAdapter than previous versions.
Read this for more clarification about this FirebaseUI docs.
From the docs, you can understand everything, but in brief:
First, configure the adapter by building FirebaseRecyclerOptions. I have used the same example from the docs.
FirebaseRecyclerOptions<Chat> options =
new FirebaseRecyclerOptions.Builder<Chat>()
.setQuery(query, Chat.class)
.build();
Next create the FirebaseRecyclerAdapter object. You should already have a ViewHolder subclass for displaying each item. You should be able to do it now.
Related
I have been getting certain issues with the onDataChange method when I am calling from Firebase Realtime Database. These issues would include data disappearing outside of the DataChange method. I tried a solution from this link,
How to return DataSnapshot value as a result of a method?, it has worked, however, when I tried passing it to a fragment bundle within the callback method, it says the values are null and there isn't any data in it. Is there any workaround for this problem that I am facing? Help is really appreciated, thanks!
import edu.ntu.ssp4_rzdns_outhink.R;
import edu.ntu.ssp4_rzdns_outhink.modals.Attraction;
public class MostPopularRecyclerViewAdapter extends RecyclerView.Adapter<MostPopularRecyclerViewAdapter.ViewHolder>{
private static final String TAG = "MostPopularRecyclerViewAdapter";
private static final String SHARED_PREFS = "attractionsFile";
private ArrayList<Attraction> pops;
private Attraction attraction;
private Context mContext;
private FragmentManager fm;
private Bundle bundle;
SharedPreferences.Editor editor;
SharedPreferences attractionFile;
public MostPopularRecyclerViewAdapter(ArrayList<Attraction> pops, Context mContext, FragmentManager fm, Bundle bundle) {
this.pops = pops;
this.mContext = mContext;
this.fm = fm;
this.bundle = bundle;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Log.d(TAG, "OnCreateViewHolder Called");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_more_list, parent, false);
ViewHolder holder = new ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder Called");
Glide.with(mContext).asBitmap().load(pops.get(position).photo_url).into(holder.attractionImage);
holder.locationName.setText(pops.get(position).att_name);
holder.locationRating.setText(pops.get(position).att_rating.toString());
holder.locationAddress.setText(pops.get(position).att_address);
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String attraction_id = pops.get(holder.getBindingAdapterPosition()).id;
readData(new FirebaseCallback() {
#Override
public void onCallBack(Attraction attr) {
bundle.putString("attid", attr.id);
bundle.putString("name", attr.att_name);
bundle.putString("address", attr.att_address);
bundle.putString("desc", attr.att_desc);
bundle.putDouble("rating", attr.att_rating);
bundle.putString("url", attr.att_url);
bundle.putSerializable("ophrs", attr.att_op_hr);
bundle.putSerializable("adminrate",attr.att_admin_rate);
bundle.putString("photo_url", attr.photo_url);
}
},attraction_id);
}
});
}
#Override
public int getItemCount() {
return pops.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
ImageView attractionImage;
TextView locationName;
TextView locationAddress;
TextView locationRating;
RelativeLayout parentLayout;
public ViewHolder(#NonNull View itemView){
super(itemView);
attractionImage = itemView.findViewById(R.id.viewmoreImage);
locationName = itemView.findViewById(R.id.viewmoreName);
locationAddress = itemView.findViewById(R.id.viewmoreLocation);
locationRating = itemView.findViewById(R.id.viewmoreRating);
parentLayout = itemView.findViewById(R.id.parent_layout_view_more);
}
}
private void readData(FirebaseCallback firebaseCallback, String attrId){
Query query = FirebaseDatabase.getInstance().getReference("attractions");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (!snapshot.exists()) {
System.out.println("Attraction Does Not Exist");
} else {
for (DataSnapshot attr : snapshot.getChildren()) {
if (attr.getKey().equals(attrId)) {
attraction = attr.getValue(Attraction.class);
attraction.setId(attr.getKey());
}
}
firebaseCallback.onCallBack(attraction);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private interface FirebaseCallback{
void onCallBack(Attraction attraction);
}
}
According to your last comment:
When I try to put these variables in the bundle, it’ll just disappear and become null.
Please note that this is the expected behavior. There are multiple inconsistencies in your code. First of all, that's not how you should handle the click event in your adapter class. Attaching a click listener to each element you display, isn't a feasible solution. You should create an interface for that as you can see in this repo.
Now, each time you click a particular element in your RecyclerView, you call the readData() method. When you receive the data, you add that data to the Bundle. The problem is that the operation that is opening the new fragment is happening faster than you get the data from the database. That's the reason why you are getting null.
To solve this, you either navigate to the next fragment, only when the data is available or you can make another call, right from the second fragment.
I'm trying to show the selected items in another view and I can't get the key using getRef method. How should I get the key to pass the data? I tried to find similar solutions on StackOverflow but just can't find it...
This is my onBindViewHolder:
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
Upload uploadCurrent = mUploads.get(position);
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
final String productKey = getRef(position).getKey();
holder.textViewName.setText(uploadCurrent.getName());
//Picasso.with(mContext).load(uploadCurrent.getmImageUrl()).fit().centerCrop().into(holder.imageView);
Glide.with(mContext).asBitmap().load(uploadCurrent.getmImageUrl()).into(holder.imageView);
holder.v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mContext, SingleProductActivity.class);
i.putExtra("ProductKey", productKey);
mContext.startActivity(i);
}
});
}
And my class where I'm trying to show upload data.
String productKey = getIntent().getStringExtra("ProductKey");
mDatabaseRef.child(productKey).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()){
String productName = snapshot.child("mName").getValue().toString();
String productDesc = snapshot.child("mDescription").getValue().toString();
String imageUrl = snapshot.child("mImageUrl").getValue().toString();
productDescriptionTxt.setText(productDesc);
singleProductNameTxt.setText(productName);
productPriceTagTxt.setText("100");
Glide.with(mContext).asBitmap().load(imageUrl).into(singleProductImg);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Here is my whole adapter
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> {
private Context mContext;
private List<Upload> mUploads;
private String link;
private DatabaseReference mDatabaseRef;
public ImageAdapter(Context context, List<Upload> uploads) {
this.mContext = context;
this.mUploads = uploads;
}
#NonNull
#Override
public ImageViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.product_item, parent, false);
return new ImageViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ImageViewHolder holder, int position) {
Upload uploadCurrent = mUploads.get(position);
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads");
final String productKey = getRef(position).getKey();
holder.textViewName.setText(uploadCurrent.getName());
//Picasso.with(mContext).load(uploadCurrent.getmImageUrl()).fit().centerCrop().into(holder.imageView);
Glide.with(mContext).asBitmap().load(uploadCurrent.getmImageUrl()).into(holder.imageView);
holder.v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(mContext, SingleProductActivity.class);
i.putExtra("ProductKey", productKey);
mContext.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return mUploads.size();
}
public class ImageViewHolder extends RecyclerView.ViewHolder{
public TextView textViewName;
public ImageView imageView;
private CardView parent;
private View v;
public ImageViewHolder(#NonNull View itemView) {
super(itemView);
parent = itemView.findViewById(R.id.parent);
textViewName = itemView.findViewById(R.id.productNameTxt);
imageView = itemView.findViewById(R.id.productImg);
//v označava jedan prikazan item
v = itemView;
}
}
}
As I see, your ImageAdapter class extends RecyclerView.Adapter. That being said, you are getting the following error:
Cannot resolve method 'getRef' in 'ImageAdapter'.
Because the RecyclerView.Adapter class doesn't contain any getRef() method inside it, hence the error. However, FirebaseRecyclerAdapter does. As you can see, the getRef() method is present in the FirebaseRecyclerAdapter class and not in the RecyclerView.Adapter class.
To solve this, you either adapt to the code of the Firebase-UI library, or you keep using the RecyclerView.Adapter and get the "productKey" like so:
Upload uploadCurrent = mUploads.get(position);
String productKey = uploadCurrent.getProductKey();
But this will only work if you have the productKey as a field inside the Upload class. If you don't have it yet, add it and populate it when you add data to the database.
I've got a RecyclerView that needs to update in real-time when content is received. It successfully shows all the content at first load. When attempting to add a new item dynamically, it makes no difference. Is there anything I'm doing wrong here? Much appreciated!
MainActivity:
RecyclerView rvClips;
ClipboardRVAdapter adapter;
ArrayList<Clip> clips = new ArrayList<>();
private void SetupRV() {
adapter = new ClipboardRVAdapter(clips);
rvClips.setAdapter(adapter);
adapter.setClickListener(this);
rvClips.setLayoutManager(new LinearLayoutManager(getActivity()));
}
//this method gets called everytime a new item is received. I confirmed that it gets called.
public void OnNewClipReceived(Clip clip) {
clips.add(0, clip);
adapter.notifyItemInserted(0);
}
Adapter:
Standard adapter code. Simply shows all the items in the recyclerview.
public class ClipboardRVAdapter extends RecyclerView.Adapter<ClipboardRVAdapter.ViewHolder> {
private ItemClickListener mClickListener;
ArrayList<Clip> clips;
public ClipboardRVAdapter(ArrayList<Clip> clips) {
this.clips = clips;
}
public void setClickListener(ItemClickListener itemClickListener) {
this.mClickListener = itemClickListener;
}
public interface ItemClickListener {
void onItemClick(View view, int position);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
// Inflate the custom layout
View contactView = inflater.inflate(R.layout.item_clipboard_clip, parent, false);
// Return a new holder instance
ViewHolder viewHolder = new ViewHolder(contactView);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
Clip clip = clips.get(position);
holder.tvClipTitle.setText(clip.content);
}
#Override
public int getItemCount() {
return clips.size();
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView tvClipTitle;
public ViewHolder(View itemView) {
super(itemView);
tvClipTitle = itemView.findViewById(R.id.tvClipTitle);
}
#Override
public void onClick(View view) {
if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
}
}
}
Since you mentioned 'realtime', I'm guessing this could be a thread issue. Your code seems correct. It could be that the adapter needs to be refreshed in a runOnUiThread function. Try this:
public void OnNewClipReceived(Clip clip) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
clips.add(0, clip);
adapter.notifyItemInserted(0);
}
});
}
You would need this method in your RecyclerView adapter.
void addNewClip(Clip clip, int index) {
this.clips.add(index, clip);
notifyItemInserted(index);
}
Adding to clips(MainActivity's) won't make a difference because your adapter has it own ArrayList to work with.
I am new to Android Studio..so please help me out.
I am working on app which shows the list of student in recycler view,I am retriving the list from Fire base Database but i'm getting the error at UserAdapter constructor class (I don't know what to provide in Super()).
I have used standard RecyclerAdapter it work the way I wanted but I couldn't get the UID of student when person clicks on it ....so I switched to FirebaseRecyclerAdapter ...here I can retrive the UID easily ...but getting error at constructor of UserAdapter.
I think I have to pass the FirebaseRecyclerOptions in my case its "options" but its show error
"Cannot reference 'UserAdapter.options' before supertype constructor has been called" and I don't know how to make the options Static.
I tried to make it static like this
public static FirebaseRecyclerOptions options;
in classmates class and accessed it in super() as super(classmates.this.options);i know its wrong method and then I declared in UserAdapter class but didnt work.
sorry for the long post.please help me out.
Here's the code:
public class classmates extends AppCompatActivity {
Toolbar toolbar;
private RecyclerView ClassmateList;
private DatabaseReference rDatabaseRef;
List<Users> list = new ArrayList<>();
FirebaseRecyclerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_classmates);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Classmates");
rDatabaseRef = FirebaseDatabase.getInstance().getReference().child("user");
ClassmateList = (RecyclerView) findViewById(R.id.recyclerView);
ClassmateList.setHasFixedSize(true);
ClassmateList.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
rDatabaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot Snapshot) {
for (DataSnapshot dataSnapshot : Snapshot.getChildren()) {
Users studentDetails = dataSnapshot.getValue(Users.class);
list.add(studentDetails);
}
adapter = new UserAdapter(list, classmates.this);
ClassmateList.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
public class UserAdapter extends FirebaseRecyclerAdapter<Users, UserAdapter.UserViewHolder> {
Context context1;
List<Users> InfoList;
FirebaseRecyclerOptions<Users> options =
new FirebaseRecyclerOptions.Builder<Users>()
.setQuery(rDatabaseRef, Users.class)
.build();
public UserAdapter(List<Users> list, classmates classmates) {
super(); *<---ERROR ,DONT KNOW WHAT TO PROVIDE*
context1=classmates;
InfoList=list;
}
#Override
protected void onBindViewHolder(#NonNull UserViewHolder holder, int position, #NonNull Users model) {
final Users users = InfoList.get(position);
holder.setName(users.getName());
holder.setStatus(users.getStatus());
holder.setThumb_img(users.getThumb_img());
String userid=getRef(position).getKey();
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_singlelayout, parent, false);
UserViewHolder holder = new UserViewHolder(view);
return holder;
}
#Override
public int getItemCount() {
return InfoList.size();
}
public class UserViewHolder extends RecyclerView.ViewHolder {
View rview;
public UserViewHolder(View itemView) {
super(itemView);
rview = itemView;
}
public void setName(String name) {
TextView singleusername = (TextView) rview.findViewById(R.id.single_displayname);
singleusername.setText(name);
}
public void setStatus(String status) {
TextView singleuserstatus = (TextView) rview.findViewById(R.id.single_status);
singleuserstatus.setText(status);
}
public void setThumb_img(String thumb_image) {
CircleImageView user_img = (CircleImageView) rview.findViewById(R.id.single_thumb_image);
Picasso.get().load(thumb_image).placeholder(R.drawable.default_img).into(user_img);
}
}
}
}
I'm trying to retrieve data from Firebase to Recyclerview. I've already implement all other steps but now i'm getting error at the last stage when i'm implementing the adapter(FirebaseRecyclerAdapter).
My Fragment
public class Journal extends Fragment {
RecyclerView recyclerView;
DatabaseReference myref;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_journal,container,false);
myref= FirebaseDatabase.getInstance().getReference("/Journal");
recyclerView = (RecyclerView) v.findViewById(R.id.journal_rv);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
FirebaseRecyclerAdapter<JournalEntry, JournalHolder> adapter = new FirebaseRecyclerAdapter<JournalEntry, JournalHolder>(
JournalEntry.class,
R.layout.journal_list_item,
JournalHolder.class,
myref) {
#Override
protected void onBindViewHolder(JournalHolder holder, int position, JournalEntry model) {
holder.setTitle(model.getEvent_title());
holder.setContent(model.getEvent_content());
holder.setSchool(model.getSchool_name());
holder.setDate(model.getDate());
holder.setStudents(model.getNumber_of_students());
holder.setSchoolIv(model.getImg_url());
}
#Override
public JournalHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
};
return v;
}
public static class JournalHolder extends RecyclerView.ViewHolder{
TextView Jtitle , Jcontent,Jschool,Jstudents,jdate;
ImageView schoolIV;
public JournalHolder(View itemView) {
super(itemView);
Jtitle =(TextView)itemView.findViewById(R.id.journal_title);
Jcontent =(TextView)itemView.findViewById(R.id.event_content);
Jschool =(TextView)itemView.findViewById(R.id.journal_school);
Jstudents =(TextView)itemView.findViewById(R.id.journal_students);
jdate = (TextView)itemView.findViewById(R.id.journal_dates) ;
schoolIV = (ImageView)itemView.findViewById(R.id.journal_image);
}
public void setTitle(String title) {
Jtitle.setText(title);
}
public void setContent(String content) {
Jcontent.setText(content);
}
public void setSchool(String school) {
Jschool.setText(school);
}
public void setDate(String date) {
jdate.setText(date);
}
public void setStudents(String students) {
Jstudents.setText(students);
}
public void setSchoolIv(String schoolIv) {
Picasso.with(itemView.getContext())
.load(schoolIv)
.into(schoolIV);
}
}
}
This is what is shown as error
FireBaseRecyclerView in FirebaseRecyclerView can not be applied to :
JournalEntry.class (java...consti.last.database.JournalEntry>)
R.layout.journal_list_item (int)
BlogViewHolder.class (java...consti.last.Journal.BlogViewHolder>)
myref (com...firebase.database.DatabaseReference)
Please help me. I tried all the methods but nothing works.
Or if you have any advice...thank you in advance.
PS : I'm using Fragments
under Activity declaration write:-
private FirebaseRecyclerAdapter<JournalEntry, JournalHolder> adapter;
then inside onCreateView():
adapter = new FirebaseRecyclerAdapter<JournalEntry, JournalHolder>(
JournalEntry.class,
R.layout.journal_list_item,
JournalHolder.class,
myref) { //be sure that these classes and parameters are correct..
above return v;:
recyclerView.setAdapter(adapter);
Use this method instead of onBindViewHolder:
#Override
protected void populateViewHolder(JournalHolder holder,JournalEntry model, int position) {
Be sure you have all the correct methods in the model class JournalEntry.class and holder class JournalHolder.class and that its the right location and right layout.
I finally found solution here:Firebase RecyclerView
I had the same problem.
In this version FirebaseResycleView use the following:
Query query = FirebaseDatabase.getInstance()
.getReference(); // you can add child as .child("child_name");
FirebaseRecyclerOptions<JournalEntry> options = new FirebaseRecyclerOptions.Builder<JournalEntry>()
.setQuery(query, JournalEntry.class)
.build();
FirebaseRecyclerAdapter<JournalEntry, JournalHolder> adapter = new FirebaseRecyclerAdapter<JournalEntry, JournalHolder>(
options) {
#Override
protected void onBindViewHolder(JournalHolder holder, int position, JournalEntry model) {
holder.setTitle(model.getEvent_title());
holder.setContent(model.getEvent_content());
holder.setSchool(model.getSchool_name());
holder.setDate(model.getDate());
holder.setStudents(model.getNumber_of_students());
holder.setSchoolIv(model.getImg_url());
}
#Override
public JournalHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.journal_list_item, parent, false);
return new JournalHolder(view);
}
};
And after don't forget:
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
adapter.startListening();