diff --git a/.gitignore b/.gitignore index 49d43a56..751a7eee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ +*/.project +*/.classpath .settings/org.eclipse.jdt.core.prefs */.settings/org.eclipse.jdt.core.prefs +*/.settings **/bin/* **/target/* **/gen/* diff --git a/.travis.yml b/.travis.yml index fbaf7a92..825f0aa9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,44 +1,29 @@ language: android jdk: oraclejdk7 +android: + components: + - build-tools-21.1.0 + - android-21 + - extra-android-m2repository + - extra-android-support + - extra-google-m2repository + env: - matrix: - - ANDROID_TARGET=15 LINT=false MAVEN=false - - ANDROID_TARGET=16 LINT=false MAVEN=false - - ANDROID_TARGET=17 LINT=false MAVEN=false - - ANDROID_TARGET=18 LINT=false MAVEN=false - - ANDROID_TARGET=19 LINT=true MAVEN=true global: - TERM=dumb - - COMPONENTS=build-tools-20.0.0,android-20,extra-android-m2repository,extra-android-support,extra-google-m2repository - - LICENSES="android-sdk-license-5be876d5|android-sdk-preview-license-52d11cd2" - - secure: Fo/btrr+HpwmQL6TNxZuh/TWRMouz9Z1RCo77tf3crNP4OHq9EAkduLc/b4i6HCGFM3fyfJ7AM5XMa3OQvXfF84FQnew7NGE6zB/CKFfKBIZyzntvrDg4VqWEAHzunT6+eBnGtxtrAE0bBo4MmUCklXWP8j5UAyjfFpSeJdOywY= - - secure: s56rqSiiwX40CQWeHTcbyVLRtwLP/pcHWqaVCKuXtZ/m9SgRI/SHp9o8ITI2dzr3syEeAkHjkJOkHQSpH0bHi1xKY4M9ODcCugwv+yDEELw1qmI6Cvwjvj1cKsG7ebt39OnCkz+TqhtI/iOEkxq7mTizFjNIxIImMkKxeQwcFgE= - - secure: UOQ9keLBuJw5Ed/eYtXarwoGuJSSvgGTob+D9aU8hVRoTUXpSDuHtk9TdS4MNXQ33jgFZEsmkpwRmV54XVEGe6xcri1uys1JDzjc+SqTEgbEh1QktfIWGvOx49YZtI2Zei0324S2qXRtemKMw4N+1XRRMP/IXEogr26Xi5JLVcI= - -before_install: - - curl -3L https://raw.github.com/embarkmobile/android-sdk-installer/version-2/android-sdk-installer | bash /dev/stdin --install=$COMPONENTS,android-$ANDROID_TARGET,sys-img-armeabi-v7a-android-$ANDROID_TARGET --accept=$LICENSES && source ~/.android-sdk-installer/env - - curl -3L -o wait_for_emulator https://github.com/embarkmobile/android-sdk-installer/raw/version-2/wait_for_emulator - - sudo chmod +x wait_for_emulator - - # Start the emulator - - echo no | android create avd --force -n test -t android-$ANDROID_TARGET --abi armeabi-v7a - - emulator -avd test -no-audio -no-window & - -before_script: - # Downloads gradle stuff - - gradle - - ./wait_for_emulator install: - true +before_script: + - sudo chmod +x gradlew + script: - - gradle connectedCheck --info - - if [[ $LINT == 'true' ]]; then gradle lint ; fi + - ./gradlew lint after_success: - - if [[ $MAVEN == 'true' && $TRAVIS_BRANCH == 'dev' && $TRAVIS_PULL_REQUEST == 'false' ]]; then gradle :lib-core:uploadArchives :lib-manipulation:uploadArchives :lib-core-slh:uploadArchives -PnexusUsername="${nexusUsername}" -PnexusPassword="${nexusPassword}" ; fi + - if [[ $TRAVIS_BRANCH == 'dev' && $TRAVIS_PULL_REQUEST == 'false' ]]; then ./gradlew :lib-core:uploadArchives :lib-manipulation:uploadArchives :lib-core-slh:uploadArchives -PnexusUsername="${nexusUsername}" -PnexusPassword="${nexusPassword}" ; fi notifications: email: false \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30803187..9b192326 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ I'm happy to view and accept pull requests. However, it is important to follow t * Branch names should start with either `feature_` or `bugfix_`. If there is an open issue, include its number, like `bugfix_123`. * **Do not** include in your commit message anything related to automatic issue closing, such as `Fixes issue 123`. We'll do that when merging your pull request. -* **Do not** put any `@author` comment. Git keeps track of all your changes and `@author` does more harm than good. +* **Do not** put any `@author` comments. Git keeps track of all your changes and `@author` does more harm than good. * **Do not** issue a pull request into the `master` branch. * Try to keep the diff as small as possible. For example, be aware of auto formatting. * All files should have the Apache 2 License header. \ No newline at end of file diff --git a/build.gradle b/build.gradle index a4110277..8ce28bc5 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:0.12.2' + classpath 'com.android.tools.build:gradle:0.14.0' classpath 'org.ajoberstar:gradle-git:0.9.0' } } diff --git a/example/.classpath b/example/.classpath deleted file mode 100644 index 940418a7..00000000 --- a/example/.classpath +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/.project b/example/.project deleted file mode 100644 index ad251d46..00000000 --- a/example/.project +++ /dev/null @@ -1,39 +0,0 @@ - - - ListViewAnimations (Example) - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/example/build.gradle b/example/build.gradle index 24012b56..f52aec58 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -17,9 +17,10 @@ apply plugin: 'com.android.application' dependencies { - compile 'com.android.support:support-annotations:20.0.0' + compile 'com.android.support:support-annotations:21.0.0' - compile 'com.android.support:support-v4:20.0.0' + compile 'com.android.support:support-v4:21.0.0' + compile 'com.android.support:appcompat-v7:21.0.0' compile 'se.emilsjolander:stickylistheaders:2.5.0' compile project(':lib-core') @@ -28,13 +29,12 @@ dependencies { } android { - compileSdkVersion 20 - buildToolsVersion '20.0.0' + compileSdkVersion 21 + buildToolsVersion '21.1' defaultConfig { - minSdkVersion 14 - //noinspection OldTargetApi - targetSdkVersion 20 + minSdkVersion 8 + targetSdkVersion 21 versionName project.VERSION_NAME versionCode Integer.parseInt(new Date().format('yyyyMMddHH')) } diff --git a/example/pom.xml b/example/pom.xml index 825a9d52..156ecc32 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -21,7 +21,7 @@ com.nhaarman.listviewanimations parent - 3.0.0-SNAPSHOT + 3.1.1-SNAPSHOT example diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml index 3c16d86c..a2503d79 100644 --- a/example/src/main/AndroidManifest.xml +++ b/example/src/main/AndroidManifest.xml @@ -22,7 +22,7 @@ diff --git a/example/src/main/java/com/haarman/listviewanimations/BaseActivity.java b/example/src/main/java/com/haarman/listviewanimations/BaseActivity.java index 2908a826..55c0521b 100644 --- a/example/src/main/java/com/haarman/listviewanimations/BaseActivity.java +++ b/example/src/main/java/com/haarman/listviewanimations/BaseActivity.java @@ -17,13 +17,13 @@ package com.haarman.listviewanimations; import android.annotation.SuppressLint; -import android.app.Activity; import android.os.Build; import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; import android.view.MenuItem; import android.view.WindowManager; -public class BaseActivity extends Activity { +public class BaseActivity extends ActionBarActivity { @SuppressLint("InlinedApi") @Override @@ -33,8 +33,8 @@ protected void onCreate(final Bundle savedInstanceState) { } super.onCreate(savedInstanceState); - assert getActionBar() != null; - getActionBar().setDisplayHomeAsUpEnabled(true); + assert getSupportActionBar() != null; + getSupportActionBar().setDisplayHomeAsUpEnabled(true); } @Override diff --git a/example/src/main/java/com/haarman/listviewanimations/MainActivity.java b/example/src/main/java/com/haarman/listviewanimations/MainActivity.java index 297c6e0c..6d2584a2 100644 --- a/example/src/main/java/com/haarman/listviewanimations/MainActivity.java +++ b/example/src/main/java/com/haarman/listviewanimations/MainActivity.java @@ -23,11 +23,14 @@ import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.content.ServiceConnection; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.support.v7.app.ActionBarActivity; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -43,7 +46,9 @@ import org.json.JSONException; import org.json.JSONObject; -public class MainActivity extends Activity { +import java.util.List; + +public class MainActivity extends ActionBarActivity { private static final String URL_GITHUB_IO = "http://nhaarman.github.io/ListViewAnimations?ref=app"; @@ -60,7 +65,30 @@ protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE); + Intent iapIntent = getExplicitIapIntent(); + if(iapIntent != null) { + bindService(iapIntent, mServiceConn, Context.BIND_AUTO_CREATE); + } + } + + /* http://stackoverflow.com/a/26318757/675383 */ + private Intent getExplicitIapIntent() { + PackageManager pm = getPackageManager(); + Intent implicitIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); + List resolveInfos = pm.queryIntentServices(implicitIntent, 0); + + // Is somebody else trying to intercept our IAP call? + if (resolveInfos == null || resolveInfos.size() != 1) { + return null; + } + + ResolveInfo serviceInfo = resolveInfos.get(0); + String packageName = serviceInfo.serviceInfo.packageName; + String className = serviceInfo.serviceInfo.name; + ComponentName component = new ComponentName(packageName, className); + Intent iapIntent = new Intent(); + iapIntent.setComponent(component); + return iapIntent; } @Override @@ -125,7 +153,9 @@ public void onSLHClicked(final View view) { @Override public void onDestroy() { super.onDestroy(); - unbindService(mServiceConn); + if(mService != null) { + unbindService(mServiceConn); + } } @Override diff --git a/example/src/main/java/com/haarman/listviewanimations/StickyListHeadersActivity.java b/example/src/main/java/com/haarman/listviewanimations/StickyListHeadersActivity.java index 65e266b3..8cfeab5d 100644 --- a/example/src/main/java/com/haarman/listviewanimations/StickyListHeadersActivity.java +++ b/example/src/main/java/com/haarman/listviewanimations/StickyListHeadersActivity.java @@ -16,6 +16,7 @@ package com.haarman.listviewanimations; +import android.os.Build; import android.os.Bundle; import com.nhaarman.listviewanimations.appearance.StickyListHeadersAdapterDecorator; @@ -32,7 +33,9 @@ protected void onCreate(final Bundle savedInstanceState) { setContentView(R.layout.activity_stickylistheaders); StickyListHeadersListView listView = (StickyListHeadersListView) findViewById(R.id.activity_stickylistheaders_listview); - listView.setFitsSystemWindows(true); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + listView.setFitsSystemWindows(true); + } MyListAdapter adapter = new MyListAdapter(this); AlphaInAnimationAdapter animationAdapter = new AlphaInAnimationAdapter(adapter); diff --git a/example/src/main/java/com/haarman/listviewanimations/appearance/AppearanceExamplesActivity.java b/example/src/main/java/com/haarman/listviewanimations/appearance/AppearanceExamplesActivity.java index 3130eab4..908acc11 100644 --- a/example/src/main/java/com/haarman/listviewanimations/appearance/AppearanceExamplesActivity.java +++ b/example/src/main/java/com/haarman/listviewanimations/appearance/AppearanceExamplesActivity.java @@ -15,11 +15,11 @@ */ package com.haarman.listviewanimations.appearance; -import android.app.ActionBar; import android.content.Context; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.v7.app.ActionBar; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -56,11 +56,11 @@ protected void onCreate(final Bundle savedInstanceState) { setAlphaAdapter(); assert getActionBar() != null; - getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); - getActionBar().setDisplayShowTitleEnabled(false); + getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); + getSupportActionBar().setDisplayShowTitleEnabled(false); SpinnerAdapter animSelectionAdapter = new AnimSelectionAdapter(this); - getActionBar().setListNavigationCallbacks(animSelectionAdapter, this); + getSupportActionBar().setListNavigationCallbacks(animSelectionAdapter, this); } private void setAlphaAdapter() { diff --git a/example/src/main/java/com/haarman/listviewanimations/gridview/GridViewActivity.java b/example/src/main/java/com/haarman/listviewanimations/gridview/GridViewActivity.java index c9c7fa8c..1f9097ef 100644 --- a/example/src/main/java/com/haarman/listviewanimations/gridview/GridViewActivity.java +++ b/example/src/main/java/com/haarman/listviewanimations/gridview/GridViewActivity.java @@ -41,7 +41,7 @@ protected void onCreate(final Bundle savedInstanceState) { gridView.setAdapter(swingBottomInAnimationAdapter); - assert getActionBar() != null; - getActionBar().setDisplayHomeAsUpEnabled(true); + assert getSupportActionBar() != null; + getSupportActionBar().setDisplayHomeAsUpEnabled(true); } } diff --git a/example/src/main/java/com/haarman/listviewanimations/itemmanipulation/DynamicListViewActivity.java b/example/src/main/java/com/haarman/listviewanimations/itemmanipulation/DynamicListViewActivity.java index 7edd1a87..36b7e2de 100644 --- a/example/src/main/java/com/haarman/listviewanimations/itemmanipulation/DynamicListViewActivity.java +++ b/example/src/main/java/com/haarman/listviewanimations/itemmanipulation/DynamicListViewActivity.java @@ -29,13 +29,13 @@ import com.haarman.listviewanimations.MyListActivity; import com.haarman.listviewanimations.R; import com.nhaarman.listviewanimations.ArrayAdapter; +import com.nhaarman.listviewanimations.appearance.simple.AlphaInAnimationAdapter; import com.nhaarman.listviewanimations.itemmanipulation.DynamicListView; import com.nhaarman.listviewanimations.itemmanipulation.dragdrop.OnItemMovedListener; import com.nhaarman.listviewanimations.itemmanipulation.dragdrop.TouchViewDraggableManager; import com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.OnDismissCallback; import com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.SimpleSwipeUndoAdapter; import com.nhaarman.listviewanimations.itemmanipulation.swipedismiss.undo.UndoAdapter; -import com.nhaarman.listviewanimations.appearance.simple.AlphaInAnimationAdapter; import java.util.Arrays; diff --git a/example/src/main/java/com/haarman/listviewanimations/util/BitmapCache.java b/example/src/main/java/com/haarman/listviewanimations/util/BitmapCache.java index fc47282a..e1733483 100644 --- a/example/src/main/java/com/haarman/listviewanimations/util/BitmapCache.java +++ b/example/src/main/java/com/haarman/listviewanimations/util/BitmapCache.java @@ -17,7 +17,7 @@ package com.haarman.listviewanimations.util; import android.graphics.Bitmap; -import android.util.LruCache; +import android.support.v4.util.LruCache; public class BitmapCache extends LruCache { diff --git a/example/src/main/res/layout/activity_examples_itemmanipulations.xml b/example/src/main/res/layout/activity_examples_itemmanipulations.xml index ea70263e..44ec00f2 100644 --- a/example/src/main/res/layout/activity_examples_itemmanipulations.xml +++ b/example/src/main/res/layout/activity_examples_itemmanipulations.xml @@ -35,7 +35,7 @@ android:layout_width="match_parent" android:layout_height="250dp" android:layout_marginBottom="4dp" - android:foreground="?android:attr/selectableItemBackground" + android:foreground="?attr/selectableItemBackground" android:onClick="onDynamicListViewClicked"> - - - - diff --git a/gradle.properties b/gradle.properties index f94b7adc..7628791d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,7 +18,7 @@ nexusUsername=DUMMY nexusPassword=DUMMY isRelease=false -VERSION_NAME=3.1.0 +VERSION_NAME=3.1.1 GROUP=com.nhaarman.listviewanimations POM_DESCRIPTION=ListViewAnimations library diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 37e9a177..5641c8de 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip diff --git a/lib-core-slh/.classpath b/lib-core-slh/.classpath deleted file mode 100644 index 3d27b6d6..00000000 --- a/lib-core-slh/.classpath +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib-core-slh/.project b/lib-core-slh/.project deleted file mode 100644 index c71d5ef1..00000000 --- a/lib-core-slh/.project +++ /dev/null @@ -1,39 +0,0 @@ - - - ListViewAnimations (StickyListHeaders Library) - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/lib-core-slh/build.gradle b/lib-core-slh/build.gradle index 3619c8f7..15960e8a 100644 --- a/lib-core-slh/build.gradle +++ b/lib-core-slh/build.gradle @@ -22,7 +22,7 @@ apply from: '../generateJavadoc.gradle' apply from: '../publishGhPages.gradle' dependencies { - provided 'com.android.support:support-annotations:20.0.0' + provided 'com.android.support:support-annotations:21.0.0' compile project(':lib-core') @@ -37,15 +37,12 @@ dependencies { } android { - compileSdkVersion 20 - buildToolsVersion '20.0.0' + compileSdkVersion 21 + buildToolsVersion '21.1' defaultConfig { minSdkVersion 8 - //noinspection OldTargetApi - targetSdkVersion 20 - versionName project.VERSION_NAME - versionCode Integer.parseInt(new Date().format('yyyyMMddHH')) + targetSdkVersion 21 } compileOptions { diff --git a/lib-core-slh/pom.xml b/lib-core-slh/pom.xml index e9ddc5a7..58ac6ee1 100644 --- a/lib-core-slh/pom.xml +++ b/lib-core-slh/pom.xml @@ -21,7 +21,7 @@ com.nhaarman.listviewanimations parent - 3.0.0-SNAPSHOT + 3.1.1-SNAPSHOT lib-core-slh @@ -36,6 +36,10 @@ android provided + + com.android.support + support-annotations + diff --git a/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/appearance/StickyListHeadersAdapterDecorator.java b/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/appearance/StickyListHeadersAdapterDecorator.java index 3cde47f5..a25dbfec 100644 --- a/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/appearance/StickyListHeadersAdapterDecorator.java +++ b/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/appearance/StickyListHeadersAdapterDecorator.java @@ -101,7 +101,7 @@ public void setListViewWrapper(@NonNull final ListViewWrapper listViewWrapper) { @Override public View getHeaderView(final int position, final View convertView, final ViewGroup parent) { if (getListViewWrapper() == null) { - throw new IllegalStateException("Call setStickyListHeadersListView() on this AnimationAdapter first!"); + throw new IllegalStateException("Call setStickyListHeadersListView() or setListViewWrapper() on this AnimationAdapter first!"); } if (convertView != null) { diff --git a/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/util/StickyListHeadersListViewWrapper.java b/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/util/StickyListHeadersListViewWrapper.java index a450885c..3d607611 100644 --- a/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/util/StickyListHeadersListViewWrapper.java +++ b/lib-core-slh/src/main/java/com/nhaarman/listviewanimations/util/StickyListHeadersListViewWrapper.java @@ -22,6 +22,7 @@ import android.widget.ListAdapter; import se.emilsjolander.stickylistheaders.StickyListHeadersListView; +import se.emilsjolander.stickylistheaders.WrapperView; public class StickyListHeadersListViewWrapper implements ListViewWrapper { @@ -41,7 +42,7 @@ public StickyListHeadersListView getListView() { @Nullable @Override public View getChildAt(final int index) { - return mListView.getListChildAt(index); + return unwrapItemView(mListView.getListChildAt(index)); } @Override @@ -61,7 +62,7 @@ public int getCount() { @Override public int getChildCount() { - return mListView.getChildCount(); + return mListView.getListChildCount(); } @Override @@ -84,4 +85,18 @@ public ListAdapter getAdapter() { public void smoothScrollBy(final int distance, final int duration) { mListView.smoothScrollBy(distance, duration); } + + /** + * Retrieves the original View that is now possibly wrapped in a WrapperView. + * + * @param view The View to retrieve the original View from. + * + * @return The original View. + */ + private View unwrapItemView(final View view) { + if (view instanceof WrapperView) { + return ((WrapperView) view).getItem(); + } + return view; + } } diff --git a/lib-core/.classpath b/lib-core/.classpath deleted file mode 100644 index 3d27b6d6..00000000 --- a/lib-core/.classpath +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib-core/.project b/lib-core/.project deleted file mode 100644 index 9473be01..00000000 --- a/lib-core/.project +++ /dev/null @@ -1,39 +0,0 @@ - - - ListViewAnimations (Core Library) - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/lib-core/build.gradle b/lib-core/build.gradle index 898d72c6..b823505b 100644 --- a/lib-core/build.gradle +++ b/lib-core/build.gradle @@ -22,7 +22,7 @@ apply from: '../generateJavadoc.gradle' apply from: '../publishGhPages.gradle' dependencies { - provided 'com.android.support:support-annotations:20.0.0' + provided 'com.android.support:support-annotations:21.0.0' compile 'com.nineoldandroids:library:2.4.0' @@ -35,15 +35,12 @@ dependencies { } android { - compileSdkVersion 20 - buildToolsVersion '20.0.0' + compileSdkVersion 21 + buildToolsVersion '21.1' defaultConfig { minSdkVersion 8 - //noinspection OldTargetApi - targetSdkVersion 20 - versionName project.VERSION_NAME - versionCode Integer.parseInt(new Date().format('yyyyMMddHH')) + targetSdkVersion 21 } compileOptions { diff --git a/lib-core/pom.xml b/lib-core/pom.xml index e69aa70a..9d97b8d6 100644 --- a/lib-core/pom.xml +++ b/lib-core/pom.xml @@ -21,7 +21,7 @@ com.nhaarman.listviewanimations parent - 3.0.0-SNAPSHOT + 3.1.1-SNAPSHOT lib-core diff --git a/lib-core/src/main/java/com/nhaarman/listviewanimations/appearance/AnimationAdapter.java b/lib-core/src/main/java/com/nhaarman/listviewanimations/appearance/AnimationAdapter.java index 26641d26..3f2cdd53 100644 --- a/lib-core/src/main/java/com/nhaarman/listviewanimations/appearance/AnimationAdapter.java +++ b/lib-core/src/main/java/com/nhaarman/listviewanimations/appearance/AnimationAdapter.java @@ -130,7 +130,7 @@ public ViewAnimator getViewAnimator() { public final View getView(final int position, @Nullable final View convertView, @NonNull final ViewGroup parent) { if (mIsRootAdapter) { if (getListViewWrapper() == null) { - throw new IllegalStateException("Call setAbsListView() on this AnimationAdapter first!"); + throw new IllegalStateException("Call setAbsListView() or setListViewWrapper() on this AnimationAdapter first!"); } assert mViewAnimator != null; diff --git a/lib-manipulation/build.gradle b/lib-manipulation/build.gradle index ca29ace3..e1a8056d 100644 --- a/lib-manipulation/build.gradle +++ b/lib-manipulation/build.gradle @@ -22,7 +22,7 @@ apply from: '../generateJavadoc.gradle' apply from: '../publishGhPages.gradle' dependencies { - provided 'com.android.support:support-annotations:20.0.0' + provided 'com.android.support:support-annotations:21.0.0' compile project(':lib-core') @@ -35,15 +35,12 @@ dependencies { } android { - compileSdkVersion 20 - buildToolsVersion '20.0.0' + compileSdkVersion 21 + buildToolsVersion '21.1' defaultConfig { minSdkVersion 8 - //noinspection OldTargetApi - targetSdkVersion 20 - versionName project.VERSION_NAME - versionCode Integer.parseInt(new Date().format('yyyyMMddHH')) + targetSdkVersion 21 } compileOptions { diff --git a/lib-manipulation/pom.xml b/lib-manipulation/pom.xml index 311a9c0e..39bd577d 100644 --- a/lib-manipulation/pom.xml +++ b/lib-manipulation/pom.xml @@ -21,7 +21,7 @@ com.nhaarman.listviewanimations parent - 3.0.0-SNAPSHOT + 3.1.1-SNAPSHOT lib-manipulation @@ -36,6 +36,10 @@ android provided + + com.android.support + support-annotations + diff --git a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DynamicListViewDragAndDropTest.java b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DynamicListViewDragAndDropTest.java index 6f85dc94..6caadbd6 100644 --- a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DynamicListViewDragAndDropTest.java +++ b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DynamicListViewDragAndDropTest.java @@ -50,7 +50,7 @@ public void setUp() throws Exception, InterruptedException { mDynamicListView.setOnItemMovedListener(mOnItemMovedListener); getInstrumentation().waitForIdleSync(); - Thread.sleep(5000); + Thread.sleep(200); } public void testOnItemMovedListenerCalled() throws InterruptedException { diff --git a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/MotionEventUtils.java b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/MotionEventUtils.java index e778d511..c8a98f06 100644 --- a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/MotionEventUtils.java +++ b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/MotionEventUtils.java @@ -16,21 +16,19 @@ package com.nhaarman.listviewanimations.itemmanipulation.dragdrop; -import android.annotation.TargetApi; import android.app.Instrumentation; import android.os.SystemClock; import android.view.MotionEvent; import android.view.View; import android.widget.AbsListView; - import com.nhaarman.listviewanimations.itemmanipulation.DynamicListView; +import com.nineoldandroids.view.ViewHelper; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -@TargetApi(14) public class MotionEventUtils { private MotionEventUtils() { @@ -42,10 +40,10 @@ public static void dispatchDragMotionEvents(final Instrumentation instrumentatio dynamicListView.getLocationOnScreen(location); View view = dynamicListView.getChildAt(fromPosition); - float fromY = (int) (view.getY() + view.getHeight() / 2) + location[1]; + float fromY = (int) (ViewHelper.getY(view) + view.getHeight() / 2) + location[1]; View toView = dynamicListView.getChildAt(toPosition); - float toY = (int) toView.getY() + location[1]; + float toY = (int) ViewHelper.getY(toView) + location[1]; toY += fromPosition < toPosition ? toView.getHeight() : 0; @@ -59,27 +57,27 @@ public static void dispatchDragScrollDownMotionEvents(final Instrumentation inst dynamicListView.getLocationOnScreen(location); View view = dynamicListView.getChildAt(fromPosition); - float fromY = (int) (view.getY()) + location[1]; + float fromY = (int) (ViewHelper.getY(view)) + location[1]; View toView = dynamicListView.getChildAt(dynamicListView.getLastVisiblePosition()); - float toY = (int) (toView.getY() + toView.getHeight()) + location[1] + 2; + float toY = (int) (ViewHelper.getY(toView) + toView.getHeight()) + location[1] + 2; List motionEvents = createMotionEvents(dynamicListView, fromY, toY); MotionEvent upEvent = motionEvents.remove(motionEvents.size() - 1); dispatchMotionEvents(instrumentation, motionEvents, true); - Thread.sleep(10000); + Thread.sleep(2000); dispatchMotionEvents(instrumentation, Arrays.asList(upEvent), true); } public static List createMotionEvents(final AbsListView absListView, final float fromY, final float toY) { - int x = (int) (absListView.getX() + absListView.getWidth() / 2); + int x = (int) (ViewHelper.getX(absListView) + absListView.getWidth() / 2); List results = new ArrayList<>(); results.add(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, fromY, 0)); - float diff = (toY - fromY) / 25; + float diff = (toY - fromY) / 40; float y = fromY; - for (int i = 0; i < 25; i++) { + for (int i = 0; i < 40; i++) { y += diff; results.add(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, x, y, 0)); } @@ -103,12 +101,12 @@ public static void dispatchMotionEvents(final Instrumentation instrumentation, f } } } while (i < 3 && !success); - Thread.sleep(100); + Thread.sleep(30); } if (wait) { - /* We need to wait for the fling animation to complete */ - Thread.sleep(1500); + /* We need to wait for the swipe animation to complete */ + Thread.sleep(750); } } diff --git a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/MotionEventUtils.java b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/MotionEventUtils.java index b6f6c368..eb8f1552 100644 --- a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/MotionEventUtils.java +++ b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/MotionEventUtils.java @@ -78,8 +78,8 @@ public static List createMotionEvents(final AbsListView absListView results.add(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, fromX, y, 0)); float diff = fromX - toX; - for (int i = 1; i < 10; i++) { - float x = fromX + diff / 10 * i; + for (int i = 1; i < 40; i++) { + float x = fromX + diff / 40 * i; results.add(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, x, y, 0)); } results.add(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, toX, y, 0)); @@ -99,12 +99,12 @@ public static void dispatchMotionEvents(final Instrumentation instrumentation, f i++; } } while (i < 3 && !success); - Thread.sleep(100); + Thread.sleep(30); } if (wait) { - /* We need to wait for the fling animation to complete */ - Thread.sleep(1500); + /* We need to wait for the swipe animation to complete */ + Thread.sleep(750); } } diff --git a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListenerTest.java b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListenerTest.java index c7947250..75210d34 100644 --- a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListenerTest.java +++ b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListenerTest.java @@ -102,13 +102,13 @@ public void testComplexDismiss() throws InterruptedException { /** - * Tests whether calling SwipeTouchListener#fling triggers a call to OnDismissCallback#onDismiss. + * Tests whether calling SwipeTouchListener#swipe triggers a call to OnDismissCallback#onDismiss. */ public void testFling() throws InterruptedException { mActivity.runOnUiThread(new Runnable() { @Override public void run() { - mSwipeTouchListener.fling(0); + mSwipeTouchListener.swipe(0); } }); diff --git a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListenerTest.java b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListenerTest.java index 8e314085..a21e3bbc 100644 --- a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListenerTest.java +++ b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListenerTest.java @@ -132,7 +132,7 @@ public void testReverseShortSwipe() throws InterruptedException { } /** - * Tests whether calling SwipeTouchListener#fling(int) triggers a call to SwipeTouchListener#afterViewFling. + * Tests whether calling SwipeTouchListener#swipe(int) triggers a call to SwipeTouchListener#afterViewFling. */ public void testFling() throws InterruptedException { mActivity.runOnUiThread( @@ -140,7 +140,7 @@ public void testFling() throws InterruptedException { @Override public void run() { - mSwipeTouchListener.fling(0); + mSwipeTouchListener.swipe(0); } } ); diff --git a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListenerTest.java b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListenerTest.java index 10d03d55..91c70ce9 100644 --- a/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListenerTest.java +++ b/lib-manipulation/src/androidTest/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListenerTest.java @@ -146,7 +146,7 @@ public void testLastItemDismissable_itemsDismissed() throws InterruptedException int lastPosition = mAbsListView.getAdapter().getCount() - 1; mAbsListView.smoothScrollToPosition(lastPosition); - Thread.sleep(15000); // Wait for the smooth scroll to settle; + Thread.sleep(3000); // Wait for the smooth scroll to settle; dispatchSwipeMotionEventsAndWait(getInstrumentation(), mAbsListView, lastPosition); // Swipe to show undo dispatchSwipeMotionEventsAndWait(getInstrumentation(), mAbsListView, lastPosition); // Swipe to dismiss @@ -167,11 +167,11 @@ public void testLastItemDismissable_itemUndone() throws InterruptedException { int lastPosition = mAbsListView.getAdapter().getCount() - 1; mAbsListView.smoothScrollToPosition(lastPosition); - Thread.sleep(5000); // Wait for the smooth scroll to settle; + Thread.sleep(3000); // Wait for the smooth scroll to settle; dispatchSwipeMotionEventsAndWait(getInstrumentation(), mAbsListView, lastPosition); // Swipe to show undo mAbsListView.smoothScrollToPosition(lastPosition); - Thread.sleep(5000); + Thread.sleep(3000); dispatchSwipeMotionEventsAndWait(getInstrumentation(), mAbsListView, lastPosition); // Swipe to dismiss /* Then I should be notified of dismissing the last item. */ diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/DynamicListView.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/DynamicListView.java index df75e694..2ea5ed9a 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/DynamicListView.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/DynamicListView.java @@ -126,16 +126,8 @@ public void setOnScrollListener(final OnScrollListener onScrollListener) { /** * Enables the drag and drop functionality for this {@code DynamicListView}. - *

