Home » Android » java – Dynamic Section Header Of RecyclerView Using Current Date&Time

java – Dynamic Section Header Of RecyclerView Using Current Date&Time

Posted by: admin May 14, 2020 Leave a comment

Questions:

I’ll use RecyclerView for a section header

I want to create section header when i insert each Date & Time data in SQLite Database

I followed below links for this solution but haven’t been successful

Please refer the below image

enter image description here

For above image data using below code OR Section is Static :

List<Company> childList = new ArrayList<>();
        List<CompanySectionHeader> sectionHeaders = new ArrayList<>();

        childList = myDb.getAllCompany();
        sectionHeaders.add(new CompanySectionHeader(childList, "WEDNESDAY 4 APRIL", 1));

Now If suppose i enter today’s data then I create 1 Section Header taking today date

Below image data section header is Static or data also:

enter image description here

Above image data are getting using Below code :

childList.add(new Company("Ketul Inc.", "11/11/2017 3:46 PM"));
        childList.add(new Company("Atmel Corporation", "09/19/2017 8:46 PM"));
        childList.add(new Company("ABC Technologies", "09/12/2017 7:41 PM"));
        childList.add(new Company("Huron Capital Partners LLC", "09/12/2017 7:25 PM"));
        sectionHeaders = new ArrayList<>();
        //Create a List of SectionHeader DataModel implements SectionHeader
        sectionHeaders.add(new CompanySectionHeader(childList, "SATURDAY 7 APRIL", 2));

Below Code is my SectionHeader.Java :

public class CompanySectionHeader implements Section<Company>, Comparable<CompanySectionHeader> {

    List<Company> childList;
    String sectionText;
    int index;

    public CompanySectionHeader(List<Company> childList, String sectionText, int index) {
        this.childList = childList;
        this.sectionText = sectionText;
        this.index = index;
    }

    @Override
    public List<Company> getChildItems() {
        return childList;
    }

    public String getSectionText() {
        return sectionText;
    }

    @Override
    public int compareTo(CompanySectionHeader another) {
        if (this.index > another.index) {
            return -1;
        } else {
            return 1;
        }
    }
}

Below is my SQLite Database Structure:

public String getFromatDate(long dateTime) {
        String formatedDate;
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(dateTime);
        Date mDate = calendar.getTime();
        SimpleDateFormat sdf;
        sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm a", new Locale("en"));
        formatedDate = sdf.format(mDate);
        return formatedDate;
    }

    public long insertCompany(Company company){

        //String sql = null;
        SQLiteDatabase db = dbHelper.getWritableDatabase();

        ContentValues values = new ContentValues();

        values.put(DatabaseHelper.KEY_COMPANY_NAME, company.getName());
        values.put(DatabaseHelper.KEY_CREATED_AT, System.currentTimeMillis());
        values.put(DatabaseHelper.KEY_UPDATED_AT, System.currentTimeMillis());
        values.put(DatabaseHelper.KEY_COMPANY_WEBSITE,company.getWebsite());
        values.put(DatabaseHelper.KEY_COMPANY_EMAIL,company.getEmail());
        values.put(DatabaseHelper.KEY_COMPANY_PHONE_HOME,company.getPhoneHome());

        long company_id = db.insert(COMPANY, null, values);

        return company_id;
    }

My Question is How to create section header dynamically

If u need any code or information you can ask me 🙂

Thanks in Advance :

How to&Answers:

I had Recently done this for sorting something on Monthly Basis. Its By overriding ViewType Function .

Screenshot

For doing this you have to use something like getViewType() in Recycler Adapter.

public class LastTransAdapter extends RecyclerView.Adapter<LastTransAdapter.ViewHolder> {
    private ArrayList<LastTransBean> lastTransBeans;
    private Context context;

    private MyCustomTextView textViewTitle, tv_Desc, tv_Date, tv_Amount;
    private LinearLayout layout1;
    private View customView, myView;

    private LayoutParams layoutParams;

    private PopupWindow popUpWindow = null;

    private RelativeLayout layout;

    private int MONTHHEADER = 1;
    private int DATAVIEW = 2;


    public LastTransAdapter(ArrayList<LastTransBean> lastTransBeans, Context context, View myView, RelativeLayout layout) {
        this.lastTransBeans = lastTransBeans;
        this.context = context;
        this.myView = myView;
        this.layout = layout;

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {

        if (i == DATAVIEW) {

             // view for normal data.


            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row_last_transactions, viewGroup, false);
            return new ViewHolder(view);
        } else {

            // view type for month or date header

            View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.single_row_month_header, viewGroup, false);
            return new ViewHolder(view);
        }
    }


    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {

        final int position = i;

        if (viewHolder.getItemViewType() == DATAVIEW) {

            //fill data for normal view


        } else {
            //set your date or month header
        }

    }

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

    @Override
    public int getItemViewType(int position) {
        if (lastTransBeans.get(position).getMonth()) {
            return MONTHHEADER;
        } else {
            return DATAVIEW;
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        MyCustomTextView transtile, transdate, transamont, tv_monthHeader;
        LinearLayout acctype;
        CardView mlastTransCardView;


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

           // cast all the textviews , buttonsetc used ion view Holder.

        }
    }
}

You can also use multiple viewholder types. Like this example.

Hope this may help you to solve your problem

Answer:

here is a sample Json for you all you have to do is save save and fetch your data in this way, run this sample on Json viewer and see structure.!

for SQLIte

public static final String TABLE_NAME = "companies_dates";
public static final String COLUMN_TIMESTAMP = "timestamp"; //primary key
public static final String COLUMN_ID = "id";// primary key



public static final String TABLE_NAME = "companies";

public static final String COLUMN_ID = "id";// primary key
public static final String COLUMN_ID_PARENT = "id_parent"; //foreign key //primary key form table companies_dates
 //or use date as parent_date
