How can I group recyclerview item by category in android studio

Viewed 2165

I want to group my recyclerview by date in android studio without using any library, I did something but I am not getting what I wanted. I have uploaded my result image so I want to group it with "getDateSection". But here DateSection is displaying above each item not according to the dates. I just want to show each date once at the top of the corresponding data group:

1 This is my codes.

DowntimeReportingAdapter.java

public class DowntimeReportingAdapter extends RecyclerView.Adapter<DowntimeReportingAdapter.MyViewHolder> implements Filterable {

    public List<DowntimeReportingUri> downtimeReportingUriList;
    private final List<DowntimeReportingUri> downtimeUriFilter;
    GridLayoutManager mLayoutManager;
    private final Context context;
    private DowntimeReportingFilter filter;
    Activity mContext;
    Context ctx;


    public DowntimeReportingAdapter(List<DowntimeReportingUri> downtimeReportingUriList, Context context) {
        this.downtimeReportingUriList = downtimeReportingUriList;
        this.downtimeUriFilter = downtimeReportingUriList;
        this.context = context;
    }

    @NotNull
    @Override
    public MyViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
       View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.downtime_reporting_item,
                parent, false);
        return new MyViewHolder(view);
    }

    @SuppressLint({"CheckResult", "SetTextI18n"})
    @Override
    public void onBindViewHolder(final MyViewHolder myViewHolder, int position) {
            
            if(downtimeReportingUriList.get(position).getDatesection().isEmpty()){
                myViewHolder.mDateSection.setVisibility(View.GONE) ;
            } else {
                myViewHolder.mDateSection.setText(downtimeReportingUriList.get(position).getDatesection());
            }
            
            RequestOptions requestOptions1 = new RequestOptions();
            requestOptions1.skipMemoryCache(true);
            requestOptions1.diskCacheStrategy(DiskCacheStrategy.ALL);
            requestOptions1.placeholder(R.drawable.full_image_blue);
            requestOptions1.error(R.drawable.full_image_blue);

            Glide.with(context)
                    .load(downtimeReportingUriList.get(position).getPicture())
                    .apply(requestOptions1)
                    .into(myViewHolder.mPicture);

            myViewHolder.issue.setText(downtimeReportingUriList.get(position).getIssues());
            myViewHolder.factory.setText(downtimeReportingUriList.get(position).getFactory());
            myViewHolder.line.setText(downtimeReportingUriList.get(position).getLine());
            myViewHolder.createdBy.setText(downtimeReportingUriList.get(position).getCreatedby());
            myViewHolder.modifiedBy.setText(downtimeReportingUriList.get(position).getModifiedby());
            myViewHolder.description.setText(downtimeReportingUriList.get(position).getDescription());
            myViewHolder.section.setText(downtimeReportingUriList.get(position).getSection());

            myViewHolder.mIssues.setText(downtimeReportingUriList.get(position).getIssues());
            myViewHolder.mCreated.setText(downtimeReportingUriList.get(position).getCreated());
            myViewHolder.mType.setText(downtimeReportingUriList.get(position).getStatus() + " | "
                    + downtimeReportingUriList.get(position).getDifference() + " | "
                    + downtimeReportingUriList.get(position).getFactory());
    }

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

    @Override
    public Filter getFilter() {
        if (filter==null) {
            filter=new DowntimeReportingFilter((ArrayList<DowntimeReportingUri>) downtimeUriFilter,this);
        }
        return filter;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        Space space;
        LikeButton mLove;
        DatabaseHandler db;
        LinearLayout linearLayout;
        private CircleImageView mPicture;
        private final ApiInterface apiInterface;
        CardView mRowContainer, mRowContainerGrid;
        ImageView mForward, mStatus;
        private HashMap<String, String> user = new HashMap<>();
        TextView mIssues, mType, mCreated, issue, factory, line, createdBy, modifiedBy, description, section, mIssuesGrid, mDateSection;

        @SuppressLint("CutPasteId")
        public MyViewHolder(View itemView, int viewType) {
            super(itemView);
            apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
                mPicture = itemView.findViewById(R.id.downtime_reporting_picture);
                mIssues = itemView.findViewById(R.id.downtime_reporting_issues);
                mIssues.setMovementMethod(new ScrollingMovementMethod());
                mType = itemView.findViewById(R.id.downtime_reporting_type);
                mLove = itemView.findViewById(R.id.downtime_reporting_like);
                mStatus = itemView.findViewById(R.id.current_status);
                mCreated = itemView.findViewById(R.id.downtime_reporting_created);
                mRowContainer = itemView.findViewById(R.id.downtime_reporting_row_container);
                linearLayout = itemView.findViewById(R.id.linearLayout);
                issue = itemView.findViewById(R.id.issues);
                factory = itemView.findViewById(R.id.factory);
                line = itemView.findViewById(R.id.line);
                createdBy = itemView.findViewById(R.id.createdby);
                modifiedBy = itemView.findViewById(R.id.modifiedby);
                description = itemView.findViewById(R.id.description);
                section = itemView.findViewById(R.id.section);
                space = itemView.findViewById(R.id.space);
                mDateSection = itemView.findViewById(R.id.datesection);

        }
    }
}

