1

I have a recyclerview which shows multiple cardviews with items. In the recyclerview, I have a popup menu to delete that current cardview.

When the dataset is empty I would like to show an empty view. Something with an image and text saying "empty" I have tried some online examples. No success.

My layout is a cardview(card_view_row.xml) is a simple view with a cardview that shows a few items.

Here is my recyclerview

public class AlarmRecyclerViewAdapter extends 
 RecyclerView.Adapter<AlarmRecyclerViewAdapter.DataObjectHolder> {

    private ArrayList<Alarm> mDataset;
    private static AlarmRecyclerViewAdapter.MyClickListener myClickListener;
    private AlarmDataAccess dataAccess;

    private Alarm alarm;
    private int switchOn = 1;
    private int switchOff = 0;
    private static Context context;
    private PopupMenu popupMenu;


    public static class DataObjectHolder extends RecyclerView.ViewHolder
            implements View
            .OnClickListener {
        TextView label;
        TextView dateTime;
        TextView label2;
        TextView textViewLabel;
        TextView gender;
        TextView daysofweek;
        Switch aSwitch;
        ImageView trash;


        public DataObjectHolder(View itemView) {
            super(itemView);

            dateTime = (TextView) itemView.findViewById(R.id.textView2);
            label = (TextView) itemView.findViewById(R.id.textView);
            label2 =(TextView) itemView.findViewById(R.id.textView3);
            aSwitch = (Switch)itemView.findViewById(R.id.switchButton);
            trash = (ImageView)itemView.findViewById(R.id.imageTrash);
            gender = (TextView)itemView.findViewById(R.id.textViewGender);
            daysofweek = (TextView)itemView.findViewById(R.id.textViewDays);
            textViewLabel = (TextView)itemView.findViewById(R.id.textViewLabel);

            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            myClickListener.onItemClick(getAdapterPosition(), v);
        }
    }

    public void setOnItemClickListener(AlarmRecyclerViewAdapter.MyClickListener myClickListener) {
        this.myClickListener = myClickListener;
    }

    public AlarmRecyclerViewAdapter(ArrayList<Alarm> myDataset, Context context2) {
        mDataset = myDataset;
        context = context2;
    }

    @Override
    public AlarmRecyclerViewAdapter.DataObjectHolder onCreateViewHolder(ViewGroup parent,
                                                                        int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_row, parent, false);
        AlarmRecyclerViewAdapter.DataObjectHolder dataObjectHolder = new AlarmRecyclerViewAdapter.DataObjectHolder(view);
        return dataObjectHolder;
    }

    @Override
    public void onBindViewHolder(final AlarmRecyclerViewAdapter.DataObjectHolder holder, final int position) {
        boolean status = false;
        int gender;

        alarm = new Alarm();

        dataAccess = new AlarmDataAccess(context);
        dataAccess.open();

        holder.label.setText(mDataset.get(position).getHourOfDay() + ":" + mDataset.get(position).getMinute() + " " + mDataset.get(position).getTimeSet());
        holder.textViewLabel.setText(mDataset.get(position).getLabel());

        gender = mDataset.get(position).getGender();
        if(gender == 0){
            holder.gender.setText("Male voice");
        }else{
            holder.gender.setText("Female voice");
        }

        holder.daysofweek.setText(mDataset.get(position).getDays());
        holder.label2.setText("" + mDataset.get(position).getAffirmationName());


        holder.trash.setImageResource(R.drawable.menu2);


        if( mDataset.get(position).getStatus() == 0){
            status = false;
        }else {
            status = true;
        }

        holder.aSwitch.setChecked(status);


        holder.aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                if (buttonView.isPressed()) {
                    if (isChecked) {
                        mDataset.get(position).setStatus(switchOn);
                    } else {
                        mDataset.get(position).setStatus(switchOff);
                    }
                    alarm.setId(mDataset.get(position).getId());
                    alarm.setStatus(mDataset.get(position).getStatus());
                    dataAccess.updateStatus(alarm);
                }
            }

        });


        holder.trash.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                popupMenu = new PopupMenu(AlarmRecyclerViewAdapter.context, v);
                popupMenu.inflate(R.menu.popup_menu);
                popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                    @Override
                    public boolean onMenuItemClick(MenuItem item) {
                        switch (item.getItemId()) {
                            case R.id.edit:
                                long selectedAlarmId = mDataset.get(position).getId();
                                Intent intent = new Intent(AlarmRecyclerViewAdapter.context, EditAlarmActivity.class);
                                intent.putExtra("id", selectedAlarmId);
                                intent.putExtra("Edit", "FromEdit");
                                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
                                AlarmRecyclerViewAdapter.context.startActivity(intent);
                                return true;
                            case R.id.delete:
                                long id = mDataset.get(position).getId();
                                mDataset.remove(position);
                                notifyItemRemoved(position);
                                notifyItemRangeChanged(position, mDataset.size());
                                dataAccess.deleteAlarm(id);
                                return true;
                        }
                        return false;

                    }
                });

                popupMenu.show();
            }
        });
    }

    public void deleteItem(int index) {
        mDataset.remove(index);
        notifyItemRemoved(index);
    }

    @Override
    public int getItemCount() {
        return mDataset.size();
    }
}

