everyone, I was trying to make a music app, and for this, I Created a Horizontal RecyclerView in my HomeFragment and my horizontal RecyclerView is getting an image with artist name.
But after clicking I load another Activity. In my other activity, I was trying to load SongsData from firebase in a listView with RecyclerView.
But the problem is I am not getting data from Firebase and it is returning null data. I provided my code below and here is the screenshot of my Firebase database:- ScreenShot
My List Class:-
public class TestUploads
{
private String songName;
private String songImageUri;
private String songUrl;
private String artistName;
public TestUploads() {
}
public String getSongName() {
return songName;
}
public void setSongName(String SongName) {
this.songName = SongName;
}
public String getSongImageUri() {
return songImageUri;
}
public void setSongImageUri(String SongImageUri) {
this.songImageUri = SongImageUri;
}
public String getSongUrl() {
return songUrl;
}
public void setSongUrl(String SongUrl) {
this.songUrl = songUrl;
}
public TestUploads(String SongImageUri, String SongName, String SongUrl ) {
this.songName = SongName;
this.artistName = SongImageUri;
this.songUrl = SongUrl;
}
}
My Adapter Class:-
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestViewHolder>{
private Context mContext;
private List<TestUploads> mUploads;
public TestAdapter(Context context , List<TestUploads> uploads) {
mContext = context;
mUploads = uploads;
}
#NonNull
#Override
public TestViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.test_package_layout , parent ,false);
return new TestViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull TestViewHolder holder, int position) {
TestUploads uploadcurrent = mUploads.get(position);
holder.name.setText(uploadcurrent.getSongName());
Glide.with(mContext)
.load(uploadcurrent.getSongImageUri())
.into(holder.image_view);
}
#Override
public int getItemCount() {
return mUploads
.size();
}
public class TestViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView artist_name;
public CircleImageView image_view;
public TestViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.test_package_song_name);
artist_name = itemView.findViewById(R.id.test_package_artist_name);
image_view = itemView.findViewById(R.id.test_package_image_name);
}
}
}
My Activity:-
public class TestActivity extends AppCompatActivity {
private ValueEventListener listener;
private DatabaseReference reference;
private List<TestUploads> mUploads;
private RecyclerView mRecyclerView;
private TestAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_package_activity);
reference = FirebaseDatabase.getInstance().getReference("ArtistView").child(getIntent().getStringExtra("Artist"))
.child("Songs");
Toast.makeText(this, "" + getIntent().getStringExtra("Artist"), Toast.LENGTH_SHORT).show();
mUploads = new ArrayList<>();
mRecyclerView = findViewById(R.id.test_pacakge_recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.smoothScrollToPosition(0);
adapter = new TestAdapter(this , mUploads);
mRecyclerView.setAdapter(adapter);
listener = reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUploads.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
TestUploads uploads =postSnapshot.getValue(TestUploads.class);
mUploads.add(uploads);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Sorry for so much code but this is not hard to solve. If you find the solution please reply to me. Thanks for reading this.
The problem in your code lies in the fact that the names of the fields in your TestUploads class are different than the name of the properties in your database. You have in your TestUploads class a field named songName but in your database, I see it as SongName and this is not correct. The names must match. When you are using a getter named getSongName(), Firebase is looking in the database for a field named songName and not SongName. See the lowercase s letter vs. capital letter S?
There are two ways in which you can solve this problem. The first one would be to remove the data in your database and add it again using field names that start with lowercase, as exist in your TestUploads class.
If you are not allowed to use the first solution, then the second approach will be to use annotations. So you should use the PropertyName annotation in front of the getters. So in your TestUploads class, a getter should look like this:
#PropertyName("SongName")
public String getSongName() {
return songName;
}
Related
I have passed data from my Activity to My Adapter. When I debug, I can see the correct data has successfully passed to my adapter, but when I attempt to use it as a string ( for example, if I want to set the text as the data I just passed), it shows as null.
On the line that says " this.uniquesharedIds = uniquesharedId;" - the "uniqiuesharedIds" is showing as null.
"uniquesharedId" shows has the successfully passed data.
I need to be able to use the string of "uniqiuesharedIds."
Sorry if this is a silly question. Sending data from Activities to Adapters always confuses me and Im not able to find a ton of documentation/videos on the topic. Thank you.
My Activity In the On Create Method
myadapter = new Invite_Contributors_Adapter(contributorInviteList, getIntent().getStringExtra("uniquesharedId"));
The Adapter
public class Invite_Contributors_Adapter extends RecyclerView.Adapter<Invite_Contributors_Adapter.myviewholder> {
private ArrayList<Model_Invite_Contributors_List> model_invite_contributors_lists = new ArrayList<>();
FirebaseAuth mAuth;
private FirebaseUser currentuser;
private DatabaseReference UsersReference;
Context context;
String uniquesharedIds;
private InviteContributorsInterface inviteContributorsInterface;
public Invite_Contributors_Adapter() {
}
public void updateInviteList (ArrayList list) {
model_invite_contributors_lists .clear();
model_invite_contributors_lists .addAll(list);
notifyDataSetChanged();
}
public Invite_Contributors_Adapter(ArrayList<Model_Invite_Contributors_List>model_invite_contributors_lists, String uniquesharedId) {
this.model_invite_contributors_lists = model_invite_contributors_lists;
this.uniquesharedIds = uniquesharedId;
}
#NonNull
#Override
public Invite_Contributors_Adapter.myviewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout_invite_contributors_list, parent, false);
return new myviewholder(view);
}
#Override
public void onBindViewHolder(#NonNull myviewholder holder, int position) {
holder.setData(model_invite_contributors_lists.get(position));
mAuth = FirebaseAuth.getInstance();
holder.Name.setText(uniquesharedIds);
}
#Override
public int getItemCount() {
return model_invite_contributors_lists.size();
}
static class myviewholder extends RecyclerView.ViewHolder implements DialogInterface.OnClickListener {
TextView Name;
CircleImageView profileImageView;
public myviewholder(#NonNull View itemView) {
super(itemView);
Name = itemView.findViewById(R.id.contributor_name);
profileImageView = itemView.findViewById(R.id.member_profile_picture);
}
#Override
public void onClick(DialogInterface dialog, int which) {
}
public void setData(Model_Invite_Contributors_List model) {
FirebaseUser currentuser;
currentuser = FirebaseAuth.getInstance().getCurrentUser();
DatabaseReference NameRef = FirebaseDatabase.getInstance().getReference(Strings.UsersReference);
NameRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
//this is very important. this says to not show the current user in the list of people to invite as a contributor.//
if (currentuser.getUid().equals(model.getUser_Id())){
ViewGroup.LayoutParams params = itemView.getLayoutParams();
params.height = 0;
itemView.setLayoutParams(params);
} else {
for(DataSnapshot ds : dataSnapshot.getChildren())
{
itemView.setVisibility(View.VISIBLE);
String profileImageString;
profileImageString = model.getProfileimage();
Glide.with(profileImageView.getContext()) //pulling in image and telling the image which imageview to go to once it comes in from the database
.load(profileImageString)
.placeholder(R.drawable.circle_placeholder)
.error(R.drawable.circle_placeholder)
.into(profileImageView);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
public void setInterface (Invite_Contributors_Adapter.InviteContributorsInterface inviteContributorsInterface) {
this.inviteContributorsInterface = inviteContributorsInterface;
}
public interface InviteContributorsInterface{
}
}
Are you using any primary constructor of the adapter like this?
myadapter = new Invite_Contributors_Adapter();
If yes, then that's where the problem is. If you're initializing object with two different constructors then you'll get the value of the object which you initialized later.
Make sure to check the adapter object & then proceed.
Basically, what I am trying to do is use a FirebaseRecyclerAdapter and populate the RecyclerView with my custom designed CardView. The code for newer versions has been changed and therefore, I tried implementing it but didn't work.
This is the code I use to write a year ago, which worked fine and populated my RecyclerView:
FirebaseRecyclerAdapter<DataClass,DataViewHolder> FBRA= new FirebaseRecyclerAdapter<DataClass, DataViewHolder>(
DataClass,
R.layout.myCardView,
DataViewHolder.class,
databaseReference
) {
#Override
protected void populateViewHolder(DataViewHolder viewHolder, DataClass model, int position) {
viewHolder.setTitle(model.gettitle());
viewHolder.setDate(model.getDate());
}
};
myRecyclerView.setAdapter(FBRA);
And now we have to use something like this,
but the problem is this code is not populating my recyclerView (What changes do I need to make here to populate my recyclerView with my cardView?)
#Override
protected void onStart() {
super.onStart();
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("Official_Services");
FirebaseRecyclerOptions<ServiceClass> options = new FirebaseRecyclerOptions.Builder<ServiceClass>()
.setQuery(query, ServiceClass.class)
.build();
FirebaseRecyclerAdapter<ServiceClass, ServiceViewHolder> FBRA = new FirebaseRecyclerAdapter<ServiceClass, ServiceViewHolder>(options) {
#NonNull
#Override
public ServiceViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View view = LayoutInflater.from(HomeActivity.this).inflate(R.layout.service_card, parent, false);
return new ServiceViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull ServiceViewHolder holder, int position, #NonNull ServiceClass model) {
holder.setServiceName(model.getServiceName());
holder.setServiceCaption(model.getServiceCaption());
}
};
mServiceList.setAdapter(FBRA);
}
Here is my ViewHolder class:
public static class ServiceViewHolder extends RecyclerView.ViewHolder {
public ServiceViewHolder(View itemView) {
super(itemView);
View mView = itemView;
}
public void setServiceName(String serviceName) {
TextView sName = itemView.findViewById(R.id.serviceName);
sName.setText(serviceName);
}
public void setServiceCaption(String serviceCaption) {
TextView sCaption = itemView.findViewById(R.id.serviceCap);
sCaption.setText(serviceCaption);
}
}
And this is my Model class of getters and setters:
public class ServiceClass {
private String serviceName;
private String serviceCode;
private String serviceCaption;
private String serviceIconUrl;
public ServiceClass() {
}
public ServiceClass(String serviceName, String serviceCode, String serviceCaption, String serviceIconUrl) {
this.serviceName = serviceName;
this.serviceCode = serviceCode;
this.serviceCaption = serviceCaption;
this.serviceIconUrl = serviceIconUrl;
}
public String getServiceName() {
return serviceName;
}
public String getServiceCode() {
return serviceCode;
}
public String getServiceCaption() {
return serviceCaption;
}
public String getServiceIconUrl() {
return serviceIconUrl;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public void setServiceCode(String serviceCode) {
this.serviceCode = serviceCode;
}
public void setServiceCaption(String serviceCaption) {
this.serviceCaption = serviceCaption;
}
public void setServiceIconUrl(String serviceIconUrl) {
this.serviceIconUrl = serviceIconUrl;
}
#Override
public String toString() {
return "ServiceClass{" +
"serviceName='" + serviceName + '\'' +
", serviceCode='" + serviceCode + '\'' +
", serviceCaption='" + serviceCaption + '\'' +
", serviceIconUrl='" + serviceIconUrl + '\'' +
'}';
}
}
Now what changes do I need to do?
Here is my entire java file:
public class HomeActivity extends AppCompatActivity {
private RecyclerView mServiceList;
private FirebaseDatabase mDatabase;
private DatabaseReference myRef;
FirebaseRecyclerAdapter<ServiceClass, ServiceViewHolder> FBRA;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
BottomNavigationViewEx bottomNavigationViewEx = findViewById(R.id.navViewBar);
bottomNavigationViewEx.enableAnimation(false);
bottomNavigationViewEx.enableShiftingMode(false);
bottomNavigationViewEx.setTextVisibility(false);
Calligrapher calligrapher = new Calligrapher(this);
calligrapher.setFont(this, "Helvetica.ttf", true);
mServiceList = findViewById(R.id.serviceRV);
mServiceList.setHasFixedSize(true);
mServiceList.setLayoutManager(new LinearLayoutManager(this));
mDatabase = FirebaseDatabase.getInstance();
myRef = mDatabase.getReference().child("Official_Services");
}
#Override
protected void onStart() {
super.onStart();
FBRA.startListening();
Query query = myRef;
FirebaseRecyclerOptions<ServiceClass> options = new FirebaseRecyclerOptions.Builder<ServiceClass>()
.setQuery(query, ServiceClass.class)
.build();
FBRA = new FirebaseRecyclerAdapter<ServiceClass, ServiceViewHolder>(options) {
#NonNull
#Override
public ServiceViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View view = LayoutInflater.from(HomeActivity.this).inflate(R.layout.service_card, parent, false);
return new ServiceViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull ServiceViewHolder holder, int position, #NonNull ServiceClass model) {
holder.setServiceName(model.getServiceName());
holder.setServiceCaption(model.getServiceCaption());
}
};
mServiceList.setAdapter(FBRA);
}
public static class ServiceViewHolder extends RecyclerView.ViewHolder {
public ServiceViewHolder(View itemView) {
super(itemView);
View mView = itemView;
}
public void setServiceName(String serviceName) {
TextView sName = itemView.findViewById(R.id.serviceName);
sName.setText(serviceName);
}
public void setServiceCaption(String serviceCaption) {
TextView sCaption = itemView.findViewById(R.id.serviceCap);
sCaption.setText(serviceCaption);
}
}
}
In order to be able to display data from the Firebase realtime database you need to start listening for changes and for that you should add the following line of code in the onStart() method:
#Override
protected void onStart() {
super.onStart();
FBRA.startListening();
}
To stop listening foir changes you need add the following line of code in the onStop() method like this:
#Override
protected void onStop() {
super.onStop();
if(FBRA != null) {
FBRA.stopListening();
}
}
Please see my answer from this post where I have explained why you should remove the listener.
P.S. Please also don't forget to make the FBRA a global variable and remove FirebaseRecyclerAdapter<ServiceClass, ServiceViewHolder> from the declaration of the object.
This is more of an advice. If you want to continue using the old method to populate your
recyclerview ie The "populateViewHolder" method instead of the new "onBindViewHolder" method just use this;
implementation 'com.firebaseui:firebase-ui:1.0.1'
instead of upgraded firebase-ui versions
I was trying to make a Music Streaming app. I created an Activity called Display Activity. I make a horizontal RecyclerView in Display Activity. In my Firebase I created A node name 'ArtistView' which contains Artist List.
After that i load Artist image and Artist name in my Horizontal recyclerView like same as Spotify. There is another node in my firebase which contain songList of Artist. Now my main question is how to make function like when user click "Guri" artist from My RecyclerView then after clicking it loads list of his Songs in New Activity from Firebase like in Spotify if we click any Artist then it loads songs of Artist in New Activity. Here is the image of my Firebsae Database:-
Firebase Screenshot
If you underStand my question then Here is the Code:-
Display Activity:-
public class DisplayActivity extends AppCompatActivity {
private ArtistRecyclerView artistRecyclerView;
private DatabaseReference databaseReference;
private ValueEventListener eventListener;
private List<ArtistHoler> artistHolerList;
private RecyclerView recyclerView;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dispplay);
artistHolerList = new ArrayList<>();
artistRecyclerView = new ArtistRecyclerView(this , artistHolerList);
databaseReference = FirebaseDatabase.getInstance().getReference("ArtistView");
databaseReference.keepSynced(true);
recyclerView = findViewById(R.id.dispay_recycler_view);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this , LinearLayoutManager.HORIZONTAL , false);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(artistRecyclerView);
eventListener = databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()){
ArtistHoler artistHoler = snapshot.getValue(ArtistHoler.class);
artistHolerList.add(artistHoler);
}
artistRecyclerView.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Artist Adapter:-
public class ArtistRecyclerView extends RecyclerView.Adapter<ArtistRecyclerView.HolderOfArtist> {
private List<ArtistHoler> mHolder;
private Context mContext;
public ArtistRecyclerView(Context context, List<ArtistHoler> holder) {
mHolder = holder;
mContext = context;
}
#NonNull
#Override
public HolderOfArtist onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.resource, parent, false);
return new HolderOfArtist(view);
}
#Override
public void onBindViewHolder(#NonNull HolderOfArtist holder, int position) {
ArtistHoler artistHoler = mHolder.get(position);
String text1 = artistHoler.getName();
Glide.with(mContext)
.asBitmap()
.centerCrop()
.load(artistHoler.getImageUri())
.into(holder.image);
holder.image.setOnClickListener(view -> Toast.makeText(mContext, text1, Toast.LENGTH_SHORT).show());
holder.name.setText(text1);
}
#Override
public int getItemCount() {
return mHolder.size();
}
public class HolderOfArtist extends RecyclerView.ViewHolder {
ImageView image;
TextView name;
public HolderOfArtist(View itemView) {
super(itemView);
image = itemView.findViewById(R.id.resource_image);
name = itemView.findViewById(R.id.resource_text);
}
}
}
Artist Holders:-
public class ArtistHoler {
private String mName;
private String mImageUri;
public ArtistHoler() {
}
public ArtistHoler(String name , String imageUri){
mName = name;
mImageUri = imageUri;
}
public String getName() {
return mName;
}
public void setName(String name){
mName = name;
}
public String getImageUri(){
return mImageUri;
}
public void setImageUri(String imageUri) {
mImageUri = imageUri;
}
}
Add click event on holder item and take the corresponding artist name and pass it to next activity.
#Override
public void onBindViewHolder(#NonNull HolderOfArtist holder, int position) {
...
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String artistName = mHolder.get(position).getName();
Intent detailIntent = new Intent(mContext, SongsActivity.class);
detailIntent.putExtra("ArtistName", artistName);
startActivity(detailIntent);
}
});
}
Then in next activity's onCreate get the artist name like below and call the firebase to get the songs list of that particular artist and do whatever you want inside onDataChange
String artistName = getIntent().getStringExtra("ArtistName");
FirebaseDatabase.getInstance().getReference("ArtistSongs").orderByKey().equalTo(artistName).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot song: dataSnapshot.child(artistName).getChildren()) {
//here song indicates "Song" with SongName and SongUrl
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
I have one activity which connects with database and all my data is coming, but I want when I click on one Card view to open data from data Card.
I have like on the first-page category and when I click on one I want to get all projects that are in that category.
I'm still learning (on my own) and this is the first problem I can't solve by myself.
Plesa helps me.
I have tried everything I can find online.
public class MainActivity extends AppCompatActivity {
ImageButton imageButton;
private FirebaseFirestore db = FirebaseFirestore.getInstance();
private CollectionReference firemRef = db.collection("kategorije");
private FirmeAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpRecyclerView();
}
private void setUpRecyclerView(){
Query query= firemRef.orderBy("logo",Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Firme> options = new
FirestoreRecyclerOptions.Builder<Firme>()
.setQuery(query,Firme.class)
.build();
adapter= new FirmeAdapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
public void onClickButton (View view){
Intent intent= new Intent(MainActivity.this,BeautyIzbornik.class);
MainActivity.this.startActivity(intent);
}
}
My ADAPTER
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.squareup.picasso.Picasso;
public class FirmeAdapter extends FirestoreRecyclerAdapter<Firme, FirmeAdapter.FirmeHolder> {
/**
* Create a new RecyclerView adapter that listens to a Firestore Query. See {#link
* FirestoreRecyclerOptions} for configuration options.
*
* #param options
*/
public FirmeAdapter(#NonNull FirestoreRecyclerOptions<Firme> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull FirmeHolder holder, int position, #NonNull final Firme model) {
holder.naziv.setText(model.getNaziv());
holder.setLogo(model.getLogo());
}
#NonNull
#Override
public FirmeHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.firme_item,
viewGroup,false);
return new FirmeHolder(v);
}
class FirmeHolder extends RecyclerView.ViewHolder {
ImageButton imageButton;
TextView naziv;
public FirmeHolder(#NonNull final View itemView) {
super(itemView);
naziv = itemView.findViewById(R.id.naziv);
imageButton =itemView.findViewById(R.id.logo);
}
public void setLogo(String logo) {
Picasso.get().load(logo).into(imageButton);
}
}
}
My Activity with my data
public class Firme {
public String logo;
public String naziv;
public String url;
public Firme ( ) {
}
public Firme (String naziv, String logo , String url){
this.logo= logo;
this.naziv= naziv;
this.url = url;
}
public String getLogo() {
return logo;
}
public String getNaziv() {
return naziv;
}
public void setLogo(String logo){
this.logo = logo;
}
public String getUrl(){
return url;
}
public void setUrl(String url){
this.url=url;
}
}
you have to perform a click listener on RecyclerView item :
Since each item has its own data , you should use this data to show the adequate information :
This how to implement a click listener for RecyclerView
In your RecyclerView.Adapter simply create an interface you can use.
private onItemClickListener mItemClickListener;
public void setOnItemClickListener(onItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public interface onItemClickListener {
void onItemClickListener(View view, int position, MyData myData);
}
In this case mItemClickListener is a global variable inside your adapter and the two methods go inside your adapter, too.
Then inside your ViewHolder apply a click listener to your itemView with itemView.setOnClickListener(this) (or whatever component you want clicked to retrieve the data)
#Override
public void onClick(View view) {
if (mItemClickListener != null) {
mItemClickListener.onItemClickListener(view, getAdapterPosition(), my_data.get(getAdapterPosition()));
}
}
This will then pass the view that has been clicked, the position of said view and the object that is contained in your list within that position.
So in your Activity, you can then just simply call the interface.
adapter.setOnItemClickListener(new CustomAdapter.onItemItemClickListener() {
#Override
public void onItemClickListener(View view, int position, MyData data) {
//do on item click functionality here
}
});
Can anyone help me to retrieve data from the node "foods" and put it in the RecyclerView. These are the file I've been working on but it turns out to be an empty list. I have viewed a tutorial on Internet but most of them were with an older version of Firebase. Recently, Firebase UI has been updated and the data binding process has changed to their new FirebaseRecyclerAdapter structure
This is my database structure:
"foods" : {
"AntipastoSalad" : {
"duration" : "30",
"img" : "https://firebasestorage.googleapis.com/v0/b/mealplanner-ec8ca.appspot.com/o/res%2Fsalad.jpg?alt=media&token=257d4392-8a1f-4fb7-84b5-b63abb4643f4",
"name" : "Antipasto salad",
"type" : "Salad"
},
This is my activity:
private RecyclerView mRecycleView;
private Query query;
private FirebaseRecyclerOptions<Meal> options;
private DatabaseReference mDatabase;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_list_row);
mDatabase = FirebaseDatabase.getInstance().getReference().child("foods");
//Recycle View
mRecycleView = (RecyclerView) findViewById(R.id.meal_items);
mRecycleView.setHasFixedSize(true);
mRecycleView.setLayoutManager(new LinearLayoutManager(this));
}
#Override
protected void onStart() {
super.onStart();
query = FirebaseDatabase.getInstance().getReferenceFromUrl("https://mealplanner-ec8ca.firebaseio.com/foods/AntipastoSalad");
options = new FirebaseRecyclerOptions.Builder<Meal>()
.setQuery(query, Meal.class)
.build();
FirebaseRecyclerAdapter<Meal, FoodListRowActivity.MealRowHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Meal, FoodListRowActivity.MealRowHolder>(
options) {
#Override
public FoodListRowActivity.MealRowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.food_row, parent, false);
return new FoodListRowActivity.MealRowHolder(v);
}
#Override
protected void onBindViewHolder(FoodListRowActivity.MealRowHolder holder, int position, Meal current) {
holder.setTitle(current.getName());
String duration = current.getDuration() + "min";
holder.setDuration(duration);
}
};
//Populate Item into Adapter
mRecycleView.setAdapter(firebaseRecyclerAdapter);
mRecycleView.addOnItemTouchListener(new RecycleViewItemClickListener(this, mRecycleView, new RecycleViewItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Intent viewMeal = new Intent(FoodListRowActivity.this, CookingInstructionActivity.class);
startActivity(viewMeal);
}
#Override
public void onLongItemClick(View view, int position) {
//TODO: DELETE
}
}));
}
public static class MealRowHolder extends RecyclerView.ViewHolder {
View mView;
public MealRowHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setTitle(String title) {
TextView foodTitle = (TextView) mView.findViewById(R.id.list_item_foodList_name);
foodTitle.setText(title);
}
public void setDuration(String title) {
TextView foodDuration = (TextView) mView.findViewById(R.id.list_item_foodList_calories);
foodDuration.setText(title);
}
}
}
and class structure:
public class Meal{
private String img;
private String duration;
private String name;
private String instruction;
public Meal(){
}
public Meal (String img, String duration, String name, String instruction){
this.img = img;
this.name = name;
this.duration = duration;
this.instruction = instruction;
}
public void update(String duration, String name, String instruction)
{
this.name = name;
this.duration = duration;
this.instruction = instruction;
}
public String getName(){
return name;
}
public String getDuration() {
return duration;
}
public String getInstruction() {
return instruction;
}
public String getImg(){return img;}
The query specified in the setQuery() method should be a reference to the root of the list you want to show in the RecyclerView, so like this:
query = FirebaseDatabase.getInstance().getReference().child("foods");
You also need to call startListening() on the adapter to instruct it to start retrieving data from the database.
From the FirebaseRecyclerAdapter lifecycle documentation:
The FirebaseRecyclerAdapter uses an event listener to monitor changes to the Firebase query. To begin listening for data, call the startListening() method. You may want to call this in your onStart() method. Make sure you have finished any authentication necessary to read the data before calling startListening() or your query will fail.
#Override protected void onStart() {
super.onStart();
adapter.startListening();
}
Similarly, the stopListening() call removes the event listener and all data in the adapter. Call this method when the containing Activity or Fragment stops:
#Override protected void onStop() {
super.onStop();
adapter.stopListening();
}
Please override getItemCount() method of FirebaseRecyclerAdapter.
#Override
public int getItemCount() {
return 1;
}
Reference.
This is how I'm retrieving my data in recyclerview using Firebase UI:
private FirebaseRecyclerAdapter<TaskPOJO, TaskViewHolder> adapter;
private void loadTasks() {
database = FirebaseDatabase.getInstance();
tasks = database.getReference("Tasks");
adapter = new FirebaseRecyclerAdapter<TaskPOJO, TaskViewHolder>(TaskPOJO.class, R.layout.task_item, TaskViewHolder.class, tasks) {
#Override
protected void populateViewHolder(TaskViewHolder viewHolder, final TaskPOJO model, int position) {
Log.wtf("valueTEst", "populateViewHolder: "+model.toString() );
Log.wtf("TEstScript1", "populateViewHolder: "+model.getTitle() );
viewHolder.title.setText(model.getTitle());
viewHolder.desc.setText(model.getDescripttion()+"\n");
viewHolder.remaining.setText(model.getRemaining()+"/"+model.getPoint());
viewHolder.points.setText("Points "+model.getRemaining());
Glide.with(viewHolder.title.getContext())
.load(model.getImage())
.into(viewHolder.image);
viewHolder.setClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Toast.makeText(getActivity(), "" /*+ model.getTitle()*/, Toast.LENGTH_SHORT).show();
Intent TaskPOJODetail = new Intent(getActivity(), Main.class);
TaskPOJODetail.putExtra("value","detail");
TaskPOJODetail.putExtra("taskId",adapter.getRef(position).getKey());
startActivity(TaskPOJODetail);
}
});
}
};
progressBar.setVisibility(View.GONE);
recyclerViewTasks.setAdapter(adapter);
}
this is my firebase structure :
hope this will help you.