DowntimeReporting.java

public class DowntimeReporting extends Fragment {

    DatabaseHandler db;
    MaterialButton refresh;
    SessionManager session;
    ProgressDialog pDialog;
    private RadioGroup sortRG;
    ApiInterface apiInterface;
    private TextView textResult;
    TextView textName, textEmail;
    private RecyclerView recyclerView;
    private LinearLayout linearLayout;
    SwipeRefreshLayout mSwipeRefreshLayout;
    private ImageView sortB, goTop, filterB;
    ShimmerFrameLayout mShimmerViewContainer;
    FloatingActionButton floatingActionButton;
    private GridLayoutManager gridLayoutManager;
    HashMap<String,String> user = new HashMap<>();
    private DowntimeReportingAdapter downtimeAdapter;
    private List<DowntimeReportingUri> downtimeUriList;
    private static final String TAG = DowntimeReporting.class.getSimpleName();

    public DowntimeReporting() {

    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ((Home) Objects.requireNonNull(getActivity())).setActionBarTitle("Downtime Reporting / Open Machine Issue");

        View view = inflater.inflate(R.layout.downtime_reporting, container, false);
        textName = view.findViewById(R.id.name);
        textEmail = view.findViewById(R.id.email);

        view.findViewById(R.id.fab).setOnClickListener(v -> showPrompt());

        pDialog = new ProgressDialog(getActivity());
        pDialog.setCancelable(false);

        db = new DatabaseHandler(getActivity().getApplicationContext());
        user = db.getUserDetails();

        session = new SessionManager(getActivity().getApplicationContext());
        if (!session.isLoggedIn()) {
            logoutUser();
        }

        refresh = view.findViewById(R.id.refresh);
        refresh.setOnClickListener(v -> {
            onResume();
            refresh.setVisibility(View.GONE);
        });

        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

        apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
        recyclerView = view.findViewById(R.id.recyclerView);
        mShimmerViewContainer = view.findViewById(R.id.shimmer_view_container);
        mSwipeRefreshLayout = view.findViewById(R.id.swipeToRefresh);
        mSwipeRefreshLayout.setColorSchemeResources(R.color.colorPrimary);
        mSwipeRefreshLayout.setOnRefreshListener(() -> {
            onResume();
            mSwipeRefreshLayout.setRefreshing(false);
            refresh.setVisibility(View.GONE);
        });

        gridLayoutManager = new GridLayoutManager(getActivity(), SPAN_COUNT_ONE);
        recyclerView.setLayoutManager(gridLayoutManager);

        linearLayout = view.findViewById(R.id.no_result);
        textResult = view.findViewById(R.id.text_result);

        floatingActionButton = view.findViewById(R.id.fab);
        floatingActionButton.setOnClickListener(view1 -> startActivity(new Intent(getActivity(), DowntimeReportingForm.class)));
        return view;
    }

