From 7722215cefc520cd0bd30b94fb20a08364374e8b Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 18:32:20 +0100 Subject: [PATCH 01/13] * use latest MaterialDrawer snapshot --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index b97e7d388..f0ec17090 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -52,7 +52,7 @@ dependencies { //used to generate the drawer on the left //https://github.com/mikepenz/MaterialDrawer - compile('com.mikepenz:materialdrawer:4.6.3@aar') { + compile('com.mikepenz:materialdrawer:5.0.0.fastAdapter.b6-SNAPSHOT@aar') { transitive = true exclude module: "fastadapter" } From fb84fb9178afe0d576902b396e50fade582e8f92 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 19:07:53 +0100 Subject: [PATCH 02/13] * showcase compatiblity with MaterialScrollBar (added to SimpleActivity) --- app/build.gradle | 4 ++ .../fastadapter/app/IconGridActivity.java | 1 + .../fastadapter/app/SimpleActivity.java | 21 ++++++- .../adapter/FastScrollIndicatorAdapter.java | 63 +++++++++++++++++++ app/src/main/res/layout/activity_sample.xml | 4 +- 5 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/mikepenz/fastadapter/app/adapter/FastScrollIndicatorAdapter.java diff --git a/app/build.gradle b/app/build.gradle index f0ec17090..c20173c76 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,6 +77,10 @@ dependencies { //customized version to allow minimal header animation compile 'com.mikepenz.thirdparty:stickyheadersrecyclerview:0.4.4-SNAPSHOT@aar' + //Used to provide the FastScrollBar + //https://github.com/krimin-killr21/MaterialScrollBar + compile 'com.turingtechnologies.materialscrollbar:lib:6.1.0' + //https://github.com/JakeWharton/butterknife compile 'com.jakewharton:butterknife:7.0.1' diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java index 490629392..c72ead6e3 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java @@ -118,6 +118,7 @@ public boolean onClick(View v, IAdapter adapter, IItem item, int position) { //get our recyclerView and do basic setup RecyclerView rv = (RecyclerView) findViewById(R.id.rv); + //init our gridLayoutManager and configure RV GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3); gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java index 6cf2ff8ae..02c08f541 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java @@ -2,6 +2,7 @@ import android.os.Bundle; import android.support.design.widget.Snackbar; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; @@ -16,14 +17,20 @@ import com.mikepenz.fastadapter.IAdapter; import com.mikepenz.fastadapter.IItem; import com.mikepenz.fastadapter.adapters.ItemAdapter; +import com.mikepenz.fastadapter.app.adapter.FastScrollIndicatorAdapter; import com.mikepenz.fastadapter.app.items.SampleItem; import com.mikepenz.fastadapter.helpers.UndoHelper; import com.mikepenz.materialize.MaterializeBuilder; +import com.turingtechnologies.materialscrollbar.AlphabetIndicator; +import com.turingtechnologies.materialscrollbar.MaterialScrollBar; import java.util.ArrayList; import java.util.List; +import java.util.Random; public class SimpleActivity extends AppCompatActivity { + private static final String[] ALPHABET = new String[]{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; + //save our FastAdapter private FastAdapter fastAdapter; @@ -47,6 +54,7 @@ protected void onCreate(Bundle savedInstanceState) { //create our ItemAdapter which will host our items final ItemAdapter itemAdapter = new ItemAdapter<>(); + final FastScrollIndicatorAdapter fastScrollIndicatorAdapter = new FastScrollIndicatorAdapter(); // undoHelper = new UndoHelper(itemAdapter, new UndoHelper.UndoListener() { @@ -79,12 +87,19 @@ public boolean onLongClick(View v, IAdapter adapter, IItem item, int position) { RecyclerView rv = (RecyclerView) findViewById(R.id.rv); rv.setLayoutManager(new LinearLayoutManager(this)); rv.setItemAnimator(new DefaultItemAnimator()); - rv.setAdapter(itemAdapter.wrap(fastAdapter)); + rv.setAdapter(fastScrollIndicatorAdapter.wrap(itemAdapter.wrap(fastAdapter))); + + //add a FastScrollBar (Showcase compatiblity) + MaterialScrollBar materialScrollBar = new MaterialScrollBar(this, rv, true); + materialScrollBar.setHandleColour(ContextCompat.getColor(this, R.color.accent)).setAutoHide(false); + materialScrollBar.addIndicator(new AlphabetIndicator(this), true); //fill with some sample data List items = new ArrayList<>(); - for (int i = 1; i <= 100; i++) { - items.add(new SampleItem().withName("Test " + i).withIdentifier(100 + i)); + for (String s : ALPHABET) { + for (int i = 1; i <= new Random().nextInt(100); i++) { + items.add(new SampleItem().withName(s + " Test " + i).withIdentifier(100 + i)); + } } itemAdapter.add(items); diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/adapter/FastScrollIndicatorAdapter.java b/app/src/main/java/com/mikepenz/fastadapter/app/adapter/FastScrollIndicatorAdapter.java new file mode 100644 index 000000000..13cd53a14 --- /dev/null +++ b/app/src/main/java/com/mikepenz/fastadapter/app/adapter/FastScrollIndicatorAdapter.java @@ -0,0 +1,63 @@ +package com.mikepenz.fastadapter.app.adapter; + +import com.mikepenz.fastadapter.AbstractAdapter; +import com.mikepenz.fastadapter.IItem; +import com.mikepenz.fastadapter.app.items.SampleItem; +import com.turingtechnologies.materialscrollbar.INameableAdapter; + +import java.util.List; + +/** + * Created by mikepenz on 30.12.15. + * This is a FastAdapter adapter implementation for the awesome Sticky-Headers lib by timehop + * https://github.com/timehop/sticky-headers-recyclerview + */ +public class FastScrollIndicatorAdapter extends AbstractAdapter implements INameableAdapter { + @Override + public Character getCharacterForElement(int position) { + IItem item = getItem(position); + if (item instanceof SampleItem && ((SampleItem) item).name != null) { + //based on the position we set the headers text + return ((SampleItem) item).name.getText().charAt(0); + } + return ' '; + } + + /** + * REQUIRED FOR THE FastAdapter. Set order to < 0 to tell the FastAdapter he can ignore this one. + **/ + + /** + * @return + */ + @Override + public int getOrder() { + return -100; + } + + @Override + public int getAdapterItemCount() { + return 0; + } + + @Override + public List getAdapterItems() { + return null; + } + + @Override + public Item getAdapterItem(int position) { + return null; + } + + @Override + public int getAdapterPosition(IItem item) { + return -1; + } + + @Override + public int getGlobalPosition(int position) { + return -1; + } + +} diff --git a/app/src/main/res/layout/activity_sample.xml b/app/src/main/res/layout/activity_sample.xml index 6246d255f..dfe3aa4f3 100755 --- a/app/src/main/res/layout/activity_sample.xml +++ b/app/src/main/res/layout/activity_sample.xml @@ -13,7 +13,7 @@ android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" /> - - + \ No newline at end of file From 2983df81fac479005c309807c251f39747fd8617 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 19:11:15 +0100 Subject: [PATCH 03/13] * expand a item to make example look a bit more interesting --- .../java/com/mikepenz/fastadapter/app/IconGridActivity.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java index c72ead6e3..33fee796b 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java @@ -165,6 +165,9 @@ public int compare(final ITypeface object1, final ITypeface object2) { //fill with some sample data itemAdapter.add(items); + //expand one item to make sample look a bit more interesting + fastAdapter.expand(2); + //restore selections (this has to be done after the items were added fastAdapter.withSavedInstanceState(savedInstanceState); } From 250184f03e1a173f05073314889aef21b31b2369 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 20:38:19 +0100 Subject: [PATCH 04/13] * remove obsolete code --- .../java/com/mikepenz/fastadapter/app/IconGridActivity.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java index 33fee796b..d68492db0 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java @@ -148,7 +148,6 @@ public int compare(final ITypeface object1, final ITypeface object2) { //add all icons of all registered Fonts to the list ArrayList items = new ArrayList<>(Iconics.getRegisteredFonts(this).size()); - int count = 0; for (ITypeface font : mFonts) { SampleItem sampleItem = new SampleItem().withName(font.getFontName()); @@ -159,7 +158,6 @@ public int compare(final ITypeface object1, final ITypeface object2) { sampleItem.withSubItems(icons); items.add(sampleItem); - count++; } //fill with some sample data From 161b9ecdbf4f40ef5f514f1abc1e1de30bbfac05 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 20:39:18 +0100 Subject: [PATCH 05/13] * add some more types so everythign through the FastAdapter is typed (if type is provided) --- .../com/mikepenz/fastadapter/FastAdapter.java | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java index 3cc7476c1..bdbbcf07c 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java @@ -27,7 +27,7 @@ public class FastAdapter extends RecyclerView.Adapter mAdapters = new ArrayMap<>(); + private ArrayMap> mAdapters = new ArrayMap<>(); // we remember all possible types so we can create a new view efficiently private ArrayMap mTypeInstances = new ArrayMap<>(); @@ -59,7 +59,7 @@ public FastAdapter() { * @param mOnClickListener the OnClickListener which will be used for a single item * @return this */ - public FastAdapter withOnClickListener(OnClickListener mOnClickListener) { + public FastAdapter withOnClickListener(OnClickListener mOnClickListener) { this.mOnClickListener = mOnClickListener; return this; } @@ -70,7 +70,7 @@ public FastAdapter withOnClickListener(OnClickListener mOnClickListener) { * @param mOnLongClickListener the OnLongClickListener which will be used for a single item * @return this */ - public FastAdapter withOnLongClickListener(OnLongClickListener mOnLongClickListener) { + public FastAdapter withOnLongClickListener(OnLongClickListener mOnLongClickListener) { this.mOnLongClickListener = mOnLongClickListener; return this; } @@ -81,7 +81,7 @@ public FastAdapter withOnLongClickListener(OnLongClickListener mOnLongClickListe * @param mOnTouchListener the TouchListener which will be used for a single item * @return this */ - public FastAdapter withOnTouchListener(OnTouchListener mOnTouchListener) { + public FastAdapter withOnTouchListener(OnTouchListener mOnTouchListener) { this.mOnTouchListener = mOnTouchListener; return this; } @@ -92,7 +92,7 @@ public FastAdapter withOnTouchListener(OnTouchListener mOnTouchListener) { * @param multiSelect true to enable multiSelect * @return this */ - public FastAdapter withMultiSelect(boolean multiSelect) { + public FastAdapter withMultiSelect(boolean multiSelect) { mMultiSelect = multiSelect; return this; } @@ -103,7 +103,7 @@ public FastAdapter withMultiSelect(boolean multiSelect) { * @param multiSelectOnLongClick false to do multiSelect via single click * @return this */ - public FastAdapter withMultiSelectOnLongClick(boolean multiSelectOnLongClick) { + public FastAdapter withMultiSelectOnLongClick(boolean multiSelectOnLongClick) { mMultiSelectOnLongClick = multiSelectOnLongClick; return this; } @@ -115,7 +115,7 @@ public FastAdapter withMultiSelectOnLongClick(boolean multiSelectOnLongClick) { * @param savedInstanceState * @return */ - public FastAdapter withSavedInstanceState(Bundle savedInstanceState) { + public FastAdapter withSavedInstanceState(Bundle savedInstanceState) { return withSavedInstanceState(savedInstanceState, ""); } @@ -127,7 +127,7 @@ public FastAdapter withSavedInstanceState(Bundle savedInstanceState) { * @param prefix a prefix added to the savedInstance key so we can store multiple states * @return */ - public FastAdapter withSavedInstanceState(Bundle savedInstanceState, String prefix) { + public FastAdapter withSavedInstanceState(Bundle savedInstanceState, String prefix) { if (savedInstanceState != null) { //make sure already done selections are removed deselect(); @@ -282,7 +282,7 @@ public int getPosition(Item item) { int position = 0; int length = mAdapters.size(); for (int i = 0; i < length; i++) { - IAdapter adapter = mAdapters.valueAt(i); + IAdapter adapter = mAdapters.valueAt(i); if (adapter.getOrder() < 0) { continue; } @@ -320,9 +320,9 @@ public RelativeInfo getRelativeInfo(int position) { } RelativeInfo relativeInfo = new RelativeInfo<>(); - IAdapter adapter = getAdapter(position); + IAdapter adapter = getAdapter(position); if (adapter != null) { - relativeInfo.item = (Item) adapter.getAdapterItem(position - getItemCount(adapter.getOrder())); + relativeInfo.item = adapter.getAdapterItem(position - getItemCount(adapter.getOrder())); relativeInfo.adapter = adapter; } return relativeInfo; @@ -334,11 +334,11 @@ public RelativeInfo getRelativeInfo(int position) { * @param position the global position * @return the adapter responsible for this global position */ - public IAdapter getAdapter(int position) { + public IAdapter getAdapter(int position) { int currentCount = 0; int length = mAdapters.size(); for (int i = 0; i < length; i++) { - IAdapter adapter = mAdapters.valueAt(i); + IAdapter adapter = mAdapters.valueAt(i); if (adapter.getOrder() < 0) { continue; } @@ -739,13 +739,13 @@ private void internalCollapse(IExpandable expandable, int position) { public void expand(int position) { Item item = getItem(position); if (item != null && item instanceof IExpandable) { - IExpandable expandable = (IExpandable) item; + IExpandable expandable = (IExpandable) item; //if this item is not already callapsed and has sub items we go on if (!expandable.isExpanded() && expandable.getSubItems() != null && expandable.getSubItems().size() > 0) { - IAdapter adapter = getAdapter(position); + IAdapter adapter = getAdapter(position); if (adapter != null && adapter instanceof IItemAdapter) { - ((IItemAdapter) adapter).add(position + 1, expandable.getSubItems()); + ((IItemAdapter) adapter).add(position + 1, expandable.getSubItems()); } //remember that this item is now opened (not collapsed) @@ -901,7 +901,7 @@ public void notifyAdapterItemRangeChanged(int position, int itemCount, Object pa } //listeners - public interface OnTouchListener { + public interface OnTouchListener { /** * the onTouch event of a specific item inside the RecyclerView * @@ -912,10 +912,10 @@ public interface OnTouchListener { * @param position the global position * @return return true if the event was consumed, otherwise false */ - boolean onTouch(View v, MotionEvent event, IAdapter adapter, IItem item, int position); + boolean onTouch(View v, MotionEvent event, IAdapter adapter, IItem item, int position); } - public interface OnClickListener { + public interface OnClickListener { /** * the onClick event of a specific item inside the RecyclerView * @@ -925,10 +925,10 @@ public interface OnClickListener { * @param position the global position * @return return true if the event was consumed, otherwise false */ - boolean onClick(View v, IAdapter adapter, IItem item, int position); + boolean onClick(View v, IAdapter adapter, IItem item, int position); } - public interface OnLongClickListener { + public interface OnLongClickListener { /** * the onLongClick event of a specific item inside the RecyclerView * @@ -938,14 +938,14 @@ public interface OnLongClickListener { * @param position the global position * @return return true if the event was consumed, otherwise false */ - boolean onLongClick(View v, IAdapter adapter, IItem item, int position); + boolean onLongClick(View v, IAdapter adapter, IItem item, int position); } /** * an internal class to return the IItem and relativePosition and it's adapter at once. used to save one iteration inside the getInternalItem method */ - public static class RelativeInfo { - public IAdapter adapter = null; + public static class RelativeInfo { + public IAdapter adapter = null; public Item item = null; } } From 7c9c2b9d0e5267c583db53c5a6fa6df75d8be60f Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 20:58:52 +0100 Subject: [PATCH 06/13] * also type click listeners so they will return the type of the adapter else IItem * document all remaining methods / properties --- .../com/mikepenz/fastadapter/FastAdapter.java | 92 +++++++++++-------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java index bdbbcf07c..e44f89ccb 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java @@ -42,9 +42,9 @@ public class FastAdapter extends RecyclerView.Adapter mOnClickListener; + private OnLongClickListener mOnLongClickListener; + private OnTouchListener mOnTouchListener; /** * default CTOR @@ -59,7 +59,7 @@ public FastAdapter() { * @param mOnClickListener the OnClickListener which will be used for a single item * @return this */ - public FastAdapter withOnClickListener(OnClickListener mOnClickListener) { + public FastAdapter withOnClickListener(OnClickListener mOnClickListener) { this.mOnClickListener = mOnClickListener; return this; } @@ -70,7 +70,7 @@ public FastAdapter withOnClickListener(OnClickListener mOnClickListener) { * @param mOnLongClickListener the OnLongClickListener which will be used for a single item * @return this */ - public FastAdapter withOnLongClickListener(OnLongClickListener mOnLongClickListener) { + public FastAdapter withOnLongClickListener(OnLongClickListener mOnLongClickListener) { this.mOnLongClickListener = mOnLongClickListener; return this; } @@ -81,11 +81,24 @@ public FastAdapter withOnLongClickListener(OnLongClickListener mOnLongClic * @param mOnTouchListener the TouchListener which will be used for a single item * @return this */ - public FastAdapter withOnTouchListener(OnTouchListener mOnTouchListener) { + public FastAdapter withOnTouchListener(OnTouchListener mOnTouchListener) { this.mOnTouchListener = mOnTouchListener; return this; } + /** + * if enabled we will select the item via a notifyItemChanged -> will animate with the Animator + * you can also use this if you have any custom logic for selections, and do not depend on the "selected" state of the view + * note if enabled it will feel a bit slower because it will animate the selection + * + * @param selectWithItemUpdate true if notifyItemChanged should be called upon select + * @return this + */ + public FastAdapter withSelectWithItemUpdate(boolean selectWithItemUpdate) { + this.mSelectWithItemUpdate = selectWithItemUpdate; + return this; + } + /** * Enable this if you want multiSelection possible in the list * @@ -112,8 +125,10 @@ public FastAdapter withMultiSelectOnLongClick(boolean multiSelectOnLongCli * re-selects all elements stored in the savedInstanceState * IMPORTANT! Call this method only after all items where added to the adapters again. Otherwise it may select wrong items! * - * @param savedInstanceState - * @return + * @param savedInstanceState If the activity is being re-initialized after + * previously being shut down then this Bundle contains the data it most + * recently supplied in Note: Otherwise it is null. + * @return this */ public FastAdapter withSavedInstanceState(Bundle savedInstanceState) { return withSavedInstanceState(savedInstanceState, ""); @@ -123,9 +138,11 @@ public FastAdapter withSavedInstanceState(Bundle savedInstanceState) { * re-selects all elements stored in the savedInstanceState * IMPORTANT! Call this method only after all items where added to the adapters again. Otherwise it may select wrong items! * - * @param savedInstanceState + * @param savedInstanceState If the activity is being re-initialized after + * previously being shut down then this Bundle contains the data it most + * recently supplied in Note: Otherwise it is null. * @param prefix a prefix added to the savedInstance key so we can store multiple states - * @return + * @return this */ public FastAdapter withSavedInstanceState(Bundle savedInstanceState, String prefix) { if (savedInstanceState != null) { @@ -165,10 +182,9 @@ public FastAdapter wrap(AbstractAdapter abstractAdapter) { /** * registers an AbstractAdapter which will be hooked into the adapter chain * - * @param adapter - * @param an adapter which extends the AbstractAdapter + * @param adapter an adapter which extends the AbstractAdapter */ - public void registerAdapter(A adapter) { + public > void registerAdapter(A adapter) { if (!mAdapters.containsKey(adapter.getOrder())) { mAdapters.put(adapter.getOrder(), adapter); } @@ -188,9 +204,9 @@ public void registerTypeInstance(Item item) { /** * Creates the ViewHolder by the viewType * - * @param parent - * @param viewType - * @return + * @param parent the parent view (the RecyclerView) + * @param viewType the current viewType which is bound + * @return the ViewHolder with the bound data */ @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @@ -259,7 +275,7 @@ public boolean onTouch(View v, MotionEvent event) { /** * Binds the data to the created ViewHolder and sets the listeners to the holder.itemView * - * @param holder + * @param holder the viewHolder we bind the data on * @param position the global position */ @Override @@ -355,7 +371,7 @@ public IAdapter getAdapter(int position) { * finds the int ItemViewType from the IItem which exists at the given position * * @param position the global position - * @return + * @return the viewType for this position */ @Override public int getItemViewType(int position) { @@ -366,7 +382,7 @@ public int getItemViewType(int position) { * finds the int ItemId from the IItem which exists at the given position * * @param position the global position - * @return + * @return the itemId for this position */ @Override public long getItemId(int position) { @@ -423,8 +439,10 @@ public int getItemCount(int order) { /** * add the values to the bundle for saveInstanceState * - * @param savedInstanceState - * @return + * @param savedInstanceState If the activity is being re-initialized after + * previously being shut down then this Bundle contains the data it most + * recently supplied in Note: Otherwise it is null. + * @return the passed bundle with the newly added data */ public Bundle saveInstanceState(Bundle savedInstanceState) { return saveInstanceState(savedInstanceState, ""); @@ -433,9 +451,11 @@ public Bundle saveInstanceState(Bundle savedInstanceState) { /** * add the values to the bundle for saveInstanceState * - * @param savedInstanceState + * @param savedInstanceState If the activity is being re-initialized after + * previously being shut down then this Bundle contains the data it most + * recently supplied in Note: Otherwise it is null. * @param prefix a prefix added to the savedInstance key so we can store multiple states - * @return + * @return the passed bundle with the newly added data */ public Bundle saveInstanceState(Bundle savedInstanceState, String prefix) { if (savedInstanceState != null) { @@ -778,7 +798,7 @@ public void notifyAdapterItemInserted(int position) { * wraps notifyItemRangeInserted * * @param position the global position - * @param itemCount + * @param itemCount the count of items inserted */ public void notifyAdapterItemRangeInserted(int position, int itemCount) { //we have to update all current stored selection and expandable states in our map @@ -803,7 +823,7 @@ public void notifyAdapterItemRemoved(int position) { * wraps notifyItemRangeRemoved * * @param position the global position - * @param itemCount + * @param itemCount the count of items removed */ public void notifyAdapterItemRangeRemoved(int position, int itemCount) { //we have to update all current stored selection and expandable states in our map @@ -849,7 +869,7 @@ public void notifyAdapterItemChanged(int position) { * wraps notifyItemChanged * * @param position the global position - * @param payload + * @param payload additional payload */ public void notifyAdapterItemChanged(int position, Object payload) { Item updateItem = getItem(position); @@ -870,7 +890,7 @@ public void notifyAdapterItemChanged(int position, Object payload) { * wraps notifyItemRangeChanged * * @param position the global position - * @param itemCount + * @param itemCount the count of items changed */ public void notifyAdapterItemRangeChanged(int position, int itemCount) { notifyAdapterItemRangeChanged(position, itemCount, null); @@ -880,8 +900,8 @@ public void notifyAdapterItemRangeChanged(int position, int itemCount) { * wraps notifyItemRangeChanged * * @param position the global position - * @param itemCount - * @param payload + * @param itemCount the count of items changed + * @param payload an additional payload */ public void notifyAdapterItemRangeChanged(int position, int itemCount, Object payload) { for (int i = position; i < position + itemCount; i++) { @@ -905,40 +925,40 @@ public interface OnTouchListener { /** * the onTouch event of a specific item inside the RecyclerView * - * @param v - * @param event + * @param v the view we clicked + * @param event the touch event * @param adapter the adapter which is responsible for the given item * @param item the IItem which was clicked * @param position the global position * @return return true if the event was consumed, otherwise false */ - boolean onTouch(View v, MotionEvent event, IAdapter adapter, IItem item, int position); + boolean onTouch(View v, MotionEvent event, IAdapter adapter, Item item, int position); } public interface OnClickListener { /** * the onClick event of a specific item inside the RecyclerView * - * @param v + * @param v the view we clicked * @param adapter the adapter which is responsible for the given item * @param item the IItem which was clicked * @param position the global position * @return return true if the event was consumed, otherwise false */ - boolean onClick(View v, IAdapter adapter, IItem item, int position); + boolean onClick(View v, IAdapter adapter, Item item, int position); } public interface OnLongClickListener { /** * the onLongClick event of a specific item inside the RecyclerView * - * @param v + * @param v the view we clicked * @param adapter the adapter which is responsible for the given item * @param item the IItem which was clicked * @param position the global position * @return return true if the event was consumed, otherwise false */ - boolean onLongClick(View v, IAdapter adapter, IItem item, int position); + boolean onLongClick(View v, IAdapter adapter, Item item, int position); } /** From 2b75948170f84a158351c6b0b0d340c0ce1a9dca Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 20:59:19 +0100 Subject: [PATCH 07/13] * type everything within the SimpleActivity to be typesafe --- .../com/mikepenz/fastadapter/app/SimpleActivity.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java index 02c08f541..e97f6451b 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/SimpleActivity.java @@ -54,7 +54,7 @@ protected void onCreate(Bundle savedInstanceState) { //create our ItemAdapter which will host our items final ItemAdapter itemAdapter = new ItemAdapter<>(); - final FastScrollIndicatorAdapter fastScrollIndicatorAdapter = new FastScrollIndicatorAdapter(); + final FastScrollIndicatorAdapter fastScrollIndicatorAdapter = new FastScrollIndicatorAdapter<>(); // undoHelper = new UndoHelper(itemAdapter, new UndoHelper.UndoListener() { @@ -68,16 +68,16 @@ public void commitRemove(int position, ArrayList removed) { //configure our fastAdapter //as we provide id's for the items we want the hasStableIds enabled to speed up things fastAdapter.setHasStableIds(true); - fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() { + fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() { @Override - public boolean onClick(View v, IAdapter adapter, IItem item, int position) { - Toast.makeText(v.getContext(), ((SampleItem) item).name.getText(v.getContext()), Toast.LENGTH_LONG).show(); + public boolean onClick(View v, IAdapter adapter, SampleItem item, int position) { + Toast.makeText(v.getContext(), (item).name.getText(v.getContext()), Toast.LENGTH_LONG).show(); return false; } }); - fastAdapter.withOnLongClickListener(new FastAdapter.OnLongClickListener() { + fastAdapter.withOnLongClickListener(new FastAdapter.OnLongClickListener() { @Override - public boolean onLongClick(View v, IAdapter adapter, IItem item, int position) { + public boolean onLongClick(View v, IAdapter adapter, SampleItem item, int position) { undoHelper.remove(SimpleActivity.this.findViewById(android.R.id.content), "Item removed", "Undo", Snackbar.LENGTH_LONG, position, 1); return true; } From 64c44d0c30d977cbb34d25afbbaee6fbd2d9b28e Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 20:59:35 +0100 Subject: [PATCH 08/13] * add new select behavior without notifyItemChanged --- .../com/mikepenz/fastadapter/FastAdapter.java | 35 +++++++++++++------ 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java index e44f89ccb..633947838 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java @@ -31,6 +31,10 @@ public class FastAdapter extends RecyclerView.Adapter mTypeInstances = new ArrayMap<>(); + // if enabled we will select the item via a notifyItemChanged -> will animate with the Animator + // you can also use this if you have any custom logic for selections, and do not depend on the "selected" state of the view + // note if enabled it will feel a bit slower because it will animate the selection + private boolean mSelectWithItemUpdate = false; // if we want multiSelect enabled private boolean mMultiSelect = false; // if we want the multiSelect only on longClick @@ -226,7 +230,7 @@ public void onClick(View v) { } if (!consumed && (!(mMultiSelect && mMultiSelectOnLongClick) || !mMultiSelect)) { - handleSelection(relativeInfo.item, pos); + handleSelection(v, relativeInfo.item, pos); } } } @@ -246,7 +250,7 @@ public boolean onLongClick(View v) { } if (!consumed && (mMultiSelect && mMultiSelectOnLongClick)) { - handleSelection(relativeInfo.item, pos); + handleSelection(v, relativeInfo.item, pos); } } return consumed; @@ -516,21 +520,32 @@ public void toggleSelection(int position) { * * @param position the global position */ - private void handleSelection(Item item, int position) { + private void handleSelection(View view, Item item, int position) { if (!item.isSelectable()) { return; } - if (mSelections.contains(position)) { - if (!mMultiSelect) { - deselect(); + boolean selected = mSelections.contains(position); + if (!mMultiSelect) { + deselect(); + } + + if (mSelectWithItemUpdate || view == null) { + if (selected) { + deselect(position); + } else { + select(position); } - deselect(position); } else { - if (!mMultiSelect) { - deselect(); + item.withSetSelected(!selected); + view.setSelected(!selected); + if (selected) { + if (mSelections.contains(position)) { + mSelections.remove(position); + } + } else { + mSelections.add(position); } - select(position); } } From bab1f9eea9c19330c83f04636f618114fd2bbbec Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 21:07:51 +0100 Subject: [PATCH 09/13] * improve selection behavior. there are now 2 different variants of selection. you can toggle this via `withSelectWithItemUpdate` (where false == default -> variant 1) 1.) direct selection via the view "selected" state, we also make sure we do not animate here so no notifyItemChanged is called if we repeatly press the same item 2.) we select the items via a notifyItemChanged. -> this will allow custom selected logics within your views (isSelected() --> do something...) and it will also animate the change via the provided itemAnimator. because of the animation of the itemAnimator the selection will have a small delay (time of animating) --- .../com/mikepenz/fastadapter/FastAdapter.java | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java index 633947838..310381775 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java @@ -526,19 +526,31 @@ private void handleSelection(View view, Item item, int position) { } boolean selected = mSelections.contains(position); - if (!mMultiSelect) { - deselect(); - } - if (mSelectWithItemUpdate || view == null) { + if (!mMultiSelect) { + deselect(); + } if (selected) { deselect(position); } else { select(position); } } else { + //we have to separately handle deselection here because if we toggle the current item we do not want to deselect this first! + Iterator entries = mSelections.iterator(); + while (entries.hasNext()) { + //deselect all but the current one! this is important! + Integer pos = entries.next(); + if (pos != position) { + deselect(pos, entries); + } + } + + //we toggle the state of the view item.withSetSelected(!selected); view.setSelected(!selected); + + //now we make sure we remember the selection! if (selected) { if (mSelections.contains(position)) { mSelections.remove(position); @@ -588,6 +600,13 @@ public void select(int position, boolean fireEvent) { } } + /** + * deselects all selections + */ + public void deselect() { + deselect(mSelections); + } + /** * deselects all items at the positions in the iteratable * @@ -631,13 +650,6 @@ private void deselect(int position, Iterator entries) { notifyItemChanged(position); } - /** - * deselects all selections - */ - public void deselect() { - deselect(mSelections); - } - /** * deletes all current selected items * From a4d5dfc477f1bfd0ea26300ff63df0a7107552c4 Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 21:09:11 +0100 Subject: [PATCH 10/13] * improve selection behavior docu --- .../main/java/com/mikepenz/fastadapter/FastAdapter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java index 310381775..e66973fdd 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java @@ -91,9 +91,10 @@ public FastAdapter withOnTouchListener(OnTouchListener mOnTouchListe } /** - * if enabled we will select the item via a notifyItemChanged -> will animate with the Animator - * you can also use this if you have any custom logic for selections, and do not depend on the "selected" state of the view - * note if enabled it will feel a bit slower because it will animate the selection + * select between the different selection behaviors. + * there are now 2 different variants of selection. you can toggle this via `withSelectWithItemUpdate(boolean)` (where false == default --> variant 1) + * 1.) direct selection via the view "selected" state, we also make sure we do not animate here so no notifyItemChanged is called if we repeatly press the same item + * 2.) we select the items via a notifyItemChanged. -> this will allow custom selected logics within your views (isSelected() --> do something...) and it will also animate the change via the provided itemAnimator. because of the animation of the itemAnimator the selection will have a small delay (time of animating) * * @param selectWithItemUpdate true if notifyItemChanged should be called upon select * @return this From 8835f19b96720f04077d3eeec29a9e50558d7d6d Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 21:14:27 +0100 Subject: [PATCH 11/13] * type click listeners in 2 samples --- .../mikepenz/fastadapter/app/IconGridActivity.java | 12 +++++------- .../mikepenz/fastadapter/app/ImageListActivity.java | 8 +++----- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java index d68492db0..d5bf036f9 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java @@ -99,14 +99,12 @@ public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { //create our FastAdapter which will manage everything fastAdapter = new FastAdapter<>(); - fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() { + fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() { @Override - public boolean onClick(View v, IAdapter adapter, IItem item, int position) { - if (item instanceof SampleItem) { - if (((SampleItem) item).getSubItems() != null) { - fastAdapter.toggleExpandable(position); - return true; - } + public boolean onClick(View v, IAdapter adapter, SampleItem item, int position) { + if (item.getSubItems() != null) { + fastAdapter.toggleExpandable(position); + return true; } return false; } diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/ImageListActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/ImageListActivity.java index 617e32d87..04bfeb72b 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/ImageListActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/ImageListActivity.java @@ -13,11 +13,9 @@ import com.mikepenz.fastadapter.FastAdapter; import com.mikepenz.fastadapter.IAdapter; -import com.mikepenz.fastadapter.IItem; import com.mikepenz.fastadapter.adapters.ItemAdapter; import com.mikepenz.fastadapter.app.dummy.ImageDummyData; import com.mikepenz.fastadapter.app.items.ImageItem; -import com.mikepenz.fastadapter.app.items.SampleItem; import com.mikepenz.materialize.MaterializeBuilder; public class ImageListActivity extends AppCompatActivity { @@ -44,10 +42,10 @@ protected void onCreate(Bundle savedInstanceState) { final ItemAdapter itemAdapter = new ItemAdapter<>(); //configure our fastAdapter - fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() { + fastAdapter.withOnClickListener(new FastAdapter.OnClickListener() { @Override - public boolean onClick(View v, IAdapter adapter, IItem item, int position) { - Toast.makeText(v.getContext(), ((SampleItem) item).name.getText(v.getContext()), Toast.LENGTH_LONG).show(); + public boolean onClick(View v, IAdapter adapter, ImageItem item, int position) { + Toast.makeText(v.getContext(), item.mName, Toast.LENGTH_LONG).show(); return false; } }); From 6ac1b2a318da559b4bc2f1afa873fc3083e5721e Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 21:15:58 +0100 Subject: [PATCH 12/13] * if we are in multiSelection we do not have to deselect the items in the new selection mode --- .../com/mikepenz/fastadapter/FastAdapter.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java index e66973fdd..b456aa315 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java @@ -537,13 +537,15 @@ private void handleSelection(View view, Item item, int position) { select(position); } } else { - //we have to separately handle deselection here because if we toggle the current item we do not want to deselect this first! - Iterator entries = mSelections.iterator(); - while (entries.hasNext()) { - //deselect all but the current one! this is important! - Integer pos = entries.next(); - if (pos != position) { - deselect(pos, entries); + if (!mMultiSelect) { + //we have to separately handle deselection here because if we toggle the current item we do not want to deselect this first! + Iterator entries = mSelections.iterator(); + while (entries.hasNext()) { + //deselect all but the current one! this is important! + Integer pos = entries.next(); + if (pos != position) { + deselect(pos, entries); + } } } From fe0e1061927880f481314393ae63fb53e59397bb Mon Sep 17 00:00:00 2001 From: Mike Penz Date: Mon, 11 Jan 2016 21:16:35 +0100 Subject: [PATCH 13/13] * [release] v0.7.0 --- README.md | 2 +- app/build.gradle | 4 ++-- gradle.properties | 4 ++-- library/build.gradle | 4 ++-- library/src/main/res/values/library_fastadapter_strings.xml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b0fe57ae5..fcb6f79e6 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Beside being blazing fast, minimizing the code you need to write, it is also rea #Include in your project ##Using Maven ```javascript -compile('com.mikepenz:fastadapter:0.6.0@aar') { +compile('com.mikepenz:fastadapter:0.7.0@aar') { transitive = true } ``` diff --git a/app/build.gradle b/app/build.gradle index c20173c76..84a2993dd 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { defaultConfig { minSdkVersion 11 targetSdkVersion 23 - versionCode 60 - versionName '0.6.0' + versionCode 70 + versionName '0.7.0' applicationVariants.all { variant -> variant.outputs.each { output -> diff --git a/gradle.properties b/gradle.properties index 7d8e9e9e0..8b420fa04 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ org.gradle.daemon=true org.gradle.parallel=true # Maven stuff -VERSION_NAME=0.6.0 -VERSION_CODE=60 +VERSION_NAME=0.7.0 +VERSION_CODE=70 GROUP=com.mikepenz POM_DESCRIPTION=FastAdapter Library diff --git a/library/build.gradle b/library/build.gradle index e54cb5893..56efd3b25 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -8,8 +8,8 @@ android { defaultConfig { minSdkVersion 10 targetSdkVersion 23 - versionCode 60 - versionName '0.6.0' + versionCode 70 + versionName '0.7.0' } buildTypes { release { diff --git a/library/src/main/res/values/library_fastadapter_strings.xml b/library/src/main/res/values/library_fastadapter_strings.xml index b5e934907..8d2364c9c 100755 --- a/library/src/main/res/values/library_fastadapter_strings.xml +++ b/library/src/main/res/values/library_fastadapter_strings.xml @@ -10,7 +10,7 @@ FastAdapter, the bullet proof, fast and easy to use adapter library, which minimizes developing time to a fraction... ]]> - 0.6.0 + 0.7.0 https://github.com/mikepenz/FastAdapter apache_2_0 true