【问题标题】:How to sort items in RecyclerView depending on a Date如何根据日期对 RecyclerView 中的项目进行排序
【发布时间】:2017-05-11 22:45:55
【问题描述】:

这就是我的屏幕应该的样子。

我添加了这个库 https://github.com/ShamylZakariya/StickyHeaders 并尝试以类似的方式进行操作。

我的模型如下所示:

公共类交易{

private int id;
private Date createdDate;
private String description;
private int amount;
private float newCredits;
}

public class Transactions {

private int totalCount;
private List<Transaction> transactions = new ArrayList<>();
}

所以在我获取所有交易后,我在适配器中设置了数据。这就是我的适配器的样子:

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);
    }
}

}

因此,如果我这样做,它会按日期对标题/部分进行排序和创建,但它将所有交易放在所有部分中,而不是在匹配日期内...

【问题讨论】:

  • 您可以在发送到适配器之前根据日期对数组列表进行排序
  • 它实际上是排序的,我在标题中得到它,但问题是,对于每个日期,我必须只获得该日期的交易......如果我在一个日期有 2 笔交易,我会标题下方有 2 项,就像我忘记上传的图片一样 :) 我将编辑我的问题,以便您查看

标签: android android-recyclerview android-viewholder stickyrecycleview


【解决方案1】:

如果项目是否应该有标题,似乎应该处理。类似,如果它是具有此日期的第一项,则返回 true,如果不是 - false。

@Override
public boolean doesSectionHaveHeader(int sectionIndex) {
    return true;
}

编辑

您可以在设置之前制作过滤列表。 例如带有姓名字母标题的地址簿:

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();
    }

}

【讨论】:

  • 我不太确定该怎么写。如果您能给我一个提示,我将不胜感激...但我认为这是主要问题,因为我得到了每个日期的所有交易(部分),但我不知道应该怎么写:@Override public int getNumberOfItemsInSection(int sectionIndex) { return section.get(sectionIndex).transactions.getTransactions().size(); }
  • 我试图通过在 TreeSet 中添加所有交易日期然后循环遍历它们来解决标题问题,但这没有帮助(在 setTransactions() 方法中..
  • @joe 这样的事情怎么样?返回sectionIndex == 0? true : item.get(sectionIndex).getDate() != item.get(sectionIndex-1).getDate();
  • 太棒了!我只需要比较解析的日期,因为日期不相等,因为不同的驯服......你知道如何处理 getNumberOfItemsInSection() 方法吗?
  • @joe 更新了我的答案。添加了一些地址簿示例。
【解决方案2】:

您可以在 Transaction 类中使用可比较的接口,并与要排序的特定字段进行比较

【讨论】:

  • 我认为我不必这样做,因为我让它们在响应 ASC 或 DESC 中排序......但问题是每个日期(部分)的那些标题(部分)和数据(交易) ...它列出了每个日期的所有交易
猜你喜欢
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 2023-03-14
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多