【问题标题】:Sticky header/item in recyclerview回收站视图中的粘性标题/项目
【发布时间】:2015-08-27 18:13:40
【问题描述】:

我已经成功地在回收站视图中实现了部分,如屏幕截图所示,具有两种不同类型的视图。 我如何在回收站视图中实现粘性标题。 我希望“A”一直保持在顶部,直到用户向上滚动,在这种情况下,下一个要粘在顶部的项目将是“B”。 我该怎么做?

【问题讨论】:

标签: android list view header sticky


【解决方案1】:

你肯定会想要为此使用一个库。 Emil Sjölander 的StickyListHeaders 是一个不错的选择(我在多个项目中使用过它),但也有其他库。

不知道您的代码的具体细节,这里是您如何使用 StickyListHeaders 的粗略草图:

  • 为您的项目和标题创建布局(您可能已经有了)。假设它们被称为item_cheese.xmlitem_header.xml

  • 在布局文件中将 ListView 替换为 StickyListHeadersListView

  • 为您的奶酪集合创建一个自定义适配器(您可能已经拥有该适配器)并使其实现StickyListHeadersAdapter

接口只增加了两个方法:

public interface StickyListHeadersAdapter extends ListAdapter {
    View getHeaderView(int position, View view, ViewGroup parent);
    long getHeaderId(int position);
}

您的适配器的完整实现如下所示。它对项目和标题都使用ViewHolders(回收视图,就像你问的那样):

public class CheeseAdapter extends BaseAdapter implements StickyListHeadersAdapter {

    private List<String> cheeses;
    private final LayoutInflater inflater;

    public CheeseAdapter(Context context, List<String> cheeses) {
        // Assuming cheeses are already alphabetically sorted at this point
        this.cheeses = cheeses;
        this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return (cheeses != null) ? cheeses.size() : 0;
    }

    @Override
    public Object getItem(int position) {
        return cheeses.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View view, ViewGroup parent) {
        CheeseViewHolder holder;
        if (view != null)
            holder = (CheeseViewHolder) view.getTag();
        else {
            view = inflater.inflate(R.layout.item_cheese, parent, false);
            holder = new CheeseViewHolder(view);
            view.setTag(holder);
        }
        holder.decorate(cheeses.get(position));
        return view;
    }

    @Override
    public long getHeaderId(int position) {
        // Return the first char of each item as its header ID
        return cheeses.get(position).charAt(0);
    }

    @Override
    public View getHeaderView(int position, View view, ViewGroup parent) {
        HeaderViewHolder holder;
        if (view != null)
            holder = (HeaderViewHolder) view.getTag();
        else {
            view = inflater.inflate(R.layout.item_header, parent, false);
            holder = new HeaderViewHolder(view);
            view.setTag(holder);
        }
        holder.decorate(cheeses.get(position));
        return view;
    }

    public class CheeseViewHolder {

        TextView tvCheeseName;

        public CheeseViewHolder(View view) {
            tvCheeseName = (TextView) view.findViewById(R.id.tvCheeseName);
        }

        public void decorate(String cheeseName) {
            if (cheeseName == null) return;
            tvCheeseName.setText(cheeseName);
        }
    }

    public class HeaderViewHolder {

        TextView tvHeader;

        public CheeseViewHolder(View view) {
            tvHeader = (TextView) view.findViewById(R.id.tvHeader);
        }

        public void decorate(String cheeseName) {
            if (cheeseName == null || cheeseName.isEmpty()) return;
            tvHeader.setText(cheeseName.toUpperCase().charAt(0));
        }
    }
}
  • 在您的 Activity 或 Fragment 中使用自定义适配器。 ScrollView 将包含带有粘性标题的字母部分,其行为为 just as advertised

就这么简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-25
    • 2022-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多