public static final String COLUMN_DATE_PARENT = "timestamp";
public static final String COLUMN_TITLE = "company";
public static final String COLUMN_TIMESTAMP = "timestamp";  

// ResponseMain.Java

 public  class  CompaniesResponse{

        ArrayList<Companies> companiesList;

        public ArrayList<Companies> getCompaniesList() {
            return companiesList;
        }

        public void setCompaniesList(ArrayList<Companies> companiesList) {
            this.companiesList = companiesList;
        }
    }

    public  class Companies{


        private String timeStamp;
        ArrayList<CompaniesItem> companiesArrayList;

        public String getTimeStamp() {
            return timeStamp;
        }

        public void setTimeStamp(String timeStamp) {
            this.timeStamp = timeStamp;
        }

        public ArrayList<CompaniesItem> getCompaniesArrayList() {
            return companiesArrayList;
        }

        public void setCompaniesArrayList(ArrayList<CompaniesItem> companiesArrayList) {
            this.companiesArrayList = companiesArrayList;
        }
    }

    public class  CompaniesItem{

        private String title;
        private String id;
        private String timeStamp;
        private String parentId;
        private String parentTimeStamp;

        //getter setters

    }


   @Override
    public void onCreate(Bundle savedInstanceState) {
        //super.onCreate(savedInstanceState);


        CompaniesResponse companiesResponse = new CompaniesResponse();

        Companies companies = new Companies();
       // CompaniesItem companiesItem = new CompaniesItem();

        //companiesItem.setId("1");
       // companiesItem.setTimeStamp("Time Stamp");
      //  ArrayList<CompaniesItem> companiesItemArrayList = new ArrayList<>();
       // companiesItemArrayList.add(companiesItem);

         companiesItemArrayList.add(myDb.getAllCompany());

        companies.setTimeStamp(myDb.getDate());
        companies.setCompaniesArrayList(companiesItemArrayList);

        ArrayList<Companies> companieslist = new ArrayList<>();

        companieslist.add(companies);

        companiesResponse.setCompaniesList(companieslist);


    }

for Json

{
 "companies ": [

{
  "date": "12-08.2018",
  "companiesList": [
    {
      "title": "Atmel Corporation",
      "date": "11/11/2017 3:46 PM"
    },
    {
      "title": "Ketul Inc.",
      "date": "11/11/2017 3:46 PM"
    }
  ]
},
{
  "date": "09/19/2017 8:46 PM",
  "companiesList": [
    {
      "title": "Huron Capital Partners LLC",
      "date": "15-06-2018"
    },
    {
      "title": "ABC Technologies",
      "date": "09/12/2017 7:41 PM"
    }
  ]
}


]


}

Answer:

Create two different ViewHolder’s and chnage them by condition like chatting recycler view like this example . in your case :

  1. create variable String date = “”
  2. then check section header date is equal if not return header view and update the date to varibale (1st time not match date so show headerview)
  3. if date match return list_header_item_view
    public int getItemViewType(int position) {
            UserMessage message = (UserMessage) mMessageList.get(position);

            if (message.getSender().getUserId().equals(SendBird.getCurrentUser().getUserId())) {
                // If the current user is the sender of the message
                return VIEW_TYPE_MESSAGE_SENT;
            } else {
                // If some other user sent the message
                return VIEW_TYPE_MESSAGE_RECEIVED;
            }
        }


    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view;

            if (viewType == VIEW_TYPE_MESSAGE_SENT) {
                view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_message_sent, parent, false);
                return new SentMessageHolder(view);
            } else if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
                view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_message_received, parent, false);
                return new ReceivedMessageHolder(view);
            }

            return null;
        }

Answer:

if I understand you correctly, your challenge is querying the SQLite db, group the records into dates, and display them in sections in the view.

Take a look at this:

public String formatDate(long dateTime) {
    String formatedDate;
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(dateTime);
    Date mDate = calendar.getTime();
    SimpleDateFormat sdf;
    sdf = new SimpleDateFormat("EEEE dd EEEE", new Locale("en"));
    formatedDate = sdf.format(mDate);
    return formatedDate;
} 

SQLiteDatabase db = this.getReadableDatabase(); 
//select companies, order record by date-time created desc (or asc)
Cursor cursor = db.query(Company.TABLE_NAME, null, null,
        null, null, null, DatabaseHelper.KEY_CREATED_AT + " DESC", null);
String day="";
ArrayList<Company> childList= new ArrayList<Company>();
int index = 0;
ArrayList<CompanySectionHeader> sectionHeaders = new ArrayList<>();
if (cursor.moveToFirst()){
      //assign the formatted current date to a variable

     day = formatDate(cursor.getString(cursor.getColumnIndex(DatabaseHelper.KEY_CREATED_AT)));
     String current_day = formatDate(cursor.getString(cursor.getColumnIndex(DatabaseHelper.KEY_CREATED_AT)));
     while(cursor.moveToNext()){
          current_day = formatDate(cursor.getString(cursor.getColumnIndex(DatabaseHelper.KEY_CREATED_AT)));
          childList.add(new Company(cursor.getColumnIndex(DatabaseHelper.KEY_COMPANY_NAME), getFromatDate(cursor.getString(cursor.getColumnIndex(DatabaseHelper.KEY_CREATED_AT))));
          //compare with day var
          if(!day.equals(current_day)) {
             //We are beginning a new day, so add the previous days company to the sectioned list
             sectionHeaders.add(new CompanySectionHeader(new ArrayList<Company>(childList), day, ++index));
             day=current_day; //this is 
             childList.clear();
          }
      }
}
cursor.close();
db.close();
//attach sectionHeaders to view here

I hope it helps.