diff --git a/README.md b/README.md index 07c7508a8..debae880b 100644 --- a/README.md +++ b/README.md @@ -8,20 +8,36 @@ Beside being blazing fast, minimizing the code you need to write, it is also rea ##A quick overview: - Click / Long-Click listeners -- Selection / Multi-Selection +- Selection / Multi-Selection [MultiselectSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/MultiselectSampleActivity.java) + - [CheckBoxSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/CheckBoxSampleActivity.java) + - [RadioButtonSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/RadioButtonSampleActivity.java) - Expandable items + - [ExpandableSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/ExpandableSampleActivity.java) + - [IconGridSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/IconGridActivity.java) + - [AdvancedSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/AdvancedSampleActivity.java) - Write less code, get better results - Simple Drag & Drop -- Headers + - [SimpleItemListSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java) +- Headers + - [StickyHeaderSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/StickyHeaderSampleActivity.java) + - [AdvancedSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/AdvancedSampleActivity.java) - Footers - FastScroller (external lib) + - [SimpleItemListSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java) +- Filter + - [SimpleItemListSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java) - Highly optimized code - Includes suggestions from the Android Team - Easily extensible +- Split item view and model + - [GenericItem](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/GenericItemActivity.java) + - [MultiTypeGenericItem](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/MultiTypeGenericItemActivity.java) - Chain other Adapters + - [SimpleItemListSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java) + - [StickyHeaderSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/StickyHeaderSampleActivity.java) - Comes with useful Helpers - - ActionModeHelper - - UndoHelper + - ActionModeHelper [MultiselectSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/MultiselectSampleActivity.java) + - UndoHelper [MultiselectSample](https://github.com/mikepenz/FastAdapter/blob/develop/app/src/main/java/com/mikepenz/fastadapter/app/MultiselectSampleActivity.java) - More to come... #Preview @@ -33,12 +49,20 @@ You can try it out here [Google Play](https://play.google.com/store/apps/details #Include in your project ##Using Maven -```javascript -compile('com.mikepenz:fastadapter:1.0.6@aar') { + +The library is split up into core, and extensions. The core functions are included in the following dependency. +```gradle +compile('com.mikepenz:fastadapter:1.1.0@aar') { transitive = true } ``` +All additions are included in the following dependency. +```gradle +compile 'com.mikepenz:fastadapter-extensions:1.1.0@aar' +``` + + ##How to use ###1. Implement your item (the easy way) Just create a class which extends the `AbstractItem` as shown below. Implement the methods, and your item is ready. diff --git a/app/build.gradle b/app/build.gradle index 5d8ce7977..2ed34ebe8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { defaultConfig { minSdkVersion 11 targetSdkVersion 23 - versionCode 106 - versionName '1.0.6' + versionCode 110 + versionName '1.1.0' applicationVariants.all { variant -> variant.outputs.each { output -> @@ -48,10 +48,13 @@ android { dependencies { compile project(':library') + compile project(':library-extensions') + + compile "com.android.support:cardview-v7:${rootProject.ext.supportLibVersion}" //used to generate the drawer on the left //https://github.com/mikepenz/MaterialDrawer - compile('com.mikepenz:materialdrawer:5.0.0.b24-SNAPSHOT@aar') { + compile('com.mikepenz:materialdrawer:5.0.0@aar') { transitive = true exclude module: "fastadapter" } @@ -60,7 +63,7 @@ dependencies { compile 'com.mikepenz:itemanimators:0.2.1@aar' //used to generate the Open Source section //https://github.com/mikepenz/AboutLibraries - compile('com.mikepenz:aboutlibraries:5.5.0@aar') { + compile('com.mikepenz:aboutlibraries:5.5.2@aar') { transitive = true exclude module: "fastadapter" } @@ -68,7 +71,7 @@ dependencies { //https://github.com/mikepenz/Android-Iconics compile 'com.mikepenz:material-design-iconic-typeface:2.2.0.1@aar' compile 'com.mikepenz:community-material-typeface:1.3.41.1@aar' - compile 'com.mikepenz:google-material-typeface:2.1.0.1.original@aar' + compile 'com.mikepenz:google-material-typeface:2.2.0.1.original@aar' compile 'com.mikepenz:fontawesome-typeface:4.5.0.1@aar' //Used for the StickyHeaderSample @@ -79,7 +82,7 @@ dependencies { //Used to provide the FastScrollBar //https://github.com/krimin-killr21/MaterialScrollBar - compile 'com.turingtechnologies.materialscrollbar:lib:7.1.1' + compile 'com.turingtechnologies.materialscrollbar:lib:8.0.0' //https://github.com/JakeWharton/butterknife compile 'com.jakewharton:butterknife:7.0.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2b1f41d7b..f3a524066 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,9 @@ + diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/AdvancedSampleActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/AdvancedSampleActivity.java index 82d9155c3..68a552849 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/AdvancedSampleActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/AdvancedSampleActivity.java @@ -22,7 +22,7 @@ import com.mikepenz.fastadapter.app.adapter.StickyHeaderAdapter; import com.mikepenz.fastadapter.app.items.ExpandableItem; import com.mikepenz.fastadapter.app.items.SampleItem; -import com.mikepenz.fastadapter.helpers.ActionModeHelper; +import com.mikepenz.fastadapter_extensions.ActionModeHelper; import com.mikepenz.iconics.context.IconicsLayoutInflater; import com.mikepenz.materialize.MaterializeBuilder; import com.mikepenz.materialize.util.UIUtils; diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/MultiselectSampleActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/MultiselectSampleActivity.java index 23afa14fd..7714445c3 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/MultiselectSampleActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/MultiselectSampleActivity.java @@ -18,8 +18,8 @@ import com.mikepenz.fastadapter.adapters.HeaderAdapter; import com.mikepenz.fastadapter.adapters.ItemAdapter; import com.mikepenz.fastadapter.app.items.SampleItem; -import com.mikepenz.fastadapter.helpers.ActionModeHelper; -import com.mikepenz.fastadapter.helpers.UndoHelper; +import com.mikepenz.fastadapter_extensions.ActionModeHelper; +import com.mikepenz.fastadapter_extensions.UndoHelper; import com.mikepenz.itemanimators.SlideDownAlphaAnimator; import com.mikepenz.materialize.MaterializeBuilder; import com.mikepenz.materialize.util.UIUtils; diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.java index d1799a093..8bbc7038f 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.java @@ -75,6 +75,7 @@ protected void onCreate(Bundle savedInstanceState) { new PrimaryDrawerItem().withName(R.string.sample_multi_generic_item).withDescription(R.string.sample_multi_generic_item_descr).withSelectable(false).withIdentifier(9).withIcon(MaterialDesignIconic.Icon.gmi_format_list_numbered), new PrimaryDrawerItem().withName(R.string.sample_checkbox_item).withDescription(R.string.sample_checkbox_item_descr).withSelectable(false).withIdentifier(10).withIcon(CommunityMaterial.Icon.cmd_checkbox_marked), new PrimaryDrawerItem().withName(R.string.sample_radiobutton_item).withDescription(R.string.sample_radiobutton_item_descr).withSelectable(false).withIdentifier(11).withIcon(CommunityMaterial.Icon.cmd_radiobox_marked), + new PrimaryDrawerItem().withName(R.string.sample_swipe_list).withDescription(R.string.sample_swipe_list_descr).withSelectable(false).withIdentifier(12).withIcon(MaterialDesignIconic.Icon.gmi_format_align_left), new DividerDrawerItem(), new PrimaryDrawerItem().withName(R.string.open_source).withSelectable(false).withIdentifier(100).withIcon(MaterialDesignIconic.Icon.gmi_github) ) @@ -105,6 +106,8 @@ public boolean onItemClick(View view, int position, IDrawerItem drawerItem) { intent = new Intent(SampleActivity.this, CheckBoxSampleActivity.class); } else if (drawerItem.getIdentifier() == 11) { intent = new Intent(SampleActivity.this, RadioButtonSampleActivity.class); + } else if (drawerItem.getIdentifier() == 12) { + intent = new Intent(SampleActivity.this, SwipeListActivity.class); } else if (drawerItem.getIdentifier() == 100) { intent = new LibsBuilder() .withFields(R.string.class.getFields()) diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java index 90623c341..f94d3f04e 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java +++ b/app/src/main/java/com/mikepenz/fastadapter/app/SimpleItemListActivity.java @@ -21,10 +21,11 @@ import com.mikepenz.fastadapter.IAdapter; import com.mikepenz.fastadapter.IItemAdapter; import com.mikepenz.fastadapter.adapters.FastItemAdapter; +import com.mikepenz.fastadapter.adapters.ItemAdapter.ItemFilterListener; import com.mikepenz.fastadapter.app.adapter.FastScrollIndicatorAdapter; import com.mikepenz.fastadapter.app.items.SampleItem; -import com.mikepenz.fastadapter.drag.ItemTouchCallback; -import com.mikepenz.fastadapter.drag.SimpleDragCallback; +import com.mikepenz.fastadapter_extensions.drag.ItemTouchCallback; +import com.mikepenz.fastadapter_extensions.drag.SimpleDragCallback; import com.mikepenz.materialize.MaterializeBuilder; import com.turingtechnologies.materialscrollbar.AlphabetIndicator; import com.turingtechnologies.materialscrollbar.DragScrollBar; @@ -34,7 +35,7 @@ import java.util.List; import java.util.Random; -public class SimpleItemListActivity extends AppCompatActivity implements ItemTouchCallback { +public class SimpleItemListActivity extends AppCompatActivity implements ItemTouchCallback, ItemFilterListener { 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 @@ -82,6 +83,8 @@ public boolean filter(SampleItem item, CharSequence constraint) { } }); + fastItemAdapter.getItemAdapter().setItemFilterListener(this); + //get our recyclerView and do basic setup RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv); recyclerView.setLayoutManager(new LinearLayoutManager(this)); @@ -175,4 +178,9 @@ public boolean itemTouchOnMove(int oldPosition, int newPosition) { fastItemAdapter.notifyAdapterItemMoved(oldPosition, newPosition); return true; } + + @Override + public void itemsFiltered() { + Toast.makeText(SimpleItemListActivity.this, "filtered items count: " + fastItemAdapter.getItemCount(), Toast.LENGTH_SHORT).show(); + } } diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/SwipeListActivity.java b/app/src/main/java/com/mikepenz/fastadapter/app/SwipeListActivity.java new file mode 100644 index 000000000..b000134fe --- /dev/null +++ b/app/src/main/java/com/mikepenz/fastadapter/app/SwipeListActivity.java @@ -0,0 +1,239 @@ +package com.mikepenz.fastadapter.app; + +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SearchView; +import android.support.v7.widget.Toolbar; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.Toast; + +import com.mikepenz.fastadapter.FastAdapter; +import com.mikepenz.fastadapter.IAdapter; +import com.mikepenz.fastadapter.IItemAdapter; +import com.mikepenz.fastadapter.adapters.FastItemAdapter; +import com.mikepenz.fastadapter.app.items.SwipeableItem; +import com.mikepenz.fastadapter_extensions.swipe.SimpleSwipeCallback; +import com.mikepenz.fastadapter_extensions.swipe.SimpleSwipeDragCallback; +import com.mikepenz.fastadapter_extensions.drag.ItemTouchCallback; +import com.mikepenz.fastadapter_extensions.drag.SimpleDragCallback; +import com.mikepenz.iconics.IconicsDrawable; +import com.mikepenz.material_design_iconic_typeface_library.MaterialDesignIconic; +import com.mikepenz.materialize.MaterializeBuilder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +public class SwipeListActivity extends AppCompatActivity implements ItemTouchCallback, SimpleSwipeCallback.ItemSwipeCallback { + 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 FastItemAdapter fastItemAdapter; + + //drag & drop + private SimpleDragCallback touchCallback; + private ItemTouchHelper touchHelper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + findViewById(android.R.id.content).setSystemUiVisibility(findViewById(android.R.id.content).getSystemUiVisibility() | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_sample); + + // Handle Toolbar + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + + //style our ui + new MaterializeBuilder().withActivity(this).build(); + + //create our FastAdapter which will manage everything + fastItemAdapter = new FastItemAdapter<>(); + + //configure our fastAdapter + fastItemAdapter.withOnClickListener(new FastAdapter.OnClickListener() { + @Override + public boolean onClick(View v, IAdapter adapter, SwipeableItem item, int position) { + Toast.makeText(v.getContext(), (item).name.getText(v.getContext()), Toast.LENGTH_LONG).show(); + return false; + } + }); + + //configure the itemAdapter + fastItemAdapter.withFilterPredicate(new IItemAdapter.Predicate() { + @Override + public boolean filter(SwipeableItem item, CharSequence constraint) { + //return true if we should filter it out + //return false to keep it + return !item.name.getText().toLowerCase().contains(constraint.toString().toLowerCase()); + } + }); + + //get our recyclerView and do basic setup + RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setAdapter(fastItemAdapter); + + //fill with some sample data + int x = 0; + List items = new ArrayList<>(); + for (String s : ALPHABET) { + int count = new Random().nextInt(20); + for (int i = 1; i <= count; i++) { + items.add(new SwipeableItem().withName(s + " Test " + x).withIdentifier(100 + x)); + x++; + } + } + fastItemAdapter.add(items); + + + //add drag and drop for item + //and add swipe as well + Drawable leaveBehindDrawableLeft = new IconicsDrawable(this) + .icon(MaterialDesignIconic.Icon.gmi_delete) + .color(Color.WHITE) + .sizeDp(24); + Drawable leaveBehindDrawableRight = new IconicsDrawable(this) + .icon(MaterialDesignIconic.Icon.gmi_archive) + .color(Color.WHITE) + .sizeDp(24); + + touchCallback = new SimpleSwipeDragCallback( + this, + this, + leaveBehindDrawableLeft, + ItemTouchHelper.LEFT, + ContextCompat.getColor(this, R.color.md_red_900) + ) + .withBackgroundSwipeRight(ContextCompat.getColor(this, R.color.md_blue_900)) + .withLeaveBehindSwipeRight(leaveBehindDrawableRight); + + touchHelper = new ItemTouchHelper(touchCallback); // Create ItemTouchHelper and pass with parameter the SimpleDragCallback + touchHelper.attachToRecyclerView(recyclerView); // Attach ItemTouchHelper to RecyclerView + + //restore selections (this has to be done after the items were added + fastItemAdapter.withSavedInstanceState(savedInstanceState); + + //set the back arrow in the toolbar + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(false); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + //add the values which need to be saved from the adapter to the bundle + outState = fastItemAdapter.saveInstanceState(outState); + super.onSaveInstanceState(outState); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + //handle the click on the back arrow click + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + + default: + return super.onOptionsItemSelected(item); + } + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu items for use in the action bar + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.search, menu); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + final SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String s) { + touchCallback.setIsDragEnabled(false); + fastItemAdapter.filter(s); + return true; + } + + + @Override + public boolean onQueryTextChange(String s) { + fastItemAdapter.filter(s); + touchCallback.setIsDragEnabled(TextUtils.isEmpty(s)); + return true; + } + }); + } else { + menu.findItem(R.id.search).setVisible(false); + } + + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean itemTouchOnMove(int oldPosition, int newPosition) { + Collections.swap(fastItemAdapter.getAdapterItems(), oldPosition, newPosition); // change position + fastItemAdapter.notifyAdapterItemMoved(oldPosition, newPosition); + return true; + } + + @Override + public void itemSwiped(int position, int direction) { + // -- Option 1: Direct action -- + //do something when swiped such as: select, remove, update, ...: + //A) fastItemAdapter.select(position); + //B) fastItemAdapter.remove(position); + //C) update item, set "read" if an email etc + + // -- Option 2: Delayed action -- + final SwipeableItem item = fastItemAdapter.getItem(position); + item.setSwipedDirection(direction); + + // This can vary depending on direction but remove & archive simulated here both results in + // removal from list + final Runnable removeRunnable = new Runnable() { + @Override + public void run() { + item.setSwipedAction(null); + int position = fastItemAdapter.getAdapterPosition(item); + if (position != RecyclerView.NO_POSITION) { + fastItemAdapter.remove(position); + } + } + }; + final View rv = findViewById(R.id.rv); + rv.postDelayed(removeRunnable, 3000); + + item.setSwipedAction(new Runnable() { + @Override + public void run() { + rv.removeCallbacks(removeRunnable); + item.setSwipedDirection(0); + int position = fastItemAdapter.getAdapterPosition(item); + if (position != RecyclerView.NO_POSITION) { + fastItemAdapter.notifyItemChanged(position); + } + } + }); + + fastItemAdapter.notifyItemChanged(position); + + //TODO can this above be made more generic, along with the support in the item? + } + +} diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/items/SwipeableItem.java b/app/src/main/java/com/mikepenz/fastadapter/app/items/SwipeableItem.java new file mode 100644 index 000000000..6dc376530 --- /dev/null +++ b/app/src/main/java/com/mikepenz/fastadapter/app/items/SwipeableItem.java @@ -0,0 +1,168 @@ +package com.mikepenz.fastadapter.app.items; + +import android.support.annotation.StringRes; +import android.support.v4.content.ContextCompat; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.view.View; +import android.widget.TextView; + +import com.mikepenz.fastadapter.app.R; +import com.mikepenz.fastadapter.items.AbstractItem; +import com.mikepenz.fastadapter.utils.ViewHolderFactory; +import com.mikepenz.materialdrawer.holder.StringHolder; + +import butterknife.Bind; +import butterknife.ButterKnife; + +/** + * Created by Mattias on 2016-02-15. + */ +public class SwipeableItem extends AbstractItem { + //the static ViewHolderFactory which will be used to generate the ViewHolder for this Item + private static final ViewHolderFactory FACTORY = new ItemFactory(); + + public StringHolder name; + public StringHolder description; + + public StringHolder undoTextSwipeFromRight; + public StringHolder undoTextSwipeFromLeft; + public StringHolder undoTextSwipeFromTop; + public StringHolder undoTextSwipeFromBottom; + + public int swipedDirection; + private Runnable swipedAction; + + public SwipeableItem withName(String Name) { + this.name = new StringHolder(Name); + return this; + } + + public SwipeableItem withName(@StringRes int NameRes) { + this.name = new StringHolder(NameRes); + return this; + } + + public SwipeableItem withDescription(String description) { + this.description = new StringHolder(description); + return this; + } + + public SwipeableItem withDescription(@StringRes int descriptionRes) { + this.description = new StringHolder(descriptionRes); + return this; + } + + public void setSwipedDirection(int swipedDirection) { + this.swipedDirection = swipedDirection; + } + + public void setSwipedAction(Runnable action) { + this.swipedAction = action; + } + + /** + * defines the type defining this item. must be unique. preferably an id + * + * @return the type + */ + @Override + public int getType() { + return R.id.fastadapter_swipable_item_id; + } + + /** + * defines the layout which will be used for this item in the list + * + * @return the layout for this item + */ + @Override + public int getLayoutRes() { + return R.layout.swipeable_item; + } + + /** + * binds the data of this item onto the viewHolder + * + * @param viewHolder the viewHolder of this item + */ + @Override + public void bindView(ViewHolder viewHolder) { + super.bindView(viewHolder); + + //set the text for the name + StringHolder.applyTo(name, viewHolder.name); + //set the text for the description or hide + StringHolder.applyToOrHide(description, viewHolder.description); + + viewHolder.swipeResultContent.setVisibility(swipedDirection != 0 ? View.VISIBLE : View.GONE); + viewHolder.itemContent.setVisibility(swipedDirection != 0 ? View.GONE : View.VISIBLE); + + CharSequence swipedAction = null; + CharSequence swipedText = null; + if (swipedDirection != 0) { + swipedAction = viewHolder.itemView.getContext().getString(R.string.action_undo); + swipedText = swipedDirection == ItemTouchHelper.LEFT ? "Removed" : "Archived"; + viewHolder.swipeResultContent.setBackgroundColor(ContextCompat.getColor(viewHolder.itemView.getContext(), swipedDirection == ItemTouchHelper.LEFT ? R.color.md_red_900 : R.color.md_blue_900)); + } + viewHolder.swipedAction.setText(swipedAction == null ? "" : swipedAction); + viewHolder.swipedText.setText(swipedText == null ? "" : swipedText); + viewHolder.swipedActionRunnable = this.swipedAction; + } + + + /** + * our ItemFactory implementation which creates the ViewHolder for our adapter. + * It is highly recommended to implement a ViewHolderFactory as it is 0-1ms faster for ViewHolder creation, + * and it is also many many times more efficient if you define custom listeners on views within your item. + */ + protected static class ItemFactory implements ViewHolderFactory { + public ViewHolder create(View v) { + return new ViewHolder(v); + } + } + + /** + * return our ViewHolderFactory implementation here + * + * @return + */ + @Override + public ViewHolderFactory getFactory() { + return FACTORY; + } + + + /** + * our ViewHolder + */ + protected static class ViewHolder extends RecyclerView.ViewHolder { + @Bind(R.id.material_drawer_name) + TextView name; + @Bind(R.id.material_drawer_description) + TextView description; + @Bind(R.id.swipe_result_content) + View swipeResultContent; + @Bind(R.id.item_content) + View itemContent; + @Bind(R.id.swiped_text) + TextView swipedText; + @Bind(R.id.swiped_action) + TextView swipedAction; + + public Runnable swipedActionRunnable; + + public ViewHolder(View view) { + super(view); + ButterKnife.bind(this, view); + swipedAction.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (swipedActionRunnable != null) { + swipedActionRunnable.run(); + } + } + }); + } + } +} diff --git a/app/src/main/res/layout/swipeable_item.xml b/app/src/main/res/layout/swipeable_item.xml new file mode 100644 index 000000000..b6935d3c8 --- /dev/null +++ b/app/src/main/res/layout/swipeable_item.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index 4206be355..cd6643caa 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -10,4 +10,5 @@ + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 66a38112c..3ca6da62c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,6 +3,8 @@ SimpleItemList Sample FastScroller, Filter, Drag&Drop + SwipeList Sample + Swipe, leave-behinds and actions IconGrid Sample Grid, Expandable ImageList Sample @@ -25,4 +27,5 @@ Use FastAdapters internal state with a RadioButton Open Source Suche + UNDO diff --git a/library/gradle-jcenter-push.gradle b/gradle-jcenter-push.gradle similarity index 100% rename from library/gradle-jcenter-push.gradle rename to gradle-jcenter-push.gradle diff --git a/library/gradle-mvn-push.gradle b/gradle-mvn-push.gradle similarity index 100% rename from library/gradle-mvn-push.gradle rename to gradle-mvn-push.gradle diff --git a/gradle.properties b/gradle.properties index 61f091f2d..84ffb79be 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,4 @@ # Maven stuff -VERSION_NAME=1.0.6 -VERSION_CODE=106 GROUP=com.mikepenz POM_DESCRIPTION=FastAdapter Library diff --git a/library-extensions/.gitignore b/library-extensions/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/library-extensions/.gitignore @@ -0,0 +1 @@ +/build diff --git a/library-extensions/build.gradle b/library-extensions/build.gradle new file mode 100644 index 000000000..656f5ea11 --- /dev/null +++ b/library-extensions/build.gradle @@ -0,0 +1,35 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + + defaultConfig { + minSdkVersion 10 + targetSdkVersion 23 + versionCode 110 + versionName '1.1.0' + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' + } + } + productFlavors { + } + lintOptions { + abortOnError false + } +} + +if (project.hasProperty('pushall') || project.hasProperty('libraryextensiononly')) { + apply from: '../gradle-mvn-push.gradle' + apply plugin: 'com.novoda.bintray-release' + apply from: '../gradle-jcenter-push.gradle' +} + +dependencies { + compile project(':library') + compile "com.android.support:design:${rootProject.ext.supportLibVersion}" +} diff --git a/library-extensions/gradle.properties b/library-extensions/gradle.properties new file mode 100755 index 000000000..6a2530f3f --- /dev/null +++ b/library-extensions/gradle.properties @@ -0,0 +1,6 @@ +POM_NAME=FastAdapter Library-Extensions +POM_ARTIFACT_ID=fastadapter-extensions +POM_PACKAGING=aar + +VERSION_NAME=1.1.0 +VERSION_CODE=110 \ No newline at end of file diff --git a/library-extensions/proguard-rules.pro b/library-extensions/proguard-rules.pro new file mode 100644 index 000000000..da6f30276 --- /dev/null +++ b/library-extensions/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Development/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/library-extensions/src/main/AndroidManifest.xml b/library-extensions/src/main/AndroidManifest.xml new file mode 100644 index 000000000..f982cae13 --- /dev/null +++ b/library-extensions/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/library/src/main/java/com/mikepenz/fastadapter/helpers/ActionModeHelper.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/ActionModeHelper.java similarity index 99% rename from library/src/main/java/com/mikepenz/fastadapter/helpers/ActionModeHelper.java rename to library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/ActionModeHelper.java index 59cc35318..fbd283fe2 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/helpers/ActionModeHelper.java +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/ActionModeHelper.java @@ -1,4 +1,4 @@ -package com.mikepenz.fastadapter.helpers; +package com.mikepenz.fastadapter_extensions; import android.support.annotation.MenuRes; diff --git a/library/src/main/java/com/mikepenz/fastadapter/helpers/UndoHelper.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/UndoHelper.java similarity index 99% rename from library/src/main/java/com/mikepenz/fastadapter/helpers/UndoHelper.java rename to library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/UndoHelper.java index 3f644a5a0..b94807267 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/helpers/UndoHelper.java +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/UndoHelper.java @@ -1,4 +1,4 @@ -package com.mikepenz.fastadapter.helpers; +package com.mikepenz.fastadapter_extensions; import android.support.design.widget.Snackbar; import android.view.View; diff --git a/library/src/main/java/com/mikepenz/fastadapter/drag/ItemTouchCallback.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/drag/ItemTouchCallback.java similarity index 85% rename from library/src/main/java/com/mikepenz/fastadapter/drag/ItemTouchCallback.java rename to library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/drag/ItemTouchCallback.java index 7578fcbaa..26fd1f9c7 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/drag/ItemTouchCallback.java +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/drag/ItemTouchCallback.java @@ -1,4 +1,4 @@ -package com.mikepenz.fastadapter.drag; +package com.mikepenz.fastadapter_extensions.drag; public interface ItemTouchCallback { diff --git a/library/src/main/java/com/mikepenz/fastadapter/drag/SimpleDragCallback.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/drag/SimpleDragCallback.java similarity index 96% rename from library/src/main/java/com/mikepenz/fastadapter/drag/SimpleDragCallback.java rename to library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/drag/SimpleDragCallback.java index 37eb9413a..1d4da6cbf 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/drag/SimpleDragCallback.java +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/drag/SimpleDragCallback.java @@ -1,4 +1,4 @@ -package com.mikepenz.fastadapter.drag; +package com.mikepenz.fastadapter_extensions.drag; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.helper.ItemTouchHelper; diff --git a/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/swipe/SimpleSwipeCallback.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/swipe/SimpleSwipeCallback.java new file mode 100644 index 000000000..2f070f7b3 --- /dev/null +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/swipe/SimpleSwipeCallback.java @@ -0,0 +1,156 @@ +package com.mikepenz.fastadapter_extensions.swipe; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.support.annotation.ColorInt; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.view.View; + + +/** + * Created by Mattias on 2016-02-13. + */ +public class SimpleSwipeCallback extends ItemTouchHelper.SimpleCallback { + + public interface ItemSwipeCallback { + + /** + * Called when an item has been swiped + * + * @param position position of item in the adapter + * @param direction direction the item was swiped + */ + void itemSwiped(int position, int direction); + + } + + private final ItemSwipeCallback itemSwipeCallback; + + private int bgColorLeft; + private int bgColorRight; + private Drawable leaveBehindDrawableLeft; + private Drawable leaveBehindDrawableRight; + + private Paint bgPaint; + private int horizontalMargin = Integer.MAX_VALUE; + + public SimpleSwipeCallback(SimpleSwipeCallback.ItemSwipeCallback itemSwipeCallback, Drawable leaveBehindDrawableLeft) { + this(itemSwipeCallback, leaveBehindDrawableLeft, ItemTouchHelper.LEFT); + } + + public SimpleSwipeCallback(SimpleSwipeCallback.ItemSwipeCallback itemSwipeCallback, Drawable leaveBehindDrawableLeft, int swipeDirs) { + this(itemSwipeCallback, leaveBehindDrawableLeft, swipeDirs, Color.RED); + } + + public SimpleSwipeCallback(ItemSwipeCallback itemSwipeCallback, Drawable leaveBehindDrawableLeft, int swipeDirs, @ColorInt int bgColor) { + super(0, swipeDirs); + this.itemSwipeCallback = itemSwipeCallback; + this.leaveBehindDrawableLeft = leaveBehindDrawableLeft; + this.bgColorLeft = bgColor; + } + + public SimpleSwipeCallback withLeaveBehindSwipeLeft(Drawable d) { + this.leaveBehindDrawableLeft = d; + setDefaultSwipeDirs(getSwipeDirs(null, null) | ItemTouchHelper.LEFT); + return this; + } + + public SimpleSwipeCallback withLeaveBehindSwipeRight(Drawable d) { + this.leaveBehindDrawableRight = d; + setDefaultSwipeDirs(getSwipeDirs(null, null) | ItemTouchHelper.RIGHT); + return this; + } + + public SimpleSwipeCallback withHorizontalMarginDp(Context ctx, int dp) { + return withHorizontalMarginPx((int) (ctx.getResources().getDisplayMetrics().density * dp)); + } + + public SimpleSwipeCallback withHorizontalMarginPx(int px) { + horizontalMargin = px; + return this; + } + + public SimpleSwipeCallback withBackgroundSwipeLeft(@ColorInt int bgColor) { + bgColorLeft = bgColor; + return this; + } + + public SimpleSwipeCallback withBackgroundSwipeRight(@ColorInt int bgColor) { + bgColorRight = bgColor; + return this; + } + + @Override + public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { + //TODO should disallow this if in swiped state + return super.getSwipeDirs(recyclerView, viewHolder); + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + viewHolder.itemView.setTranslationX(0); + viewHolder.itemView.setTranslationY(0); + int position = viewHolder.getAdapterPosition(); + if (position != RecyclerView.NO_POSITION) { + itemSwipeCallback.itemSwiped(position, direction); + } + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { + // not enabled + return false; + } + + //Inspired/modified from: https://github.com/nemanja-kovacevic/recycler-view-swipe-to-delete/blob/master/app/src/main/java/net/nemanjakovacevic/recyclerviewswipetodelete/MainActivity.java + @Override + public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + View itemView = viewHolder.itemView; + if (viewHolder.getAdapterPosition() == RecyclerView.NO_POSITION) { + return; + } + if (Math.abs(dX) > Math.abs(dY)) { + boolean isLeft = dX < 0; + if (bgPaint == null) { + bgPaint = new Paint(); + if (horizontalMargin == Integer.MAX_VALUE) { + withHorizontalMarginDp(recyclerView.getContext(), 16); + } + } + bgPaint.setColor(isLeft ? bgColorLeft : bgColorRight); + + if (bgPaint.getColor() != Color.TRANSPARENT) { + int left = isLeft ? itemView.getRight() + (int) dX : itemView.getLeft(); + int right = isLeft ? itemView.getRight() : (itemView.getLeft() + (int) dX); + c.drawRect(left, itemView.getTop(), right, itemView.getBottom(), bgPaint); + } + + Drawable drawable = isLeft ? leaveBehindDrawableLeft : leaveBehindDrawableRight; + if (drawable != null) { + int itemHeight = itemView.getBottom() - itemView.getTop(); + int intrinsicWidth = drawable.getIntrinsicWidth(); + int intrinsicHeight = drawable.getIntrinsicWidth(); + + int left; + int right; + if (isLeft) { + left = itemView.getRight() - horizontalMargin - intrinsicWidth; + right = itemView.getRight() - horizontalMargin; + } else { + left = itemView.getLeft() + horizontalMargin; + right = itemView.getLeft() + horizontalMargin + intrinsicWidth; + } + int top = itemView.getTop() + (itemHeight - intrinsicHeight) / 2; + int bottom = top + intrinsicHeight; + drawable.setBounds(left, top, right, bottom); + + drawable.draw(c); + } + } + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } +} diff --git a/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/swipe/SimpleSwipeDragCallback.java b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/swipe/SimpleSwipeDragCallback.java new file mode 100644 index 000000000..e2d1eee16 --- /dev/null +++ b/library-extensions/src/main/java/com/mikepenz/fastadapter_extensions/swipe/SimpleSwipeDragCallback.java @@ -0,0 +1,78 @@ +package com.mikepenz.fastadapter_extensions.swipe; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.support.annotation.ColorInt; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; + +import com.mikepenz.fastadapter_extensions.drag.ItemTouchCallback; +import com.mikepenz.fastadapter_extensions.drag.SimpleDragCallback; + +/** + * Created by Mattias on 2016-02-13. + */ +public class SimpleSwipeDragCallback extends SimpleDragCallback { + + private final SimpleSwipeCallback simpleSwipeCallback; + + public SimpleSwipeDragCallback(ItemTouchCallback itemTouchCallback, SimpleSwipeCallback.ItemSwipeCallback itemSwipeCallback, Drawable leaveBehindDrawable) { + this(itemTouchCallback, itemSwipeCallback, leaveBehindDrawable, ItemTouchHelper.LEFT); + } + + public SimpleSwipeDragCallback(ItemTouchCallback itemTouchCallback, SimpleSwipeCallback.ItemSwipeCallback itemSwipeCallback, Drawable leaveBehindDrawable, int swipeDirs) { + this(itemTouchCallback, itemSwipeCallback, leaveBehindDrawable, swipeDirs, Color.RED); + } + + public SimpleSwipeDragCallback(ItemTouchCallback itemTouchCallback, SimpleSwipeCallback.ItemSwipeCallback itemSwipeCallback, Drawable leaveBehindDrawable, int swipeDirs, @ColorInt int bgColor) { + super(itemTouchCallback); + setDefaultSwipeDirs(swipeDirs); + simpleSwipeCallback = new SimpleSwipeCallback(itemSwipeCallback, leaveBehindDrawable, swipeDirs, bgColor); + } + + public SimpleSwipeDragCallback withLeaveBehindSwipeLeft(Drawable d) { + setDefaultSwipeDirs(getSwipeDirs(null, null)|ItemTouchHelper.LEFT); + simpleSwipeCallback.withLeaveBehindSwipeLeft(d); + return this; + } + + public SimpleSwipeDragCallback withLeaveBehindSwipeRight(Drawable d) { + setDefaultSwipeDirs(getSwipeDirs(null, null) | ItemTouchHelper.RIGHT); + simpleSwipeCallback.withLeaveBehindSwipeRight(d); + return this; + } + + public SimpleSwipeDragCallback withHorizontalMarginDp(Context ctx, int dp) { + simpleSwipeCallback.withHorizontalMarginDp(ctx, dp); + return this; + } + + public SimpleSwipeDragCallback withHorizontalMarginPx(int px) { + simpleSwipeCallback.withHorizontalMarginPx(px); + return this; + } + + public SimpleSwipeDragCallback withBackgroundSwipeLeft(@ColorInt int bgColor) { + simpleSwipeCallback.withBackgroundSwipeLeft(bgColor); + return this; + } + + public SimpleSwipeDragCallback withBackgroundSwipeRight(@ColorInt int bgColor) { + simpleSwipeCallback.withBackgroundSwipeRight(bgColor); + return this; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + simpleSwipeCallback.onSwiped(viewHolder, direction); + } + + @Override + public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + simpleSwipeCallback.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + //Happen to know that our direct parent class doesn't (currently) draw anything... + //super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } +} diff --git a/library/build.gradle b/library/build.gradle index 9c75f2ef0..4be3be31b 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -1,5 +1,4 @@ apply plugin: 'com.android.library' -apply plugin: 'com.novoda.bintray-release' android { compileSdkVersion rootProject.ext.compileSdkVersion @@ -8,8 +7,8 @@ android { defaultConfig { minSdkVersion 10 targetSdkVersion 23 - versionCode 106 - versionName '1.0.6' + versionCode 110 + versionName '1.1.0' } buildTypes { release { @@ -24,12 +23,14 @@ android { } } -apply from: 'gradle-mvn-push.gradle' -apply from: 'gradle-jcenter-push.gradle' +if (project.hasProperty('pushall') || project.hasProperty('librarycoreonly')) { + apply from: '../gradle-mvn-push.gradle' + apply plugin: 'com.novoda.bintray-release' + apply from: '../gradle-jcenter-push.gradle' +} dependencies { compile "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" compile "com.android.support:recyclerview-v7:${rootProject.ext.supportLibVersion}" compile "com.android.support:support-annotations:${rootProject.ext.supportLibVersion}" - compile "com.android.support:design:${rootProject.ext.supportLibVersion}" } diff --git a/library/gradle.properties b/library/gradle.properties index 14230b7a4..48a600d6d 100755 --- a/library/gradle.properties +++ b/library/gradle.properties @@ -1,22 +1,6 @@ -# Project-wide Gradle settings. - -# IDE (e.g. Android Studio) users: -# Settings specified in this file will override any Gradle settings -# configured through the IDE. - -# For more details on how to configure your build environment visit -# http://www.gradle.org/docs/current/userguide/build_environment.html - -# Specifies the JVM arguments used for the daemon process. -# The setting is particularly useful for tweaking memory settings. -# Default value: -Xmx10248m -XX:MaxPermSize=256m -# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 - -# When configured, Gradle will run in incubating parallel mode. -# This option should only be used with decoupled projects. More details, visit -# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true - POM_NAME=FastAdapter Library POM_ARTIFACT_ID=fastadapter POM_PACKAGING=aar + +VERSION_NAME=1.1.0 +VERSION_CODE=110 \ No newline at end of file diff --git a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java index 144edc0cf..abd8f4075 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/FastAdapter.java @@ -503,7 +503,6 @@ public long getItemId(int position) { * * @return the global count */ - @Override public int getItemCount() { return mGlobalSize; } @@ -514,14 +513,42 @@ public int getItemCount() { * @param order the number up to which the items are counted * @return the total count of items up to the adapter order */ - public int getItemCount(int order) { + public int getPreItemCountByOrder(int order) { + //if we are empty just return 0 count + if (mGlobalSize == 0) { + return 0; + } + + int size = 0; + + //count the number of items before the adapter with the given order + for (IAdapter adapter : mAdapters.values()) { + if (adapter.getOrder() == order) { + return size; + } else { + size = size + adapter.getAdapterItemCount(); + } + } + + //get the count of items which are before this order + return size; + } + + + /** + * calculates the item count up to a given (excluding this) adapter (defined by the global position of the item) + * + * @param position the global position of an adapter item + * @return the total count of items up to the adapter which holds the given position + */ + public int getPreItemCount(int position) { //if we are empty just return 0 count if (mGlobalSize == 0) { return 0; } //get the count of items which are before this order - return mAdapterSizes.floorKey(order); + return mAdapterSizes.floorKey(position); } /** @@ -568,6 +595,12 @@ public Bundle saveInstanceState(Bundle savedInstanceState, String prefix) { private void cacheSizes() { mAdapterSizes.clear(); int size = 0; + + //we also have to add this for the first adapter otherwise the floorKey method will return the wrong value + if (mAdapters.size() > 0) { + mAdapterSizes.put(0, mAdapters.valueAt(0)); + } + for (IAdapter adapter : mAdapters.values()) { if (adapter.getAdapterItemCount() > 0) { mAdapterSizes.put(size, adapter); diff --git a/library/src/main/java/com/mikepenz/fastadapter/adapters/GenericItemAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/adapters/GenericItemAdapter.java index b0c19ecb2..82428c805 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/adapters/GenericItemAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/adapters/GenericItemAdapter.java @@ -92,7 +92,7 @@ public final void addModel(int position, Model... models) { */ public void addModel(int position, List models) { super.add(position, toItems(models)); - mItems.addAll(position - getFastAdapter().getItemCount(getOrder()), models); + mItems.addAll(position - getFastAdapter().getPreItemCount(position), models); } /** @@ -103,7 +103,7 @@ public void addModel(int position, List models) { */ public void setModel(int position, Model model) { super.set(position, toItem(model)); - mItems.set(position - getFastAdapter().getItemCount(getOrder()), model); + mItems.set(position - getFastAdapter().getPreItemCount(position), model); } /** @@ -125,11 +125,12 @@ public void removeModelRange(int position, int itemCount) { //global position to relative int length = mItems.size(); + int preItemCount = getFastAdapter().getPreItemCount(position); //make sure we do not delete to many items - int saveItemCount = Math.min(itemCount, length - position + getFastAdapter().getItemCount(getOrder())); + int saveItemCount = Math.min(itemCount, length - position + preItemCount); for (int i = 0; i < saveItemCount; i++) { - mItems.remove(position - getFastAdapter().getItemCount(getOrder())); + mItems.remove(position - preItemCount); } } @@ -140,7 +141,7 @@ public void removeModelRange(int position, int itemCount) { */ public void removeModel(int position) { super.remove(position); - mItems.remove(position - getFastAdapter().getItemCount(getOrder())); + mItems.remove(position - getFastAdapter().getPreItemCount(position)); } /** diff --git a/library/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java b/library/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java index 65f97a00d..7508f021a 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java +++ b/library/src/main/java/com/mikepenz/fastadapter/adapters/ItemAdapter.java @@ -69,6 +69,14 @@ public void filter(CharSequence constraint) { mItemFilter.filter(constraint); } + public void setItemFilterListener(ItemFilterListener listener) { + mItemFilterListener = listener; + } + protected ItemFilterListener mItemFilterListener; + public interface ItemFilterListener { + void itemsFiltered(); + } + /** * @return the order of the items within the FastAdapter */ @@ -116,7 +124,7 @@ public int getAdapterPosition(Item item) { * @return the global position */ public int getGlobalPosition(int position) { - return position + getFastAdapter().getItemCount(getOrder()); + return position + getFastAdapter().getPreItemCount(position); } /** @@ -160,7 +168,7 @@ public void set(List items) { //get sizes int newItemsCount = items.size(); int previousItemsCount = mItems.size(); - int itemsBeforeThisAdapter = getFastAdapter().getItemCount(getOrder()); + int itemsBeforeThisAdapter = getFastAdapter().getPreItemCountByOrder(getOrder()); //make sure the new items list is not a reference of the already mItems list if (items != mItems) { @@ -227,7 +235,7 @@ public void add(List items) { } mItems.addAll(items); mapPossibleTypes(items); - getFastAdapter().notifyAdapterItemRangeInserted(getFastAdapter().getItemCount(getOrder()), items.size()); + getFastAdapter().notifyAdapterItemRangeInserted(getFastAdapter().getPreItemCountByOrder(getOrder()), items.size()); } /** @@ -252,7 +260,7 @@ public void add(int position, List items) { IdDistributor.checkIds(items); } if (items != null) { - mItems.addAll(position - getFastAdapter().getItemCount(getOrder()), items); + mItems.addAll(position - getFastAdapter().getPreItemCount(position), items); mapPossibleTypes(items); getFastAdapter().notifyAdapterItemRangeInserted(position, items.size()); } @@ -268,7 +276,7 @@ public void set(int position, Item item) { if (mUseIdDistributor) { IdDistributor.checkId(item); } - mItems.set(position - getFastAdapter().getItemCount(getOrder()), item); + mItems.set(position - getFastAdapter().getPreItemCount(position), item); mapPossibleType(item); getFastAdapter().notifyAdapterItemChanged(position); } @@ -279,7 +287,7 @@ public void set(int position, Item item) { * @param position the global position */ public void remove(int position) { - mItems.remove(position - getFastAdapter().getItemCount(getOrder())); + mItems.remove(position - getFastAdapter().getPreItemCount(position)); getFastAdapter().notifyAdapterItemRemoved(position); } @@ -292,11 +300,12 @@ public void remove(int position) { public void removeRange(int position, int itemCount) { //global position to relative int length = mItems.size(); + int preItemCount = getFastAdapter().getPreItemCount(position); //make sure we do not delete to many items - int saveItemCount = Math.min(itemCount, length - position + getFastAdapter().getItemCount(getOrder())); + int saveItemCount = Math.min(itemCount, length - position + preItemCount); for (int i = 0; i < saveItemCount; i++) { - mItems.remove(position - getFastAdapter().getItemCount(getOrder())); + mItems.remove(position - preItemCount); } getFastAdapter().notifyAdapterItemRangeRemoved(position, saveItemCount); @@ -308,7 +317,7 @@ public void removeRange(int position, int itemCount) { public void clear() { int count = mItems.size(); mItems.clear(); - getFastAdapter().notifyAdapterItemRangeRemoved(getFastAdapter().getItemCount(getOrder()), count); + getFastAdapter().notifyAdapterItemRangeRemoved(getFastAdapter().getPreItemCountByOrder(getOrder()), count); } /** @@ -354,6 +363,10 @@ protected FilterResults performFiltering(CharSequence constraint) { protected void publishResults(CharSequence constraint, FilterResults results) { // Now we have to inform the adapter about the new list filtered set((List) results.values); + + if (mItemFilterListener != null) { + mItemFilterListener.itemsFiltered(); + } } } } diff --git a/library/src/main/java/com/mikepenz/fastadapter/helpers/ClickListenerHelper.java b/library/src/main/java/com/mikepenz/fastadapter/helpers/ClickListenerHelper.java index 77339b3e8..c22ae09ce 100644 --- a/library/src/main/java/com/mikepenz/fastadapter/helpers/ClickListenerHelper.java +++ b/library/src/main/java/com/mikepenz/fastadapter/helpers/ClickListenerHelper.java @@ -28,7 +28,7 @@ public ClickListenerHelper(FastAdapter fastAdapter) { * @param view the view which listens for the click * @param onClickListener the listener which gets called */ - public void listen(final RecyclerView.ViewHolder viewHolder, View view, final OnClickListener onClickListener) { + public void listen(final RecyclerView.ViewHolder viewHolder, View view, final OnClickListener onClickListener) { view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -49,7 +49,7 @@ public void onClick(View v) { * @param viewId the viewId which listens for the click * @param onClickListener the listener which gets called */ - public void listen(final RecyclerView.ViewHolder viewHolder, @IdRes int viewId, final OnClickListener onClickListener) { + public void listen(final RecyclerView.ViewHolder viewHolder, @IdRes int viewId, final OnClickListener onClickListener) { viewHolder.itemView.findViewById(viewId).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/library/src/main/res/values/library_fastadapter_strings.xml b/library/src/main/res/values/library_fastadapter_strings.xml index d4ea00f3a..cf28a5763 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... ]]> - 1.0.6 + 1.1.0 https://github.com/mikepenz/FastAdapter apache_2_0 true diff --git a/settings.gradle b/settings.gradle index ef1bbc736..d4fb34603 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -include ':app' +include ':app', ':library-extensions' include ':library' \ No newline at end of file