diff --git a/app/src/main/java/tellh/com/recyclerstickyheaderview/MainActivity.java b/app/src/main/java/tellh/com/recyclerstickyheaderview/MainActivity.java
index ba0acc0..ee1d70b 100644
--- a/app/src/main/java/tellh/com/recyclerstickyheaderview/MainActivity.java
+++ b/app/src/main/java/tellh/com/recyclerstickyheaderview/MainActivity.java
@@ -13,6 +13,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
+import java.util.Random;
import tellh.com.stickyheaderview_rv.adapter.DataBean;
import tellh.com.stickyheaderview_rv.adapter.StickyHeaderViewAdapter;
@@ -20,6 +21,7 @@
public class MainActivity extends AppCompatActivity {
private RecyclerView rv;
private StickyHeaderViewAdapter adapter;
+ private Random random = new Random(System.currentTimeMillis());
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -74,9 +76,11 @@ public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add_view:
User user = new User("Sticky View", 123, "https://avatars.githubusercontent.com/u/15800681?v=3");
- user.setShouldSticky(true);
- adapter.getDisplayList().add(3, user);
- adapter.notifyItemInserted(3);
+ user.setShouldSticky(random.nextBoolean());
+ adapter.append(user);
+ break;
+ case R.id.action_clear_all:
+ adapter.clear(rv);
break;
default:
break;
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
index 8b38acb..56afae3 100644
--- a/app/src/main/res/menu/menu_main.xml
+++ b/app/src/main/res/menu/menu_main.xml
@@ -1,5 +1,5 @@
\ No newline at end of file
diff --git a/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/LinkListStack.java b/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/LinkListStack.java
new file mode 100644
index 0000000..fa32ba6
--- /dev/null
+++ b/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/LinkListStack.java
@@ -0,0 +1,42 @@
+package tellh.com.stickyheaderview_rv;
+
+import java.util.EmptyStackException;
+import java.util.LinkedList;
+
+/**
+ * Created by tlh on 2017/5/11 :)
+ */
+
+public class LinkListStack {
+ private LinkedList list = new LinkedList<>();
+
+ public E push(E item) {
+ list.addLast(item);
+ return item;
+ }
+
+ public E pop() {
+ if (list.isEmpty())
+ return null;
+ return list.removeLast();
+ }
+
+ public synchronized E peek() {
+ if (list.size() == 0)
+ throw new EmptyStackException();
+ return list.peekLast();
+ }
+
+ public boolean isEmpty() {
+ return list.size() == 0;
+ }
+
+ public void clear() {
+ list.clear();
+ }
+
+ public boolean remove(E item) {
+ return list.remove(item);
+ }
+
+}
diff --git a/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/StickyHeaderView.java b/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/StickyHeaderView.java
index b8beb42..477e7b0 100644
--- a/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/StickyHeaderView.java
+++ b/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/StickyHeaderView.java
@@ -11,9 +11,6 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
-import java.util.List;
-import java.util.Stack;
-
import tellh.com.stickyheaderview_rv.adapter.DataBean;
import tellh.com.stickyheaderview_rv.adapter.StickyHeaderViewAdapter;
import tellh.com.stickyheaderview_rv.adapter.ViewBinder;
@@ -22,14 +19,15 @@
* Created by tlh on 2017/1/21 :)
*/
-public class StickyHeaderView extends FrameLayout {
+public class StickyHeaderView extends FrameLayout
+ implements StickyHeaderViewAdapter.DataSetChangeListener {
private boolean hasInit = false;
private FrameLayout mHeaderContainer;
private RecyclerView mRecyclerView;
private int mHeaderHeight = -1;
private StickyHeaderViewAdapter adapter;
private LinearLayoutManager layoutManager;
- private Stack stickyHeaderPositionStack = new Stack<>();
+ private LinkListStack stickyHeaderStack = new LinkListStack<>();
private SparseArray mViewHolderCache;
public StickyHeaderView(Context context) {
@@ -70,6 +68,7 @@ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
throw new RuntimeException
("Your RecyclerView.Adapter should be the type of StickyHeaderViewAdapter.");
StickyHeaderView.this.adapter = (StickyHeaderViewAdapter) adapter;
+ StickyHeaderView.this.adapter.setDataSetChangeListener(StickyHeaderView.this);
layoutManager = (LinearLayoutManager) mRecyclerView.getLayoutManager();
mViewHolderCache = new SparseArray<>();
} /*else if (mHeaderHeight == 0) {
@@ -83,17 +82,19 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (mHeaderHeight == -1 || adapter == null || layoutManager == null)
return;
- List displayList = adapter.getDisplayList();
- if (stickyHeaderPositionStack.isEmpty())
- stickyHeaderPositionStack.push(findFirstVisibleStickyHeaderPosition(displayList, 0));
+ if (stickyHeaderStack.isEmpty() && adapter.getDisplayListSize() != 0)
+ stickyHeaderStack.push(adapter.get(findFirstVisibleStickyHeaderPosition(0)));
int firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition();
- int firstVisibleStickyHeaderPosition = findFirstVisibleStickyHeaderPosition(displayList, firstVisibleItemPosition);
- int currentStickyHeaderPosition = stickyHeaderPositionStack.peek();
+ if (firstVisibleItemPosition == -1)
+ return;
+ int firstVisibleStickyHeaderPosition = findFirstVisibleStickyHeaderPosition(firstVisibleItemPosition);
+ int currentStickyHeaderPosition = adapter.getPosition(stickyHeaderStack.peek());
if (firstVisibleStickyHeaderPosition - firstVisibleItemPosition > 1) {
return;
}
// 如果两个连续两个都是StickyView, 取下面那个View
- if (displayList.get(firstVisibleStickyHeaderPosition + 1).shouldSticky())
+ DataBean dataBean = adapter.get(firstVisibleStickyHeaderPosition + 1);
+ if (dataBean != null && dataBean.shouldSticky())
firstVisibleStickyHeaderPosition++;
View firstVisibleStickyHeader = layoutManager.findViewByPosition(firstVisibleStickyHeaderPosition);
if (firstVisibleStickyHeader == null)
@@ -102,20 +103,20 @@ public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (headerTop > 0 && headerTop <= mHeaderHeight) { //吸顶正在更替的状态
mHeaderContainer.setY(-(mHeaderHeight - headerTop));
if (firstVisibleStickyHeaderPosition == currentStickyHeaderPosition) {
- stickyHeaderPositionStack.pop();
- if (!stickyHeaderPositionStack.isEmpty())
- updateHeaderView(stickyHeaderPositionStack.peek());
+ stickyHeaderStack.pop();
+ if (!stickyHeaderStack.isEmpty())
+ updateHeaderView(stickyHeaderStack.peek());
}
} else if (headerTop <= 0) { //吸顶稳定在最上方的状态
mHeaderContainer.setY(0);
- updateHeaderView(firstVisibleItemPosition);
+ updateHeaderView(adapter.get(firstVisibleItemPosition));
}
// Cache the StickyHeader position.
if (firstVisibleStickyHeaderPosition > currentStickyHeaderPosition)
- stickyHeaderPositionStack.push(firstVisibleStickyHeaderPosition);
+ stickyHeaderStack.push(adapter.get(firstVisibleStickyHeaderPosition));
else if (firstVisibleStickyHeaderPosition < currentStickyHeaderPosition)
- stickyHeaderPositionStack.pop();
+ stickyHeaderStack.pop();
}
}
@@ -123,18 +124,17 @@ else if (firstVisibleStickyHeaderPosition < currentStickyHeaderPosition)
}
- private int findFirstVisibleStickyHeaderPosition(List displayList, int firstVisibleItemPosition) {
+ private int findFirstVisibleStickyHeaderPosition(int firstVisibleItemPosition) {
int i = firstVisibleItemPosition;
- for (; i < displayList.size(); i++) {
- if (!displayList.get(i).shouldSticky())
+ for (; i < adapter.getDisplayListSize(); i++) {
+ if (!adapter.get(i).shouldSticky())
continue;
break;
}
return i;
}
- private void updateHeaderView(int position) {
- DataBean entity = adapter.getDisplayList().get(position);
+ private void updateHeaderView(DataBean entity) {
int layoutId = entity.getItemLayoutId(adapter);
clearHeaderView();
RecyclerView.ViewHolder viewHolder = mViewHolderCache.get(layoutId);
@@ -147,9 +147,10 @@ private void updateHeaderView(int position) {
}
mHeaderContainer.addView(viewHolder.itemView);
mHeaderHeight = mHeaderContainer.getHeight();
- headerViewBinder.bindView(adapter, viewHolder, position, entity);
+ headerViewBinder.bindView(adapter, viewHolder, adapter.getPosition(entity), entity);
}
+ // Remove the Header View
private void clearHeaderView() {
mHeaderContainer.removeAllViews();
}
@@ -160,4 +161,19 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
super.onLayout(changed, left, top, right, bottom);
}
+ @Override
+ public void onClearAll() {
+ stickyHeaderStack.clear();
+ clearHeaderView();
+ }
+
+ @Override
+ public void remove(int pos) {
+ DataBean entity = adapter.get(pos);
+ if (stickyHeaderStack.peek() == entity)
+ clearHeaderView();
+ if (entity != null && entity.shouldSticky()) {
+ stickyHeaderStack.remove(entity);
+ }
+ }
}
diff --git a/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/adapter/StickyHeaderViewAdapter.java b/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/adapter/StickyHeaderViewAdapter.java
index 7deee2b..982dadf 100644
--- a/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/adapter/StickyHeaderViewAdapter.java
+++ b/stickyheaderview-rv/src/main/java/tellh/com/stickyheaderview_rv/adapter/StickyHeaderViewAdapter.java
@@ -8,13 +8,13 @@
import android.view.ViewGroup;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
public class StickyHeaderViewAdapter extends RecyclerView.Adapter {
private static int SIZE_VIEW_BINDER_POOL = 10;
private SparseArrayCompat viewBinderPool;
protected List displayList;
+ private DataSetChangeListener onDataSetChangeListener;
public StickyHeaderViewAdapter(List extends DataBean> displayList) {
viewBinderPool = new SparseArrayCompat<>(SIZE_VIEW_BINDER_POOL);
@@ -23,10 +23,24 @@ public StickyHeaderViewAdapter(List extends DataBean> displayList) {
this.displayList.addAll(displayList);
}
- public List getDisplayList() {
+ private List getDisplayList() {
return displayList;
}
+ public int getDisplayListSize() {
+ return displayList == null ? 0 : displayList.size();
+ }
+
+ public DataBean get(int i) {
+ if (i < getDisplayListSize())
+ return displayList.get(i);
+ else return null;
+ }
+
+ public int getPosition(DataBean dataBean) {
+ return displayList.indexOf(dataBean);
+ }
+
@Override
public int getItemViewType(int position) {
return displayList.get(position).getItemLayoutId(this);
@@ -69,37 +83,35 @@ public void clearViewBinderCache() {
viewBinderPool.clear();
}
- public void addAll(List extends DataBean> list) {
+ public void append(List extends DataBean> list) {
if (list == null)
return;
displayList.addAll(list);
notifyDataSetChanged();
}
+ public void append(DataBean dataBean) {
+ displayList.add(dataBean);
+ notifyItemInserted(displayList.size() - 1);
+ }
+
public void refresh(List extends DataBean> list) {
if (list == null)
return;
+ onDataSetChangeListener.onClearAll();
displayList.clear();
displayList.addAll(list);
notifyDataSetChanged();
}
- public void add(int pos, DataBean item) {
- displayList.add(pos, item);
- notifyItemInserted(pos);
- }
-
public void delete(int pos) {
+ onDataSetChangeListener.remove(pos);
displayList.remove(pos);
notifyItemRemoved(pos);
}
- public void swap(int fromPosition, int toPosition) {
- Collections.swap(displayList, fromPosition, toPosition);
- notifyItemMoved(fromPosition, toPosition);
- }
-
public void clear(RecyclerView recyclerView) {
+ onDataSetChangeListener.onClearAll();
displayList.clear();
notifyDataSetChanged();
recyclerView.scrollToPosition(0);
@@ -109,4 +121,15 @@ public StickyHeaderViewAdapter RegisterItemType(ViewBinder viewBinder) {
viewBinderPool.put(viewBinder.getItemLayoutId(this), viewBinder);
return this;
}
+
+ // Don't Call this Method
+ public void setDataSetChangeListener(DataSetChangeListener listener) {
+ this.onDataSetChangeListener = listener;
+ }
+
+ public interface DataSetChangeListener {
+ void onClearAll();
+
+ void remove(int pos);
+ }
}