This is what my screen should look like.
I added this library https://github.com/ShamylZakariya/StickyHeaders and tried to do it in similar way.
My model looks like this:
public class Transaction {
private int id;
private Date createdDate;
private String description;
private int amount;
private float newCredits;
}
and
public class Transactions {
private int totalCount;
private List<Transaction> transactions = new ArrayList<>();
}
So after i fetch all my transactions I set the data in adapter.. this is what my adapter looks like:
public class WalletAdapter extends SectioningAdapter {
private static final boolean USE_DEBUG_APPEARANCE = false;
private Transactions transactions;
private List<Section> sections = new ArrayList<>();
public WalletAdapter() {
}
private class Section {
String alpha;
Transactions transactions;
}
public Transactions getTransactions() {
return transactions;
}
public void setTransactions(Transactions transactions) {
this.transactions = transactions;
sections.clear();
char alpha = 0;
Section currentSection = null;
for (Transaction transaction : transactions.getTransactions()) {
String date = parseDate(transaction.getCreatedDate());
if (date.charAt(0) != alpha) {
if (currentSection != null) {
sections.add(currentSection);
}
currentSection = new Section();
alpha = date.charAt(0);
currentSection.alpha = String.valueOf(alpha);
}
if (currentSection != null) {
currentSection.transactions = this.transactions;
}
}
sections.add(currentSection);
notifyAllSectionsDataSetChanged();
}
private String parseDate(Date date) {
DateFormat df = new SimpleDateFormat("dd.MM.yyyy", Locale.getDefault());
String formattedDate = "";
formattedDate = df.format(date);
return formattedDate;
}
@Override
public int getNumberOfSections() {
return sections.size();
}
@Override
public boolean doesSectionHaveHeader(int sectionIndex) {
return true;
}
@Override
public boolean doesSectionHaveFooter(int sectionIndex) {
return false;
}
@Override
public int getNumberOfItemsInSection(int sectionIndex) {
return sections.get(sectionIndex).transactions.getTransactions().size();
}
@Override
public ItemViewHolder onCreateItemViewHolder(ViewGroup parent, int itemUserType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.wallet_item, parent, false);
return new ItemViewHolder(v);
}
@Override
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent, int headerUserType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.wallet_header, parent, false);
return new HeaderViewHolder(v);
}
@Override
public void onBindItemViewHolder(SectioningAdapter.ItemViewHolder viewHolder, int sectionIndex, int itemIndex, int itemType) {
Section section = sections.get(sectionIndex);
ItemViewHolder holder = (ItemViewHolder) viewHolder;
Transaction transaction = section.transactions.getTransactions().get(itemIndex);
holder.description.setText(transaction.getDescription());
holder.ammount.setText(String.valueOf(transaction.getAmount()));
holder.time.setText(parseDate(transaction.getCreatedDate()));
holder.total.setText(String.valueOf(transaction.getNewCredits()));
}
@Override
public void onBindHeaderViewHolder(SectioningAdapter.HeaderViewHolder viewHolder, int sectionIndex, int headerType) {
Section s = sections.get(sectionIndex);
HeaderViewHolder hvh = (HeaderViewHolder) viewHolder;
Transaction transaction = s.transactions.getTransactions().get(sectionIndex);
if (USE_DEBUG_APPEARANCE) {
hvh.itemView.setBackgroundColor(0x55ffffff);
hvh.dateHeader.setText(pad(sectionIndex * 2) + s.alpha);
} else {
hvh.dateHeader.setText(parseDate(transaction.getCreatedDate()));
}
}
private String pad(int spaces) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < spaces; i++) {
b.append(' ');
}
return b.toString();
}
public class HeaderViewHolder extends SectioningAdapter.HeaderViewHolder {
TextView dateHeader;
public HeaderViewHolder(View itemView) {
super(itemView);
dateHeader = (TextView) itemView.findViewById(R.id.date);
}
}
public class ItemViewHolder extends SectioningAdapter.ItemViewHolder {
TextView description;
TextView time;
TextView ammount;
TextView total;
public ItemViewHolder(View itemView) {
super(itemView);
description = (TextView) itemView.findViewById(R.id.description);
time = (TextView) itemView.findViewById(R.id.time);
ammount = (TextView) itemView.findViewById(R.id.ammount);
total = (TextView) itemView.findViewById(R.id.new_credits);
}
}
}
So if I do it this way, It sorts and creates headers/sections by date, but it puts all transactions in all sections, not inside matching date...
Seems like this should handle if item should have header or no. Smth like, if it is first item with this date return true, if not - false.
@Override
public boolean doesSectionHaveHeader(int sectionIndex) {
return true;
}
EDIT:
You can make filtered list before setting it. For example for address book with name letter header:
public class AddressBookDemoAdapter extends SectioningAdapter {
Locale locale = Locale.getDefault();
static final boolean USE_DEBUG_APPEARANCE = false;
private class Section {
String alpha;
ArrayList<Person> people = new ArrayList<>();
}
public class ItemViewHolder extends SectioningAdapter.ItemViewHolder {
TextView personNameTextView;
public ItemViewHolder(View itemView) {
super(itemView);
personNameTextView = (TextView) itemView.findViewById(R.id.personNameTextView);
}
}
public class HeaderViewHolder extends SectioningAdapter.HeaderViewHolder {
TextView titleTextView;
public HeaderViewHolder(View itemView) {
super(itemView);
titleTextView = (TextView) itemView.findViewById(R.id.titleTextView);
}
}
List<Person> people;
ArrayList<Section> sections = new ArrayList<>();
public AddressBookDemoAdapter() {
}
public List<Person> getPeople() {
return people;
}
public void setPeople(List<Person> people) {
this.people = people;
sections.clear();
// sort people into buckets by the first letter of last name
char alpha = 0;
Section currentSection = null;
for (Person person : people) {
if (person.name.last.charAt(0) != alpha) {
if (currentSection != null) {
sections.add(currentSection);
}
currentSection = new Section();
alpha = person.name.last.charAt(0);
currentSection.alpha = String.valueOf(alpha);
}
if (currentSection != null) {
currentSection.people.add(person);
}
}
sections.add(currentSection);
notifyAllSectionsDataSetChanged();
}
@Override
public int getNumberOfSections() {
return sections.size();
}
@Override
public int getNumberOfItemsInSection(int sectionIndex) {
return sections.get(sectionIndex).people.size();
}
@Override
public boolean doesSectionHaveHeader(int sectionIndex) {
return true;
}
@Override
public boolean doesSectionHaveFooter(int sectionIndex) {
return false;
}
@Override
public ItemViewHolder onCreateItemViewHolder(ViewGroup parent, int itemType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.list_item_addressbook_person, parent, false);
return new ItemViewHolder(v);
}
@Override
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent, int headerType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.list_item_addressbook_header, parent, false);
return new HeaderViewHolder(v);
}
@SuppressLint("SetTextI18n")
@Override
public void onBindItemViewHolder(SectioningAdapter.ItemViewHolder viewHolder, int sectionIndex, int itemIndex, int itemType) {
Section s = sections.get(sectionIndex);
ItemViewHolder ivh = (ItemViewHolder) viewHolder;
Person person = s.people.get(itemIndex);
ivh.personNameTextView.setText(capitalize(person.name.last) + ", " + capitalize(person.name.first));
}
@SuppressLint("SetTextI18n")
@Override
public void onBindHeaderViewHolder(SectioningAdapter.HeaderViewHolder viewHolder, int sectionIndex, int headerType) {
Section s = sections.get(sectionIndex);
HeaderViewHolder hvh = (HeaderViewHolder) viewHolder;
if (USE_DEBUG_APPEARANCE) {
hvh.itemView.setBackgroundColor(0x55ffffff);
hvh.titleTextView.setText(pad(sectionIndex * 2) + s.alpha);
} else {
hvh.titleTextView.setText(s.alpha);
}
}
private String capitalize(String s) {
if (s != null && s.length() > 0) {
return s.substring(0,1).toUpperCase(locale) + s.substring(1);
}
return "";
}
private String pad(int spaces) {
StringBuilder b = new StringBuilder();
for (int i = 0; i < spaces; i++) {
b.append(' ');
}
return b.toString();
}
}