Search code examples
androidfirebasefirebase-realtime-databaseandroid-recyclerviewfirebaseui

How to use FirebaseRecyclerAdaptor in RecycleView i.e. Listing Firebase data in RecycleView


It show how we can show a list of data from firebase to recycler view using FirebaseRecyclerAdaptar.

Output

Our output looks like this and the answer is given below

enter image description here


Solution

  • I was new to Android and I wasted more than 4 days to do this. So i am explaining this solution so that you dont have to waste time.

    Requirements

    • First of all your project should be connected to firebase.
    • Dependencies
      • compile 'com.google.firebase:firebase-database:11.0.0'
      • compile 'com.google.firebase:firebase-auth:11.0.0'
      • compile 'com.android.support:recyclerview-v7:25.2.0'
      • compile 'com.firebaseui:firebase-ui-database:0.5.1'
      • compile 'com.google.firebase:firebase-storage:10.0(if you want images and other storage file)
      • compile 'com.github.bumptech.glide:glide:4.0.0' (this is to show image in view from database)

    My Firebase Database

    enter image description here

    I will retrieve this data using FirebaseRecyclerAdaptar and load it on RecycleView

    model to get and set data from and to firebase

    First of all create model.java file which contains getters and setters and constructor for all the data we need. Note that the variable you defined inside mode should match with the name of database fields. Here is my model.java file i will name my model as Main.java you can name it on your own.

    public class Main implements Serializable {
    
        private String firstName;
        private String lastName;
        private String profilePic;
        private String email;
        private String id;
        private String phone;
        private String mobile;
    
        public Main(){
    
        }
    
        public Main(String firstName, String lastName, String profilePic, String email, String id, String phone, String mobile) {
           this.firstName = firstName;
           this.lastName = lastName;
           this.profilePic = profilePic;
           this.email = email;
           this.id = id;
           this.phone = phone;
           this.mobile = mobile;
        }
    
        public String getMobile() {
           return mobile;
        }
    
        public void setMobile(String mobile) {
           this.mobile = mobile;
        }
    
        public String getPhone() {
           return phone;
        }
    
        public void setPhone(String phone) {
           this.phone = phone;
        }
    
        public String getId() {
           return id;
        }
    
        public void setId(String id) {
           this.id = id;
        }
    
        public String getFirstName() {
           return firstName;
        }
    
        public void setFirstName(String firstName) {
           this.firstName = firstName;
        }
    
        public String getLastName() {
           return lastName;
        }
    
        public void setLastName(String lastName) {
           this.lastName = lastName;
        }
    
        public String getProfilePic() {
           return profilePic;
        }
    
        public void setProfilePic(String profilePic) {
           this.profilePic = profilePic;
        }
    
        public String getEmail() {
           return email;
        }
    
        public void setEmail(String email) {
           this.email = email;
        }
    }
    

    You can see String name, email is exactly same as database field name, email. And don't forget to create empty constructor as shown because firebase requires an empty constructor. Here i have defined all variable in String, in your case you can define integer also but remember that your database should contain integer value.

    main view containing recyclerview

    Now create a view that holds your recyclerView. I have created my view as activity_main.xml you can name it on your own.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       xmlns:tools="http://schemas.android.com/tools"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       app:layout_behavior="@string/appbar_scrolling_view_behavior"
       tools:context="com.firebase.firebaseemailauthentication.Main2Activity"
       tools:showIn="@layout/app_bar_main2"
       android:orientation="vertical"
       >
    
       <android.support.v7.widget.RecyclerView
           android:id="@+id/recycle_profile_list"
           android:layout_width="match_parent"
           android:layout_height="match_parent" />
    
    </LinearLayout>
    

    My view look like this

    mainview containing recyclier view

    view that contains single row

    Now you should create a new xml file that can show your data i.e. a single row design i have created row_profile_list.xml below is the code of xml file.

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:id="@+id/mainLayout"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:elevation="5dp"
       android:orientation="vertical"
       android:visibility="visible"
       app:cardBackgroundColor="#ffffff"
       app:cardCornerRadius="10dp"
       app:cardUseCompatPadding="true">
    
    <LinearLayout
        android:id="@+id/row_profile_lists"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="10dp"
        android:visibility="visible"
        android:weightSum="4">
    
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1.5"
            android:orientation="horizontal">
    
            <de.hdodenhof.circleimageview.CircleImageView
                android:id="@+id/row_profile_image"
                android:layout_width="wrap_content"
                android:layout_height="75dp" />
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:orientation="vertical"
            android:padding="5dp">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <TextView
                    android:id="@+id/row_fname"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/row_lname"
                    android:text="First Name"
                    android:textSize="16sp"
                    android:textStyle="bold" />
    
                <TextView
                    android:id="@+id/row_lname"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_above="@+id/tf_email"
                    android:gravity="left"
                    android:paddingLeft="5sp"
                    android:text="Last Name"
                    android:textSize="16sp"
                    android:textStyle="bold" />
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:orientation="horizontal">
    
                <TextView
                    android:id="@+id/row_email"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="TextView"
                    android:textSize="12sp" />
            </LinearLayout>
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.5"
            android:orientation="horizontal">
    
            <Button
                android:id="@+id/row_call"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|center_horizontal"
                android:layout_weight="1"
                android:text="Call" />
        </LinearLayout>
    
    
       </LinearLayout>
    </LinearLayout>
    

    This view look like this you can design it on your needs.

    single row view design

    now lets begin with FirebaseRecyclerAdaptar

    Create an Activity that returns activity_main.xml. Inside main activity define recycler view and firebase recycler adaptar like this

    private RecyclerView recycler_profile_lists;
    private FirebaseRecyclerAdapter adapter;
    

    Than assign recycler_profile_lists with recycleview inside on create method like this

    recycler_profile_lists = (RecyclerView) findViewById(R.id.recycle_profile_list);
    fetchProfileLists();
    

    Note that findViewById(R.id.recycle_profile_list) is the id of RecyclerView designed in activity_main.xml. fetchProfileLists() refers to another method or function. i am doing this because i dont want to do everything inside on create method. You also better not do inside onCreate method.

    Now another thing you should do is make ViewHolder method that holds single row view that we created earlier i.e. row_profile_list.xml. View holder class looks like this. i have named it as ProfileListHolder. Here it has extended RecyclerView.ViewHolder it helps to hold the certain view. the we have defined some views, textviews, image views and buttons. Then you can see mView = itemView we have assigned itemView in a view we defined above. and other textview and image view are also assigner with respective view. Note that the id you assign here should be defined in single row view i.e. row_profile_list.xml

    public static class ProfileListHolder extends RecyclerView.ViewHolder {
        public View mainLayout;
        public View linearLayout;
        View mView;
        public Main my = new Main();
        TextView firstName;
        TextView lastName;
        TextView email;
        ImageView profilePic;
        Button phoneCall;
    
        View view;
    
        public ProfileListHolder(final View itemView) {
            super(itemView);
            mView = itemView;
    
            firstName = (TextView) itemView.findViewById(R.id.row_fname);
            lastName = (TextView) itemView.findViewById(R.id.row_lname);
            email = (TextView) itemView.findViewById(R.id.row_email);
            profilePic = (ImageView) itemView.findViewById(R.id.row_profile_image);
            phoneCall = (Button) itemView.findViewById(R.id.row_call);
            mainLayout = itemView.findViewById(R.id.mainLayout);
            linearLayout = itemView.findViewById(R.id.row_profile_lists);
    
    
    
    
    
            view = itemView.findViewById(R.id.row_profile_lists);
        }
    }
    

    Now fetchProfileLists method or function looks like this.

    private void fetchProfileLists() {
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
        recycler_profile_lists.setHasFixedSize(true);
        recycler_profile_lists.setLayoutManager(new LinearLayoutManager(this));
    
        adapter = new FirebaseRecyclerAdapter<Main, ProfileListHolder>(Main.class, R.layout.row_profile_list, ProfileListHolder.class, ref.child("userProfile")) {
            @Override
            protected void populateViewHolder(final ProfileListHolder viewHolder, final Main model, final int position) {
                String userid = FirebaseAuth.getInstance().getCurrentUser().getUid();
                if (!userid.matches(model.getId())) {
                    viewHolder.mainLayout.setVisibility(View.VISIBLE);
                    viewHolder.linearLayout.setVisibility(View.VISIBLE);
                    viewHolder.firstName.setText(model.getFirstName());
                    viewHolder.lastName.setText(model.getLastName());
                    viewHolder.email.setText(model.getEmail());
    
                    Glide.with(Main2Activity.this).load(model.getProfilePic())
                            .thumbnail(0.5f)
                            .into(viewHolder.profilePic);
    
                    viewHolder.mView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            String id = model.getId();
                            Intent i=new Intent(Main2Activity.this, OtherProfileActivity.class);
                            i.putExtra("user_id",id);
                            startActivity(i);
                        }
                    });
    
                    viewHolder.phoneCall.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
    
    
    
    
                            final String phone = model.getPhone();
                            final String mobile = model.getMobile();
                            if(!TextUtils.isEmpty(mobile)){
    
                                LayoutInflater inflater = Main2Activity.this.getLayoutInflater();
                                final View view = inflater.inflate(R.layout.alert_dialog, null);
    
                                TextView alert_mobile = (TextView) view.findViewById(R.id.alert_mobile);
                                alert_mobile.setText(mobile);
    
                                TextView alert_phone = (TextView) view.findViewById(R.id.alert_phone);
                                alert_phone.setText(phone);
    
                                Button alert_call_phone = (Button) view.findViewById(R.id.alert_phone_btn);
                                alert_call_phone.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        Intent call = new Intent(Intent.ACTION_DIAL);
                                        call.setData(Uri.parse("tel:" + phone));
                                        startActivity(call);
                                    }
                                });
    
                                Button alert_call_mobile = (Button) view.findViewById(R.id.alert_mobile_btn);
                                alert_call_mobile.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        Intent call = new Intent(Intent.ACTION_DIAL);
                                        call.setData(Uri.parse("tel:" + mobile));
                                        startActivity(call);
                                    }
                                });
    
                                Button alert_cancel = (Button) view.findViewById(R.id.alert_cancel_btn);
                                alert_cancel.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        Main2Activity.this.alertDialog.dismiss();
                                    }
                                });
    
                                AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
                                builder.setView(view);
                                Main2Activity.this.alertDialog = builder.create();
                                Main2Activity.this.alertDialog.show();
    
                            }else{
                                Intent call = new Intent(Intent.ACTION_DIAL);
                                call.setData(Uri.parse("tel:" + phone));
                                startActivity(call);
                            }
    
    
                        }
                    });
                }else{
                    int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 0, getResources().getDisplayMetrics());
                    viewHolder.mainLayout.setMinimumHeight(px);
                }
    
            }
    
    
        };
    
    
        recycler_profile_lists.setAdapter(adapter);
    }
    

    Now i will explain FirebaseRecyclerAdaptar in detail firstly we have taken reference of our database, and we have set size and layout manager for RecyclerView. This is because we want to show our content in linear way. We can show our RecyclerView in Grid layout also. Now ew have assigner new FirebaseRecyclerAdaptar in adaptar we have defined earlier. Here we have passed < Main, ProfileListHolder > like this here the Main refers to Main.java which is model we created earlier. and ProfileListHolder is a view holder we created above. Now we can pass four different parameters. first is the class of model, second is the single layout i.e. R.layout.row_profile_list, note that we have not defined this layout in our view holder. it sense that this single row view will be hold by our view holder. another parameter is viewholder class and last parameter is the database reference. Note that the given database reference should contain array not object. if you database reference holds object than this will throw error. Now inside populate view we have three parameter first is view holder, second is model and third is position. Now you can see there viewHolder.firstName.setText(model.getName()); what this does is form viewHolder we can access the views that we have created and assigned. in that view we can set text using mode.getName(); model.getName() will return the value from database with respective position and the view will be populated. for every data it will populate a new view. You can set onClickListener inside populate view for an item and other textview or buttons of an item. If you have any question you can ask any time.