    public void getDowntimes(){

        Call<List<DowntimeReportingUri>> call = apiInterface.getDowntimes();
        call.enqueue(new Callback<List<DowntimeReportingUri>>() {
            @SuppressLint("NonConstantResourceId")
            @Override
            public void onResponse(@NotNull Call<List<DowntimeReportingUri>> call, @NotNull Response<List<DowntimeReportingUri>> response) {
                mShimmerViewContainer.stopShimmer();
                mShimmerViewContainer.setVisibility(View.GONE);
                downtimeUriList = response.body();
                Log.i(DowntimeReporting.class.getSimpleName(), Objects.requireNonNull(response.body()).toString());
                downtimeAdapter = new DowntimeReportingAdapter(downtimeUriList, gridLayoutManager, getActivity());
                ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
                itemTouchHelper.attachToRecyclerView(recyclerView);
                Log.d(TAG, "Number Downtime Reporting Received: " + downtimeUriList.size());
                recyclerView.setAdapter(downtimeAdapter);
                downtimeAdapter.notifyDataSetChanged();
            }

            @Override
            public void onFailure(@NotNull Call<List<DowntimeReportingUri>> call, @NotNull Throwable t) {
                mShimmerViewContainer.stopShimmer();
                refresh.setVisibility(View.VISIBLE);
                LayoutInflater inflater = Objects.requireNonNull(getActivity()).getLayoutInflater();
                View layout = inflater.inflate(R.layout.custom_toast_message, getActivity().findViewById(R.id.custom_toast_container));
                TextView text = layout.findViewById(R.id.text);
                text.setText(t.getMessage());
                Toast toast = new Toast(getActivity().getApplicationContext());
                CardView cardView = layout.findViewById(R.id.card_view);
                cardView.setBackgroundResource(R.drawable.error_style);
                ImageView toastImageView = layout.findViewById(R.id.toastImageView);
                toastImageView.setImageResource(R.drawable.error);
                toast.setGravity(Gravity.BOTTOM, 0, 40);
                toast.setDuration(Toast.LENGTH_SHORT);
                toast.setView(layout);
                toast.show();
            }
        });
    }

    @Override
    public void onResume() {
        super.onResume();
        mShimmerViewContainer.startShimmer();
        refresh.setVisibility(View.GONE);
        getDowntimes();
    }

