Skip to content

Instantly share code, notes, and snippets.

@mohammedragabmohammedborik
Forked from gabrielemariotti/README.md
Created February 26, 2018 09:22
Show Gist options
  • Save mohammedragabmohammedborik/18d48a981eaf27611274081e889c784d to your computer and use it in GitHub Desktop.
Save mohammedragabmohammedborik/18d48a981eaf27611274081e889c784d to your computer and use it in GitHub Desktop.

Revisions

  1. @gabrielemariotti gabrielemariotti revised this gist Jan 15, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -40,4 +40,4 @@ Example:
    mRecyclerView.setAdapter(mSectionedAdapter);
    ```

    You can customize the section layout, changing the layout `section.xm`l and changing the code in the `SectionedGridRecyclerViewAdapter.SectionViewHolder` class and `SectionedGridRecyclerViewAdapter#onBindViewHolder` method.
    You can customize the section layout, changing the layout `section.xml` and changing the code in the `SectionedGridRecyclerViewAdapter.SectionViewHolder` class and `SectionedGridRecyclerViewAdapter#onBindViewHolder` method.
  2. @gabrielemariotti gabrielemariotti revised this gist Jan 15, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@ You can use this class to realize a simple sectioned grid `RecyclerView.Adapter`

    ![Screen](http://3.bp.blogspot.com/-8cl5IxT3X7c/VLhOC8EWUiI/AAAAAAAAkMs/2V9K-EoPThc/s400/sectionedGridRecycler.png)

    The `RecyclerView` have to use a `GridLayoutManager`.
    The `RecyclerView` has to use a `GridLayoutManager`.

    This is a porting of the class `SimpleSectionedListAdapter` provided by [Google](https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/SimpleSectionedListAdapter.java)

  3. @gabrielemariotti gabrielemariotti created this gist Jan 15, 2015.
    43 changes: 43 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,43 @@
    You can use this class to realize a simple sectioned grid `RecyclerView.Adapter` without changing your code.

    ![Screen](http://3.bp.blogspot.com/-8cl5IxT3X7c/VLhOC8EWUiI/AAAAAAAAkMs/2V9K-EoPThc/s400/sectionedGridRecycler.png)

    The `RecyclerView` have to use a `GridLayoutManager`.

    This is a porting of the class `SimpleSectionedListAdapter` provided by [Google](https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/SimpleSectionedListAdapter.java)

    If you are looking for a sectioned list `RecyclerView.Adapter` you can take a look [here](https://gist.github.com/gabrielemariotti/4c189fb1124df4556058)


    Example:
    ```java
    //Your RecyclerView
    mRecyclerView = (RecyclerView) getActivity().findViewById(R.id.list);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(),4));

    //Your RecyclerView.Adapter
    mAdapter = new SimpleAdapter(getActivity());

    //This is the code to provide a sectioned grid
    List<SectionedGridRecyclerViewAdapter.Section> sections =
    new ArrayList<SectionedGridRecyclerViewAdapter.Section>();

    //Sections
    sections.add(new SectionedGridRecyclerViewAdapter.Section(0,"Section 1"));
    sections.add(new SectionedGridRecyclerViewAdapter.Section(5,"Section 2"));
    sections.add(new SectionedGridRecyclerViewAdapter.Section(12,"Section 3"));
    sections.add(new SectionedGridRecyclerViewAdapter.Section(14,"Section 4"));
    sections.add(new SectionedGridRecyclerViewAdapter.Section(20,"Section 5"));

    //Add your adapter to the sectionAdapter
    SectionedGridRecyclerViewAdapter.Section[] dummy = new SectionedGridRecyclerViewAdapter.Section[sections.size()];
    SectionedGridRecyclerViewAdapter mSectionedAdapter = new
    SectionedGridRecyclerViewAdapter(getActivity(),R.layout.section,R.id.section_text,mRecyclerView,mAdapter);
    mSectionedAdapter.setSections(sections.toArray(dummy));

    //Apply this adapter to the RecyclerView
    mRecyclerView.setAdapter(mSectionedAdapter);
    ```

    You can customize the section layout, changing the layout `section.xm`l and changing the code in the `SectionedGridRecyclerViewAdapter.SectionViewHolder` class and `SectionedGridRecyclerViewAdapter#onBindViewHolder` method.
    183 changes: 183 additions & 0 deletions SectionedGridRecyclerViewAdapter.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,183 @@
    /**
    * @author Gabriele Mariotti ([email protected])
    */
    public class SectionedGridRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private final Context mContext;
    private static final int SECTION_TYPE = 0;

    private boolean mValid = true;
    private int mSectionResourceId;
    private int mTextResourceId;
    private LayoutInflater mLayoutInflater;
    private RecyclerView.Adapter mBaseAdapter;
    private SparseArray<Section> mSections = new SparseArray<Section>();
    private RecyclerView mRecyclerView;


    public SectionedGridRecyclerViewAdapter(Context context, int sectionResourceId, int textResourceId,RecyclerView recyclerView,
    RecyclerView.Adapter baseAdapter) {

    mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    mSectionResourceId = sectionResourceId;
    mTextResourceId = textResourceId;
    mBaseAdapter = baseAdapter;
    mContext = context;
    mRecyclerView = recyclerView;

    mBaseAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
    @Override
    public void onChanged() {
    mValid = mBaseAdapter.getItemCount()>0;
    notifyDataSetChanged();
    }

    @Override
    public void onItemRangeChanged(int positionStart, int itemCount) {
    mValid = mBaseAdapter.getItemCount()>0;
    notifyItemRangeChanged(positionStart, itemCount);
    }

    @Override
    public void onItemRangeInserted(int positionStart, int itemCount) {
    mValid = mBaseAdapter.getItemCount()>0;
    notifyItemRangeInserted(positionStart, itemCount);
    }

    @Override
    public void onItemRangeRemoved(int positionStart, int itemCount) {
    mValid = mBaseAdapter.getItemCount()>0;
    notifyItemRangeRemoved(positionStart, itemCount);
    }
    });

    final GridLayoutManager layoutManager = (GridLayoutManager)(mRecyclerView.getLayoutManager());
    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
    return (isSectionHeaderPosition(position))? layoutManager.getSpanCount() : 1 ;
    }
    });
    }


    public static class SectionViewHolder extends RecyclerView.ViewHolder {

    public TextView title;

    public SectionViewHolder(View view,int mTextResourceid) {
    super(view);
    title = (TextView) view.findViewById(mTextResourceid);
    }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int typeView) {
    if (typeView == SECTION_TYPE) {
    final View view = LayoutInflater.from(mContext).inflate(mSectionResourceId, parent, false);
    return new SectionViewHolder(view,mTextResourceId);
    }else{
    return mBaseAdapter.onCreateViewHolder(parent, typeView -1);
    }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder sectionViewHolder, int position) {
    if (isSectionHeaderPosition(position)) {
    ((SectionViewHolder)sectionViewHolder).title.setText(mSections.get(position).title);
    }else{
    mBaseAdapter.onBindViewHolder(sectionViewHolder,sectionedPositionToPosition(position));
    }

    }

    @Override
    public int getItemViewType(int position) {
    return isSectionHeaderPosition(position)
    ? SECTION_TYPE
    : mBaseAdapter.getItemViewType(sectionedPositionToPosition(position)) +1 ;
    }


    public static class Section {
    int firstPosition;
    int sectionedPosition;
    CharSequence title;

    public Section(int firstPosition, CharSequence title) {
    this.firstPosition = firstPosition;
    this.title = title;
    }

    public CharSequence getTitle() {
    return title;
    }
    }


    public void setSections(Section[] sections) {
    mSections.clear();

    Arrays.sort(sections, new Comparator<Section>() {
    @Override
    public int compare(Section o, Section o1) {
    return (o.firstPosition == o1.firstPosition)
    ? 0
    : ((o.firstPosition < o1.firstPosition) ? -1 : 1);
    }
    });

    int offset = 0; // offset positions for the headers we're adding
    for (Section section : sections) {
    section.sectionedPosition = section.firstPosition + offset;
    mSections.append(section.sectionedPosition, section);
    ++offset;
    }

    notifyDataSetChanged();
    }

    public int positionToSectionedPosition(int position) {
    int offset = 0;
    for (int i = 0; i < mSections.size(); i++) {
    if (mSections.valueAt(i).firstPosition > position) {
    break;
    }
    ++offset;
    }
    return position + offset;
    }

    public int sectionedPositionToPosition(int sectionedPosition) {
    if (isSectionHeaderPosition(sectionedPosition)) {
    return RecyclerView.NO_POSITION;
    }

    int offset = 0;
    for (int i = 0; i < mSections.size(); i++) {
    if (mSections.valueAt(i).sectionedPosition > sectionedPosition) {
    break;
    }
    --offset;
    }
    return sectionedPosition + offset;
    }

    public boolean isSectionHeaderPosition(int position) {
    return mSections.get(position) != null;
    }


    @Override
    public long getItemId(int position) {
    return isSectionHeaderPosition(position)
    ? Integer.MAX_VALUE - mSections.indexOfKey(position)
    : mBaseAdapter.getItemId(sectionedPositionToPosition(position));
    }

    @Override
    public int getItemCount() {
    return (mValid ? mBaseAdapter.getItemCount() + mSections.size() : 0);
    }

    }
    53 changes: 53 additions & 0 deletions SimpleAdapter.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,53 @@
    /**
    * @author Gabriele Mariotti ([email protected])
    */
    public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.SimpleViewHolder> {
    private static final int COUNT = 100;

    private final Context mContext;
    private final List<Integer> mItems;
    private int mCurrentItemId = 0;

    public static class SimpleViewHolder extends RecyclerView.ViewHolder {
    public final TextView title;

    public SimpleViewHolder(View view) {
    super(view);
    title = (TextView) view.findViewById(R.id.title);
    }
    }

    public SimpleAdapter(Context context) {
    mContext = context;
    mItems = new ArrayList<Integer>(COUNT);
    for (int i = 0; i < COUNT; i++) {
    addItem(i);
    }
    }

    public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    final View view = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
    return new SimpleViewHolder(view);
    }

    @Override
    public void onBindViewHolder(SimpleViewHolder holder, final int position) {
    holder.title.setText(mItems.get(position).toString());
    }

    public void addItem(int position) {
    final int id = mCurrentItemId++;
    mItems.add(position, id);
    notifyItemInserted(position);
    }

    public void removeItem(int position) {
    mItems.remove(position);
    notifyItemRemoved(position);
    }

    @Override
    public int getItemCount() {
    return mItems.size();
    }
    }
    11 changes: 11 additions & 0 deletions item.xml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/title"
    android:layout_width="match_parent"
    android:layout_height="130dp"
    android:gravity="center"
    android:layout_margin="4dp"
    android:textColor="#999999"
    android:textStyle="bold"
    android:textSize="22sp"
    android:background="@drawable/item_background"/>
    13 changes: 13 additions & 0 deletions section.xml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,13 @@
    <?xml version="1.0" encoding="utf-8"?>

    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="48dp"
    android:gravity="center_vertical"
    android:paddingLeft="16dp"
    android:singleLine="true"
    android:textAllCaps="true"
    android:background="#90CAF9"
    android:textSize="16sp"
    android:id="@+id/section_text"
    android:textStyle="bold" />