From 6b1dd74ceb565f194ca2d45d51ee2dbd747c78a1 Mon Sep 17 00:00:00 2001 From: Mario Velasco Date: Mon, 1 Feb 2016 19:23:50 +0100 Subject: [PATCH 1/4] Support GridLayoutManager --- .../HeaderPositionCalculator.java | 7 ++++++ .../StickyRecyclerHeadersAdapter.java | 6 +++++ .../StickyRecyclerHeadersDecoration.java | 3 ++- .../sample/MainActivity.java | 20 +++++++++++++-- sample/src/main/res/values/arrays.xml | 25 ------------------- 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/library/src/main/java/com/timehop/stickyheadersrecyclerview/HeaderPositionCalculator.java b/library/src/main/java/com/timehop/stickyheadersrecyclerview/HeaderPositionCalculator.java index d7bf82e..d12f03a 100644 --- a/library/src/main/java/com/timehop/stickyheadersrecyclerview/HeaderPositionCalculator.java +++ b/library/src/main/java/com/timehop/stickyheadersrecyclerview/HeaderPositionCalculator.java @@ -74,6 +74,13 @@ public boolean hasNewHeader(int position, boolean isReverseLayout) { return false; } + int numColumns = mAdapter.getNumColumns(); + int columnOfItem = position % numColumns; + if (columnOfItem > 0) { + int firstItemOnRowPosition = position - columnOfItem; + return hasNewHeader(firstItemOnRowPosition, isReverseLayout); + } + long headerId = mAdapter.getHeaderId(position); if (headerId < 0) { diff --git a/library/src/main/java/com/timehop/stickyheadersrecyclerview/StickyRecyclerHeadersAdapter.java b/library/src/main/java/com/timehop/stickyheadersrecyclerview/StickyRecyclerHeadersAdapter.java index 23990fa..0072bc3 100644 --- a/library/src/main/java/com/timehop/stickyheadersrecyclerview/StickyRecyclerHeadersAdapter.java +++ b/library/src/main/java/com/timehop/stickyheadersrecyclerview/StickyRecyclerHeadersAdapter.java @@ -36,4 +36,10 @@ public interface StickyRecyclerHeadersAdapter 0) { continue; } diff --git a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java index 591bd10..bf0a547 100644 --- a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java +++ b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java @@ -6,6 +6,7 @@ import android.os.Handler; import android.os.Looper; import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; @@ -24,6 +25,8 @@ public class MainActivity extends AppCompatActivity { + private static final int NUM_COLUMNS = 3; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -35,7 +38,8 @@ protected void onCreate(Bundle savedInstanceState) { // Set adapter populated with example dummy data final AnimalsHeadersAdapter adapter = new AnimalsHeadersAdapter(); - adapter.add("Animals below!"); + adapter.setNumColumns(NUM_COLUMNS); +// adapter.add("Animals below!"); adapter.addAll(getDummyDataSet()); recyclerView.setAdapter(adapter); @@ -58,7 +62,9 @@ public void run() { // Set layout manager int orientation = getLayoutManagerOrientation(getResources().getConfiguration().orientation); - final LinearLayoutManager layoutManager = new LinearLayoutManager(this, orientation, isReverseButton.isChecked()); +// final LinearLayoutManager layoutManager = new LinearLayoutManager(this, orientation, isReverseButton.isChecked()); + + final GridLayoutManager layoutManager = new GridLayoutManager(this, NUM_COLUMNS); recyclerView.setLayoutManager(layoutManager); // Add the sticky headers decoration @@ -118,6 +124,8 @@ private int getLayoutManagerOrientation(int activityOrientation) { private class AnimalsHeadersAdapter extends AnimalsAdapter implements StickyRecyclerHeadersAdapter { + private int numColumns = 1; + @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) @@ -163,5 +171,13 @@ private int getRandomColor() { }); } + @Override + public int getNumColumns() { + return numColumns; + } + + public void setNumColumns(int numColumns) { + this.numColumns = numColumns; + } } } diff --git a/sample/src/main/res/values/arrays.xml b/sample/src/main/res/values/arrays.xml index 3254d55..b99b880 100644 --- a/sample/src/main/res/values/arrays.xml +++ b/sample/src/main/res/values/arrays.xml @@ -205,12 +205,9 @@ Egyptian Mau Electric Eel Elephant - Elephant Seal - Elephant Shrew Emperor Penguin Emperor Tamarin Emu - English Cocker Spaniel English Shepherd English Springer Spaniel Entlebucher Mountain Dog @@ -223,7 +220,6 @@ Field Spaniel Fin Whale Finnish Spitz - Fire-Bellied Toad Fish Fishing Cat Flamingo @@ -246,8 +242,6 @@ Gentoo Penguin Geoffroys Tamarin Gerbil - German Pinscher - German Shepherd Gharial Giant African Land Snail Giant Clam @@ -293,8 +287,6 @@ Himalayan Hippopotamus Honey Bee - Horn Shark - Horned Frog Horse Horseshoe Crab Howler Monkey @@ -310,7 +302,6 @@ Indian Elephant Indian Palm Squirrel Indian Rhinoceros - Indian Star Tortoise Indochinese Tiger Indri Insect @@ -320,16 +311,12 @@ Jackal Jaguar Japanese Chin - Japanese Macaque - Javan Rhinoceros Javanese Jellyfish Kakapo Kangaroo Keel Billed Toucan Killer Whale - King Crab - King Penguin Kingfisher Kiwi Koala @@ -345,7 +332,6 @@ Leopard Cat Leopard Seal Leopard Tortoise - Liger Lion Lionfish Little Penguin @@ -381,8 +367,6 @@ Monitor Lizard Monkey Monte Iberia Eleuth - Moorhen - Moose Moray Eel Moth Mountain Gorilla @@ -406,7 +390,6 @@ Opossum Orang-utan Ostrich - Otter Oyster Pademelon Panther @@ -416,8 +399,6 @@ Pekingese Pelican Penguin - Persian - Pheasant Pied Tamarin Pig Pika @@ -445,7 +426,6 @@ Pygmy Marmoset Quail Quetzal - Quokka Quoll Rabbit Raccoon @@ -455,7 +435,6 @@ Rat Rattlesnake Red Knee Tarantula - Red Panda Red Wolf Red-handed Tamarin Reindeer @@ -476,7 +455,6 @@ Saola Scorpion Scorpion Fish - Sea Dragon Sea Lion Sea Otter Sea Slug @@ -542,8 +520,6 @@ Tiffany Tiger Tiger Salamander - Tiger Shark - Tortoise Toucan Tree Frog Tropicbird @@ -583,7 +559,6 @@ Woolly Mammoth Woolly Monkey Wrasse - X-Ray Tetra Yak Yellow-Eyed Penguin Yorkshire Terrier From 67ef3f578f09216162e1491d0df604e129349a75 Mon Sep 17 00:00:00 2001 From: Mario Velasco Date: Tue, 2 Feb 2016 12:20:31 +0100 Subject: [PATCH 2/4] reorder items when adding or removing items --- .../sample/AnimalsAdapter.java | 2 +- .../sample/MainActivity.java | 82 +++++++++++++++++-- sample/src/main/res/values/arrays.xml | 26 ++++++ 3 files changed, 103 insertions(+), 7 deletions(-) diff --git a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/AnimalsAdapter.java b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/AnimalsAdapter.java index 1872b4c..04afa62 100644 --- a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/AnimalsAdapter.java +++ b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/AnimalsAdapter.java @@ -12,7 +12,7 @@ */ public abstract class AnimalsAdapter extends RecyclerView.Adapter { - private ArrayList items = new ArrayList(); + protected ArrayList items = new ArrayList(); public AnimalsAdapter() { setHasStableIds(true); diff --git a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java index bf0a547..2c4acdf 100644 --- a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java +++ b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java @@ -9,6 +9,7 @@ import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -22,6 +23,7 @@ import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersTouchListener; import java.security.SecureRandom; +import java.util.Collection; public class MainActivity extends AppCompatActivity { @@ -124,7 +126,8 @@ private int getLayoutManagerOrientation(int activityOrientation) { private class AnimalsHeadersAdapter extends AnimalsAdapter implements StickyRecyclerHeadersAdapter { - private int numColumns = 1; + private static final String EMPTY_NAME = " "; + private int numColumns = 1; @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @@ -142,11 +145,12 @@ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { @Override public long getHeaderId(int position) { - if (position == 0) { - return -1; - } else { - return getItem(position).charAt(0); - } + int numColumnOfItem = position % numColumns; + if (numColumnOfItem == 0) { + return getFirstChar(getItem(position)); + } else { + return getHeaderId(position - numColumnOfItem); + } } @Override @@ -179,5 +183,71 @@ public int getNumColumns() { public void setNumColumns(int numColumns) { this.numColumns = numColumns; } + + @Override + public void add(int index, String object) { + super.add(index, object); + reorderItems(); + } + + @Override + public void add(String object) { + super.add(object); + reorderItems(); + } + + @Override + public void addAll(Collection collection) { + super.addAll(collection); + reorderItems(); + } + + @Override + public void addAll(String... items) { + super.addAll(items); + reorderItems(); + } + + @Override + public void remove(String object) { + super.remove(object); + reorderItems(); + } + + private void reorderItems() { + long firstCharOnLastItem = -1; + + for (int i = 0; i < items.size(); i++) { + String item = items.get(i); + if (getFirstChar(item) != firstCharOnLastItem) { // new header found for item + int numColumnOfItem = i % numColumns; + if (numColumnOfItem > 0 && !EMPTY_NAME.equals(item)) { // fill row with empty items + int emptyVideos = numColumns - numColumnOfItem; + for (int j = 0; j < emptyVideos; j++) { + items.add(i, EMPTY_NAME); + if (j != emptyVideos - 1) { + i++; + } + } + continue; + } else if (numColumnOfItem == 0 && EMPTY_NAME.equals(item)){ + // remove empty items to avoid empty rows when removing items + while (items.get(i).equals(EMPTY_NAME)) { + items.remove(i); + } + i--; + } + firstCharOnLastItem = getFirstChar(item); + } + } + } + + private int getFirstChar(String name) { + if (TextUtils.isEmpty(name)) { + return 0; + } else { + return name.charAt(0); + } + } } } diff --git a/sample/src/main/res/values/arrays.xml b/sample/src/main/res/values/arrays.xml index b99b880..f4282b9 100644 --- a/sample/src/main/res/values/arrays.xml +++ b/sample/src/main/res/values/arrays.xml @@ -17,6 +17,7 @@ Airedale Terrier Akbash Akita + Akita Alaskan Malamute Albatross Aldabra Giant Tortoise @@ -205,9 +206,12 @@ Egyptian Mau Electric Eel Elephant + Elephant Seal + Elephant Shrew Emperor Penguin Emperor Tamarin Emu + English Cocker Spaniel English Shepherd English Springer Spaniel Entlebucher Mountain Dog @@ -220,6 +224,7 @@ Field Spaniel Fin Whale Finnish Spitz + Fire-Bellied Toad Fish Fishing Cat Flamingo @@ -242,6 +247,8 @@ Gentoo Penguin Geoffroys Tamarin Gerbil + German Pinscher + German Shepherd Gharial Giant African Land Snail Giant Clam @@ -287,6 +294,8 @@ Himalayan Hippopotamus Honey Bee + Horn Shark + Horned Frog Horse Horseshoe Crab Howler Monkey @@ -302,6 +311,7 @@ Indian Elephant Indian Palm Squirrel Indian Rhinoceros + Indian Star Tortoise Indochinese Tiger Indri Insect @@ -311,12 +321,16 @@ Jackal Jaguar Japanese Chin + Japanese Macaque + Javan Rhinoceros Javanese Jellyfish Kakapo Kangaroo Keel Billed Toucan Killer Whale + King Crab + King Penguin Kingfisher Kiwi Koala @@ -332,6 +346,7 @@ Leopard Cat Leopard Seal Leopard Tortoise + Liger Lion Lionfish Little Penguin @@ -367,6 +382,8 @@ Monitor Lizard Monkey Monte Iberia Eleuth + Moorhen + Moose Moray Eel Moth Mountain Gorilla @@ -390,6 +407,7 @@ Opossum Orang-utan Ostrich + Otter Oyster Pademelon Panther @@ -399,6 +417,8 @@ Pekingese Pelican Penguin + Persian + Pheasant Pied Tamarin Pig Pika @@ -426,6 +446,7 @@ Pygmy Marmoset Quail Quetzal + Quokka Quoll Rabbit Raccoon @@ -435,6 +456,7 @@ Rat Rattlesnake Red Knee Tarantula + Red Panda Red Wolf Red-handed Tamarin Reindeer @@ -455,6 +477,7 @@ Saola Scorpion Scorpion Fish + Sea Dragon Sea Lion Sea Otter Sea Slug @@ -520,6 +543,8 @@ Tiffany Tiger Tiger Salamander + Tiger Shark + Tortoise Toucan Tree Frog Tropicbird @@ -559,6 +584,7 @@ Woolly Mammoth Woolly Monkey Wrasse + X-Ray Tetra Yak Yellow-Eyed Penguin Yorkshire Terrier From 55f4de31667bcc97f2148bc759034a0044c71d10 Mon Sep 17 00:00:00 2001 From: Mario Velasco Date: Tue, 2 Feb 2016 12:26:48 +0100 Subject: [PATCH 3/4] duplicated item removed --- sample/src/main/res/values/arrays.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/sample/src/main/res/values/arrays.xml b/sample/src/main/res/values/arrays.xml index f4282b9..3254d55 100644 --- a/sample/src/main/res/values/arrays.xml +++ b/sample/src/main/res/values/arrays.xml @@ -17,7 +17,6 @@ Airedale Terrier Akbash Akita - Akita Alaskan Malamute Albatross Aldabra Giant Tortoise From d416b261d3d1e15e1723bf90fca741303299c6f0 Mon Sep 17 00:00:00 2001 From: Mario Velasco Date: Tue, 2 Feb 2016 12:57:26 +0100 Subject: [PATCH 4/4] Fix. Case when removing all elements of section --- .../stickyheadersrecyclerview/sample/MainActivity.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java index 2c4acdf..52d50aa 100644 --- a/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java +++ b/sample/src/main/java/com/timehop/stickyheadersrecyclerview/sample/MainActivity.java @@ -237,7 +237,9 @@ private void reorderItems() { } i--; } - firstCharOnLastItem = getFirstChar(item); + if (!EMPTY_NAME.equals(item)) { + firstCharOnLastItem = getFirstChar(item); + } } } }