    @Override
    public void onPause() {
        super.onPause();
        mShimmerViewContainer.stopShimmer();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        setHasOptionsMenu(true);
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onCreateOptionsMenu(@NotNull Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.downtime_reporting_menu, menu);
        SearchManager searchManager = (SearchManager) Objects.requireNonNull(getActivity()).getSystemService(Context.SEARCH_SERVICE);
        final SearchView searchView = (SearchView) menu.findItem(R.id.downtime_reporting_search).getActionView();
        LinearLayout searchBar = searchView.findViewById(R.id.search_bar);
        searchBar.setLayoutTransition(new LayoutTransition());
        MenuItem searchMenuItem = menu.findItem(R.id.downtime_reporting_search);
        searchView.setSearchableInfo(
                searchManager.getSearchableInfo(getActivity().getComponentName())
        );
        searchView.setQueryHint("Search DownTime Reporting Activity...");
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(final String query) {
                downtimeAdapter.getFilter().filter(query);
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                if(newText!=null)
                    downtimeAdapter.getFilter().filter(newText);
                if(downtimeAdapter.getItemCount()<1){
                    recyclerView.setVisibility(View.GONE);
                    linearLayout.setVisibility(View.VISIBLE);
                    textResult.setText(R.string.no_result);
                } else {
                    recyclerView.setVisibility(View.VISIBLE);
                    downtimeAdapter.getFilter().filter(newText);
                    linearLayout.setVisibility(View.GONE);
                }
                return false;
            }
        });

        searchMenuItem.getIcon().setVisible(false, false);
    }

    @Override
    public boolean onOptionsItemSelected(@NotNull MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.downtime_reporting_menu_switch_layout) {
            switchLayout();
            switchIcon(item);
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

downtime_reporting_item.xml

<LinearLayout
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/datesection"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="2dp"
        android:layout_marginTop="2dp"
        android:gravity="center"
        android:text="@string/currently_not_available"
        android:layout_gravity="center"
        android:textColor="@color/mainText"
        android:textSize="16sp"/>

<androidx.cardview.widget.CardView
    android:id="@+id/downtime_reporting_row_container"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:backgroundTint="@color/card_bg"
    card_view:cardCornerRadius="12dp"
    card_view:cardElevation="2dp"
    android:layout_weight="2"
    android:layout_marginTop="10dp"
    android:layout_marginRight="4dp"
    android:layout_marginLeft="4dp">

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="110dp"
        android:layout_gravity="center"
        android:orientation="vertical">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="2dp"
                android:layout_alignParentEnd="true">

                <ImageView
                    android:id="@+id/btmDialog"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    android:src="@drawable/ic_baseline_more_horiz_24" />

                <Space
                    android:layout_width="15dp"
                    android:layout_height="wrap_content"/>

                <ImageView
                    android:id="@+id/dropdown"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    android:src="@drawable/ic_baseline_arrow_drop_down_24" />

                <Space
                    android:layout_width="15dp"
                    android:layout_height="wrap_content"/>

                <ImageView
                    android:id="@+id/current_status"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:padding="2dp"
                    android:src="@drawable/open_status" />

                <Space
                    android:layout_width="15dp"
                    android:layout_height="wrap_content"/>

                <ImageView
                    android:id="@+id/forward"
                    android:layout_width="20dp"
                    android:layout_height="20dp"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    android:padding="2dp"
                    android:visibility="gone"
                    android:src="@drawable/forward" />

                <Space
                    android:id="@+id/space"
                    android:layout_width="15dp"
                    android:layout_height="wrap_content"
                    android:visibility="gone"/>

            </LinearLayout>

            <de.hdodenhof.circleimageview.CircleImageView
                android:id="@+id/downtime_reporting_picture"
                android:layout_width="70dp"
                android:layout_height="70dp"
                android:layout_centerVertical="true"
                android:layout_marginStart="16dp"
                android:src="@drawable/full_image_blue"
                android:transitionName="@string/simple_activity_transition" />

            <LinearLayout
                android:id="@+id/layoutName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignTop="@+id/downtime_reporting_picture"
                android:layout_alignParentStart="true"
                android:layout_marginStart="90dp"
                android:layout_marginEnd="15dp"
                android:layout_marginBottom="5dp"
                android:gravity="top"
                android:orientation="horizontal"
                android:weightSum="100">

                <TextView
                    android:id="@+id/downtime_reporting_issues"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="100"
                    android:scrollbars="vertical"
                    android:singleLine="true"
                    android:ellipsize="end"
                    android:paddingTop="5dp"
                    android:inputType="textPersonName"
                    android:text="@string/currently_not_available"
                    android:textColor="@color/mainText"
                    android:textStyle="bold"
                    android:transitionName="@string/title_transition" />

                <Space
                    android:layout_width="5dp"
                    android:layout_height="wrap_content"/>

                <TextView
                    android:id="@+id/downtime_reporting_created"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="10"
                    android:gravity="end"
                    android:paddingTop="5dp"
                    android:text="@string/currently_not_available"
                    android:textColor="@color/date"
                    />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/layoutName"
                android:layout_alignStart="@+id/layoutName"
                android:layout_alignBottom="@+id/downtime_reporting_picture"
                android:layout_marginEnd="15dp"
                android:gravity="top"
                android:layout_centerInParent="true"
                android:orientation="horizontal"
                android:weightSum="2">

                <TextView
                    android:id="@+id/downtime_reporting_type"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:singleLine="true"
                    android:ellipsize="end"
                    android:layout_gravity="center"
                    android:scrollbars="vertical"
                    android:gravity="start"
                    android:text="@string/currently_not_available"
                    android:textColor="@color/mainText"
                    android:transitionName="descTransition" />

                <com.like.LikeButton
                    app:liked="false"
                    android:id="@+id/downtime_reporting_like"
                    android:background="?attr/selectableItemBackgroundBorderless"
                    android:layout_width="40dp"
                    android:layout_height="40dp"
                    android:layout_gravity="center"
                    android:layout_weight="1"
                    app:icon_type="thumb"
                    app:is_enabled="false"/>
            </LinearLayout>
    </RelativeLayout>
    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true"
        android:orientation="vertical"
        android:visibility="gone">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scaleType="fitXY" />

        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="15dp">

            <TableRow>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/issue"
                    android:textColor="@color/mainText" />

                <TextView
                    android:id="@+id/issues"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/mainText"
                    android:text="@string/currently_not_available"
                    android:textStyle="bold" />
            </TableRow>

            <TableRow>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Factory   "
                    android:textColor="@color/mainText" />

                <TextView
                    android:id="@+id/factory"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/mainText"
                    android:text="@string/currently_not_available"
                    android:textStyle="bold" />
            </TableRow>

            <TableRow>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/mainText"
                    android:text="Line   " />

                <TextView
                    android:id="@+id/line"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/currently_not_available"
                    android:textColor="@color/mainText"
                    android:textStyle="bold" />
            </TableRow>

            <TableRow>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Section   "
                    android:textColor="@color/mainText"/>

                <TextView
                    android:id="@+id/section"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/mainText"
                    android:text="@string/currently_not_available"
                    android:textStyle="bold" />
            </TableRow>

            <TableRow>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/mainText"
                    android:text="Created By   " />

                <TextView
                    android:id="@+id/createdby"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/currently_not_available"
                    android:textColor="@color/mainText"
                    android:textStyle="bold" />
            </TableRow>

            <TableRow>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/mainText"
                    android:text="Modified By   " />

                <TextView
                    android:id="@+id/modifiedby"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/currently_not_available"
                    android:textColor="@color/mainText"
                    android:textStyle="bold" />
            </TableRow>

            <TableRow>

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Description   "
                    android:textColor="@color/mainText"/>

                <TextView
                    android:id="@+id/description"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:inputType="textMultiLine"
                    android:textColor="@color/mainText"
                    android:text="@string/currently_not_available"
                    android:textStyle="bold" />
            </TableRow>
        </TableLayout>
    </LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>

DowntimeReportingUri.java

 public class DowntimeReportingUri {

    @SerializedName("id")
    private int id;
    @SerializedName("createdby")
    private String createdby;
    @SerializedName("issues")
    private String issues;
    @SerializedName("description")
    private String description;
    @SerializedName("datesection")
    private String datesection;

public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getIssues() {
        return issues;
    }

    public void setIssues(String issues) {
        this.issues = issues;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getDatesection() {
        return datesection;
    }

    public void setDatesection(String datesection) {
        this.datesection = datesection;
    }
}
3 Answers

If you just want to show date at the first item then check if recycler view item position is at the top then set date text visibility to visible else visibility gone

I cannot add code I'm on a mobile device

There's a clever workaround that you can try. Just check the date for each entry; in the meanwhile declare a global variable to store the date. Whenever the date changes for an entry which will obviously be the first entry for that date, then only the date label will be displayed using setVisibility() method, else it will be hidden. And remember to change the date in the global variable whenever it changes.

Related