- * NOTE: This method can only be called on devices running ICS (14) and above, otherwise an exception will be thrown. - * - * @throws java.lang.UnsupportedOperationException if the device uses an older API than 14. */ public void enableDragAndDrop() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { - throw new UnsupportedOperationException("Drag and drop is only supported API levels 14 and up!"); - } - mDragAndDropHandler = new DragAndDropHandler(this); } @@ -324,7 +316,7 @@ public int computeVerticalScrollRange() { return super.computeVerticalScrollRange(); } - /* Proxy methods below */ + /* Delegated methods below */ /** * Inserts an item at given index. Will show an entrance animation for the new item if the newly added item is visible. @@ -460,16 +452,16 @@ public void setDismissableManager(@Nullable final DismissableManager dismissable } /** - * Flings the {@link android.view.View} corresponding to given position out of sight. + * Swipes the {@link android.view.View} corresponding to given position out of sight. * Calling this method has the same effect as manually swiping an item off the screen. *

* This method does nothing if no swipe functionality is enabled. * * @param position the position of the item in the {@link android.widget.ListAdapter}. Must be visible. */ - public void fling(final int position) { + public void swipe(final int position) { if (mSwipeTouchListener != null) { - mSwipeTouchListener.fling(position); + mSwipeTouchListener.swipe(position); } } @@ -555,7 +547,7 @@ public void onScrollStateChanged(final AbsListView view, final int scrollState) if (scrollState == SCROLL_STATE_TOUCH_SCROLL) { if (mSwipeTouchListener instanceof SwipeUndoTouchListener) { - ((SwipeUndoTouchListener) mSwipeTouchListener).dimissPending(); + ((SwipeUndoTouchListener) mSwipeTouchListener).dismissPending(); } } } diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DragAndDropHandler.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DragAndDropHandler.java index 26c231ba..74c1cf5f 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DragAndDropHandler.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/dragdrop/DragAndDropHandler.java @@ -1,9 +1,5 @@ package com.nhaarman.listviewanimations.itemmanipulation.dragdrop; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.annotation.TargetApi; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Rect; @@ -24,6 +20,11 @@ import com.nhaarman.listviewanimations.itemmanipulation.DynamicListView; import com.nhaarman.listviewanimations.itemmanipulation.TouchEventHandler; import com.nhaarman.listviewanimations.util.Swappable; +import com.nineoldandroids.animation.Animator; +import com.nineoldandroids.animation.AnimatorListenerAdapter; +import com.nineoldandroids.animation.ValueAnimator; +import com.nineoldandroids.view.ViewHelper; +import com.nineoldandroids.view.ViewPropertyAnimator; /** * A class which handles drag and drop functionality for listview implementations backed up by a @@ -32,7 +33,6 @@ *

* Users of this class must call {@link #onTouchEvent(android.view.MotionEvent)} and {@link #dispatchDraw(android.graphics.Canvas)} on the right moments. */ -@TargetApi(14) public class DragAndDropHandler implements TouchEventHandler { private static final int INVALID_ID = -1; @@ -108,12 +108,12 @@ public class DragAndDropHandler implements TouchEventHandler { private OnItemMovedListener mOnItemMovedListener; /** - * The raw x coordinate of the down event. + * The x coordinate of the down event. */ private float mDownX; /** - * The raw y coordinate of the down event. + * The y coordinate of the down event. */ private float mDownY; @@ -148,11 +148,7 @@ public DragAndDropHandler(@NonNull final DragAndDropListViewWrapper dragAndDropL mDraggableManager = new DefaultDraggableManager(); - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) { - mSwitchViewAnimator = new KitKatSwitchViewAnimator(); - } else { - mSwitchViewAnimator = new LSwitchViewAnimator(); - } + mSwitchViewAnimator = new DragSwitchViewAnimator(); mMobileItemId = INVALID_ID; @@ -227,10 +223,12 @@ public void startDragging(final int position) { } - mMobileView = mWrapper.getChildAt(position - mWrapper.getFirstVisiblePosition() + mWrapper.getHeaderViewsCount()); + long itemId = mAdapter.getItemId(position); + mMobileView = getViewForId(itemId); + if (mMobileView != null) { mOriginalMobileItemPosition = position; - mMobileItemId = mAdapter.getItemId(position); + mMobileItemId = itemId; mHoverDrawable = new HoverDrawable(mMobileView, mLastMotionEventY); mMobileView.setVisibility(View.INVISIBLE); } @@ -304,13 +302,13 @@ public boolean onTouchEvent(@NonNull final MotionEvent event) { * @return {@code true} if we have started dragging, {@code false} otherwise. */ private boolean handleDownEvent(@NonNull final MotionEvent event) { - mDownX = event.getRawX(); - mDownY = event.getRawY(); + mDownX = event.getX(); + mDownY = event.getY(); return true; } /** - * Retrieves the position in the list corresponding to itemId. + * Retrieves the position in the list corresponding to itemId, subtracting any header views. * * @return the position of the item in the list, or {@link android.widget.AdapterView#INVALID_POSITION} if the {@code View} corresponding to the id was not found. */ @@ -319,7 +317,7 @@ private int getPositionForId(final long itemId) { if (v == null) { return AdapterView.INVALID_POSITION; } else { - return mWrapper.getPositionForView(v); + return mWrapper.getPositionForView(v) - mWrapper.getHeaderViewsCount(); } } @@ -362,15 +360,16 @@ private View getViewForId(final long itemId) { private boolean handleMoveEvent(@NonNull final MotionEvent event) { boolean handled = false; - float deltaX = event.getRawX() - mDownX; - float deltaY = event.getRawY() - mDownY; + float deltaX = event.getX() - mDownX; + float deltaY = event.getY() - mDownY; if (mHoverDrawable == null && Math.abs(deltaY) > mSlop && Math.abs(deltaY) > Math.abs(deltaX)) { - int position = mWrapper.pointToPosition((int) event.getX(), (int) event.getY()); + int position = mWrapper.pointToPosition((int) mDownX, (int) mDownY); if (position != AdapterView.INVALID_POSITION) { View downView = mWrapper.getChildAt(position - mWrapper.getFirstVisiblePosition()); assert downView != null; - if (mDraggableManager.isDraggable(downView, position - mWrapper.getHeaderViewsCount(), event.getX() - downView.getX(), event.getY() - downView.getY())) { + + if (mDraggableManager.isDraggable(downView, position - mWrapper.getHeaderViewsCount(), mDownX - ViewHelper.getX(downView), mDownY - ViewHelper.getY(downView))) { startDragging(position - mWrapper.getHeaderViewsCount()); handled = true; } @@ -395,21 +394,21 @@ private void switchIfNecessary() { } int position = getPositionForId(mMobileItemId); - long aboveItemId = position - 1 - mWrapper.getHeaderViewsCount() >= 0 ? mAdapter.getItemId(position - 1 - mWrapper.getHeaderViewsCount()) : INVALID_ID; - long belowItemId = position + 1 - mWrapper.getHeaderViewsCount() < mAdapter.getCount() - ? mAdapter.getItemId(position + 1 - mWrapper.getHeaderViewsCount()) - : INVALID_ID; + int aboveItemPosition = position - 1 >= 0 ? position - 1 : AdapterView.INVALID_POSITION; + int belowItemPosition = position + 1 < mAdapter.getCount() ? position + 1 : AdapterView.INVALID_POSITION; + final int switchPosition = mHoverDrawable.isMovingUpwards() ? aboveItemPosition : belowItemPosition; - final long switchId = mHoverDrawable.isMovingUpwards() ? aboveItemId : belowItemId; - View switchView = getViewForId(switchId); + if (switchPosition >= 0 && switchPosition < mAdapter.getCount()) { + final long switchId = mAdapter.getItemId(switchPosition); + View switchView = getViewForId(switchId); - final int deltaY = mHoverDrawable.getDeltaY(); - if (switchView != null && Math.abs(deltaY) > mHoverDrawable.getIntrinsicHeight()) { - switchViews(switchView, switchId, mHoverDrawable.getIntrinsicHeight() * (deltaY < 0 ? -1 : 1)); + final int deltaY = mHoverDrawable.getDeltaY(); + if (switchView != null && Math.abs(deltaY) > mHoverDrawable.getIntrinsicHeight()) { + switchViews(switchView, switchId, mHoverDrawable.getIntrinsicHeight() * (deltaY < 0 ? -1 : 1)); + } } mScrollHandler.handleMobileCellScroll(); - mWrapper.getListView().invalidate(); } @@ -425,16 +424,17 @@ private void switchIfNecessary() { private void switchViews(final View switchView, final long switchId, final float translationY) { assert mHoverDrawable != null; assert mAdapter != null; - assert mMobileView != null; - final int switchViewPosition = mWrapper.getPositionForView(switchView); - int mobileViewPosition = mWrapper.getPositionForView(mMobileView); + int switchViewPosition = getPositionForId(switchId); + int mobileViewPosition = getPositionForId(mMobileItemId); - ((Swappable) mAdapter).swapItems(switchViewPosition - mWrapper.getHeaderViewsCount(), mobileViewPosition - mWrapper.getHeaderViewsCount()); + ((Swappable) mAdapter).swapItems(switchViewPosition, mobileViewPosition); ((BaseAdapter) mAdapter).notifyDataSetChanged(); mHoverDrawable.shift(switchView.getHeight()); - mSwitchViewAnimator.animateSwitchView(switchId, translationY); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { + mSwitchViewAnimator.animateSwitchView(switchId, translationY); + } } /** @@ -451,13 +451,15 @@ private boolean handleUpEvent() { } assert mHoverDrawable != null; - ValueAnimator valueAnimator = ValueAnimator.ofInt(mHoverDrawable.getTop(), (int) mMobileView.getY()); + refreshMobileView(); + + ValueAnimator valueAnimator = ValueAnimator.ofInt(mHoverDrawable.getTop(), (int) ViewHelper.getY(mMobileView)); SettleHoverDrawableAnimatorListener listener = new SettleHoverDrawableAnimatorListener(mHoverDrawable, mMobileView); valueAnimator.addUpdateListener(listener); valueAnimator.addListener(listener); valueAnimator.start(); - int newPosition = getPositionForId(mMobileItemId) - mWrapper.getHeaderViewsCount(); + int newPosition = getPositionForId(mMobileItemId); if (mOriginalMobileItemPosition != newPosition && mOnItemMovedListener != null) { mOnItemMovedListener.onItemMoved(mOriginalMobileItemPosition, newPosition); } @@ -465,6 +467,22 @@ private boolean handleUpEvent() { return true; } + /** + * Refresh mMobileView from mMobileItemId since views may be shuffled because of ListView implementation. + */ + private void refreshMobileView() { + if (mMobileView != null) { + View view = getViewForId(mMobileItemId); + if (view != null) { + if (!mMobileView.equals(view)) { + mMobileView.setVisibility(View.VISIBLE); + } + mMobileView = view; + mMobileView.setVisibility(View.INVISIBLE); + } + } + } + /** * Handles the cancel event. * @@ -503,57 +521,9 @@ public boolean isDraggable(@NonNull final View view, final int position, final f } /** - * A {@link SwitchViewAnimator} for versions KitKat and below. - * This class immediately updates {@link #mMobileView} to be the newly mobile view. - */ - private class KitKatSwitchViewAnimator implements SwitchViewAnimator { - - @Override - public void animateSwitchView(final long switchId, final float translationY) { - assert mMobileView != null; - mWrapper.getListView().getViewTreeObserver().addOnPreDrawListener(new AnimateSwitchViewOnPreDrawListener(mMobileView, switchId, translationY)); - mMobileView = getViewForId(mMobileItemId); - } - - private class AnimateSwitchViewOnPreDrawListener implements ViewTreeObserver.OnPreDrawListener { - - private final View mPreviousMobileView; - - private final long mSwitchId; - - private final float mTranslationY; - - AnimateSwitchViewOnPreDrawListener(final View previousMobileView, final long switchId, final float translationY) { - mPreviousMobileView = previousMobileView; - mSwitchId = switchId; - mTranslationY = translationY; - } - - @Override - public boolean onPreDraw() { - mWrapper.getListView().getViewTreeObserver().removeOnPreDrawListener(this); - - View switchView = getViewForId(mSwitchId); - if (switchView != null) { - switchView.setTranslationY(mTranslationY); - switchView.animate().translationY(0).start(); - } - - mPreviousMobileView.setVisibility(View.VISIBLE); - - if (mMobileView != null) { - mMobileView.setVisibility(View.INVISIBLE); - } - return true; - } - } - } - - /** - * A {@link SwitchViewAnimator} for versions L and above. - * This class updates {@link #mMobileView} only after the next frame has been drawn. + * A {@link SwitchViewAnimator}. */ - private class LSwitchViewAnimator implements SwitchViewAnimator { + private class DragSwitchViewAnimator implements SwitchViewAnimator { @Override public void animateSwitchView(final long switchId, final float translationY) { @@ -577,21 +547,15 @@ public boolean onPreDraw() { View switchView = getViewForId(mSwitchId); if (switchView != null) { - switchView.setTranslationY(mTranslationY); - switchView.animate().translationY(0).start(); + ViewHelper.setTranslationY(switchView, mTranslationY); + ViewPropertyAnimator.animate(switchView).translationY(0).start(); } - assert mMobileView != null; - mMobileView.setVisibility(View.VISIBLE); - mMobileView = getViewForId(mMobileItemId); - assert mMobileView != null; - mMobileView.setVisibility(View.INVISIBLE); return true; } } } - /** * A class which handles scrolling for this {@code DynamicListView} when dragging an item. *

@@ -680,9 +644,8 @@ public void onScroll(@NonNull final AbsListView view, final int firstVisibleItem mPreviousLastVisibleItem = mPreviousLastVisibleItem == -1 ? mCurrentLastVisibleItem : mPreviousLastVisibleItem; if (mHoverDrawable != null) { - assert mMobileView != null; - float y = mMobileView.getY(); - mHoverDrawable.onScroll(y); + refreshMobileView(); + mHoverDrawable.onScroll(ViewHelper.getY(mMobileView)); } if (!mIsSettlingHoverDrawable) { @@ -710,15 +673,20 @@ private void checkAndHandleFirstVisibleCellChange() { return; } - int position = getPositionForId(mMobileItemId); - if (position == AdapterView.INVALID_POSITION) { + int mobilePosition = getPositionForId(mMobileItemId); + if (mobilePosition == AdapterView.INVALID_POSITION) { + return; + } + + int switchItemPosition = mobilePosition - 1; + if (switchItemPosition < mCurrentFirstVisibleItem) { return; } - long switchItemId = position - 1 - mWrapper.getHeaderViewsCount() >= 0 ? mAdapter.getItemId(position - 1 - mWrapper.getHeaderViewsCount()) : INVALID_ID; - View switchView = getViewForId(switchItemId); - if (switchView != null) { - switchViews(switchView, switchItemId, -switchView.getHeight()); + long switchItemId = mAdapter.getItemId(switchItemPosition); + View switchItemView = getViewForId(switchItemId); + if (switchItemView != null) { + switchViews(switchItemView, switchItemId, -switchItemView.getHeight()); } } @@ -731,17 +699,20 @@ private void checkAndHandleLastVisibleCellChange() { return; } - int position = getPositionForId(mMobileItemId); - if (position == AdapterView.INVALID_POSITION) { + int mobilePosition = getPositionForId(mMobileItemId); + if (mobilePosition == AdapterView.INVALID_POSITION) { + return; + } + + int switchItemPosition = mobilePosition + 1; + if (switchItemPosition > mCurrentLastVisibleItem) { return; } - long switchItemId = position + 1 - mWrapper.getHeaderViewsCount() < mAdapter.getCount() - ? mAdapter.getItemId(position + 1 - mWrapper.getHeaderViewsCount()) - : INVALID_ID; - View switchView = getViewForId(switchItemId); - if (switchView != null) { - switchViews(switchView, switchItemId, switchView.getHeight()); + long switchItemId = mAdapter.getItemId(switchItemPosition); + View switchItemView = getViewForId(switchItemId); + if (switchItemView != null) { + switchViews(switchItemView, switchItemId, switchItemView.getHeight()); } } } diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/expandablelistitem/ExpandableListItemAdapter.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/expandablelistitem/ExpandableListItemAdapter.java index fb0e6542..4d266221 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/expandablelistitem/ExpandableListItemAdapter.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/expandablelistitem/ExpandableListItemAdapter.java @@ -22,10 +22,12 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; +import android.widget.AbsListView; import android.widget.FrameLayout; import android.widget.LinearLayout; import com.nhaarman.listviewanimations.ArrayAdapter; +import com.nhaarman.listviewanimations.util.AbsListViewWrapper; import com.nhaarman.listviewanimations.util.AdapterViewUtil; import com.nhaarman.listviewanimations.util.ListViewWrapper; import com.nhaarman.listviewanimations.util.ListViewWrapperSetter; @@ -110,6 +112,11 @@ protected ExpandableListItemAdapter(@NonNull final Context context, final int la mExpandedIds = new ArrayList<>(); } + public void setAbsListView(@NonNull final AbsListView absListView) { + setListViewWrapper(new AbsListViewWrapper(absListView)); + } + + @SuppressWarnings("NullableProblems") @Override public void setListViewWrapper(@NonNull final ListViewWrapper listViewWrapper) { @@ -401,7 +408,7 @@ private View getContentParent(final int position) { @Nullable private View findViewForPosition(final int position) { if (mListViewWrapper == null) { - throw new IllegalStateException("Call setAbsListView on this ExpanableListItemAdapter!"); + throw new IllegalStateException("Call setAbsListView or setListViewWrapper on this ExpanableListItemAdapter!"); } View result = null; diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissAdapter.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissAdapter.java index 5649f06b..577786ff 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissAdapter.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissAdapter.java @@ -79,7 +79,7 @@ public void setListViewWrapper(@NonNull final ListViewWrapper listViewWrapper) { */ public void setDismissableManager(@Nullable final DismissableManager dismissableManager) { if (mDismissTouchListener == null) { - throw new IllegalStateException("You must call setAbsListView() first."); + throw new IllegalStateException("You must call setAbsListView() or setListViewWrapper() first."); } mDismissTouchListener.setDismissableManager(dismissableManager); } diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListener.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListener.java index 022d9e6a..0f731852 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListener.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeDismissTouchListener.java @@ -83,23 +83,13 @@ public SwipeDismissTouchListener(@NonNull final ListViewWrapper listViewWrapper, mDismissAnimationTime = listViewWrapper.getListView().getContext().getResources().getInteger(android.R.integer.config_shortAnimTime); } - /** - * Dismisses the {@link android.view.View} corresponding to given position. - * Calling this method has the same effect as manually swiping an item off the screen. - * - * @param position the position of the item in the {@link android.widget.ListAdapter}. Must be visible. - */ - public void dismiss(final int position) { - fling(position); - } - @Override - public void fling(final int position) { + public void swipe(final int position) { int firstVisiblePosition = getListViewWrapper().getFirstVisiblePosition(); int lastVisiblePosition = getListViewWrapper().getLastVisiblePosition(); if (firstVisiblePosition <= position && position <= lastVisiblePosition) { - super.fling(position); + super.swipe(position); } else if (position > lastVisiblePosition) { directDismiss(position); } else { diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListener.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListener.java index 7fff7767..58410647 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListener.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/SwipeTouchListener.java @@ -261,7 +261,7 @@ public void disableSwipe() { * * @param position the position of the item in the {@link android.widget.ListAdapter}. Must be visible. */ - public void fling(final int position) { + public void swipe(final int position) { int firstVisiblePosition = mListViewWrapper.getFirstVisiblePosition(); int lastVisiblePosition = mListViewWrapper.getLastVisiblePosition(); if (position < firstVisiblePosition || position > lastVisiblePosition) { @@ -278,6 +278,26 @@ public void fling(final int position) { mVirtualListCount--; } + /** + * Dismisses the {@link android.view.View} corresponding to given position from the list. + * This will not first fling the item sideways, but immediately does the remove animation. + * + * @param position The position of the item in the {@link android.widget.ListAdapter}. Must be visible. + */ + public void dismiss(final int position) { + int firstVisiblePosition = mListViewWrapper.getFirstVisiblePosition(); + int lastVisiblePosition = mListViewWrapper.getLastVisiblePosition(); + if (position < firstVisiblePosition || position > lastVisiblePosition) { + throw new IllegalArgumentException("View for position " + position + " not visible!"); + } + + View downView = AdapterViewUtil.getViewForPosition(mListViewWrapper, position); + if (downView == null) { + throw new IllegalStateException("No view found for position " + position); + } + afterViewFling(downView, position); + } + @Override public boolean isInteracting() { return mSwiping; diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SimpleSwipeUndoAdapter.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SimpleSwipeUndoAdapter.java index 836295db..49597042 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SimpleSwipeUndoAdapter.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SimpleSwipeUndoAdapter.java @@ -108,6 +108,10 @@ public View getView(final int position, @Nullable final View convertView, @NonNu @Override @NonNull public View getPrimaryView(@NonNull final View view) { + if(!(view instanceof SwipeUndoView)){ + throw new IllegalArgumentException("Swiped view is not an instance of SwipeUndoView. Did you disable swiping of the header and footer using DismissableManager?"); + } + View primaryView = ((SwipeUndoView) view).getPrimaryView(); if (primaryView == null) { throw new IllegalStateException("primaryView == null"); @@ -118,6 +122,10 @@ public View getPrimaryView(@NonNull final View view) { @Override @NonNull public View getUndoView(@NonNull final View view) { + if(!(view instanceof SwipeUndoView)){ + throw new IllegalArgumentException("Swiped view is not an instance of SwipeUndoView. Did you disable swiping of the header and footer using DismissableManager?"); + } + View undoView = ((SwipeUndoView) view).getUndoView(); if (undoView == null) { throw new IllegalStateException("undoView == null"); diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoAdapter.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoAdapter.java index 482ade3c..12320070 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoAdapter.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoAdapter.java @@ -71,7 +71,7 @@ public void setListViewWrapper(@NonNull final ListViewWrapper listViewWrapper) { */ public void setDismissableManager(@Nullable final DismissableManager dismissableManager) { if (mSwipeUndoTouchListener == null) { - throw new IllegalStateException("You must call setAbsListView() first."); + throw new IllegalStateException("You must call setAbsListView() or setListViewWrapper() first."); } mSwipeUndoTouchListener.setDismissableManager(dismissableManager); } @@ -84,7 +84,7 @@ public void setSwipeUndoTouchListener(@NonNull final SwipeUndoTouchListener swip @Override public View getView(final int position, @Nullable final View convertView, @NonNull final ViewGroup parent) { if (getListViewWrapper() == null) { - throw new IllegalArgumentException("Call setAbsListView() on this SwipeUndoAdapter before setAdapter()!"); + throw new IllegalArgumentException("Call setAbsListView() or setListViewWrapper() on this SwipeUndoAdapter before setAdapter()!"); } return super.getView(position, convertView, parent); } diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListener.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListener.java index 628a9e6f..78a6e179 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListener.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoTouchListener.java @@ -125,7 +125,7 @@ public boolean hasPendingItems() { /** * Dismisses all items that are in the undo state. */ - public void dimissPending() { + public void dismissPending() { for (int position : mUndoPositions) { performDismiss(mUndoViews.get(position), position); } diff --git a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoView.java b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoView.java index aef72e30..fe555f36 100644 --- a/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoView.java +++ b/lib-manipulation/src/main/java/com/nhaarman/listviewanimations/itemmanipulation/swipedismiss/undo/SwipeUndoView.java @@ -83,4 +83,12 @@ View getPrimaryView() { View getUndoView() { return mUndoView; } + + @Override + public void setVisibility(final int visibility) { + if(mPrimaryView != null) { + mPrimaryView.setVisibility(visibility); + } + super.setVisibility(visibility); + } } diff --git a/pom.xml b/pom.xml index 61950b56..015ceed6 100644 --- a/pom.xml +++ b/pom.xml @@ -33,7 +33,7 @@ An Android library which allows developers to easily add animations to ListView items https://github.com/nhaarman/ListViewAnimations 2013 - 3.0.0-SNAPSHOT + 3.1.1-SNAPSHOT lib-core @@ -69,6 +69,10 @@ https://github.com/nhaarman/ListViewAnimations/issues + + 3.1.1 + + UTF-8 @@ -77,8 +81,9 @@ 19 - 4.4.2_r3 - 19.1.0 + 4.4.2_r4 + 21.0.1 + 21.0.0 2.4.0 4.11 1.9.5 @@ -86,11 +91,11 @@ 3.9.0-rc.2 - 1.7 + 1.9 2.3.2 - 3.0 - 2.9 - 2.2.1 + 3.1 + 2.10.1 + 2.4 1.4 1.3.2 @@ -111,7 +116,8 @@ com.android.support support-annotations - ${android-support.version} + ${android-support-annotation.version} + provided jar @@ -126,7 +132,7 @@ se.emilsjolander stickylistheaders - 2.4.0 + 2.5.0 aar