My recyclerview is inside a fragment view

<RelativeLayout 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"
android:id="@+id/fragment_place">

    <ImageButton
        android:id="@+id/add_button"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_gravity="end|bottom"
        android:tint="@color/icon"
        android:elevation="12dp"
        android:background="@drawable/oval_ripple"
        tools:backgroundTint="#96ceb4"
        android:src="@android:drawable/ic_input_add"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_marginStart="12dp"
        android:layout_marginTop="14dp" />


    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
        android:layout_below="@+id/add_button"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp" />

</RelativeLayout>

Is there a way to detect if the data set is empty to show an empty view with text saying empty or something? I need this done inside recyclerview since I am deleting items inside there.

EDIT

I finally figured out how to do it. I am posting this incase anyone else has the same problem.

http://akbaribrahim.com/empty-view-for-androids-recyclerview/
  • Just Recyclerview height is change to wrap_content – Raj Jul 03 '17 at 05:18
  • Add the textview at the end of relativelayout that height and width is matchparent and text alignment is set to center & add two lines in java if(list size is not empty the hide the textview else show the textview) – Raj Jul 03 '17 at 05:22
  • I cant do that. My recyclerview is deleting the items in the dataset. Therefore, my fragment wont know if its empty or not. How can onCreate get called again? – Kinetic Uncertainty Jul 03 '17 at 16:50
  • Use AdapterDataObserver, see this link https://stackoverflow.com/a/52716769/4797289 – Rasoul Miri Oct 09 '18 at 08:56

1 Answers1

0

For my personal use I use this trick :

I use two LinearLayout, one with my RecyclerView and another with a simple TextView saying "Empty". Both are in the same parent view.

<LinearLayout
        android:id="@+id/linearContent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:visibility="invisible">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/my_recycler_view"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:scrollbars="vertical" />

    </LinearLayout>

    <LinearLayout
        android:id="@+id/linearEmpty"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textEmpty"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="30dp"
            android:text="@string/dialog_no_result"
            android:textColor="@color/cardview_dark_background" />
    </LinearLayout>

And when I update my list of item I call this method :

if (linearContent != null && linearEmpty != null) {
        if (mListItems.isEmpty()) {
            linearContent.setVisibility(View.GONE);
            linearEmpty.setVisibility(View.VISIBLE);
            textEmpty.setVisibility(View.VISIBLE);
        } else {
            linearContent.setVisibility(View.VISIBLE);
            linearEmpty.setVisibility(View.GONE);
            textEmpty.setVisibility(View.GONE);
        }
    }

Then I use the same layout, but just change the visibility of some objects.

Hope it help.

olivejp
  • 900
  • 1
  • 9
  • 14
  • where would i find the layout inside the recyclerview to set the invisibility? would i have to put it inside the holder? – Kinetic Uncertainty Jul 03 '17 at 05:41
  • If you want a CardView to display 'Empty'. You should replace my with id "id/textEmpty" by a static CardView item with a textview inside that said "Empty". – olivejp Jul 03 '17 at 05:50
  • I added linearContent = (LinearLayout)itemView.findViewById(R.id.linearContent); but its null – Kinetic Uncertainty Jul 03 '17 at 05:54
  • I dont want a cardview to display empty. – Kinetic Uncertainty Jul 03 '17 at 05:54
  • There wont be any cardviews anymore. I want to just have a icon image and a display empty. – Kinetic Uncertainty Jul 03 '17 at 05:56
  • In your RelativeLayout just add a down your . When your list of items is empty make your recyclerView.setVisibility(View.Gone) and textView.setVisibilty(View.Visible) and vice versa. – olivejp Jul 03 '17 at 09:00
  • How can i set visibility on the textview from the recyclerview? The recyclerview is doing the deleting of the items in the dataset. The fragment has the recyclerview. I need to be able to do it from recyclerview since its doing the deleing – Kinetic Uncertainty Jul 03 '17 at 16:53
  • if i was deleting items from the fragment i wouldn't have created this post. It would be easy. – Kinetic Uncertainty Jul 03 '17 at 16:56
  • Ok, then why don't you create a interface in your fragment with a method nammed updateVisibility(). You can pass this fragment to your adapter (via the constructor) and when you click on an item you call this method to make your recyclerView visible or not. – olivejp Jul 03 '17 at 22:48