From 251e575421dd808083605d391deddf83987c27a0 Mon Sep 17 00:00:00 2001 From: Max Pop <maxence.gr@hotmail.fr> Date: Mon, 21 Sep 2020 12:17:55 +0200 Subject: [PATCH] Resign all with gpg key --- core/pulltorefresh/build.gradle | 8 - core/pulltorefresh/lint-baseline.xml | 326 ---- .../src/main/AndroidManifest.xml | 6 - .../pulltorefresh/library/ILoadingLayout.java | 57 - .../pulltorefresh/library/IPullToRefresh.java | 246 --- .../library/LoadingLayoutProxy.java | 73 - .../library/OverscrollHelper.java | 178 -- .../library/PullToRefreshAdapterViewBase.java | 475 ----- .../library/PullToRefreshBase.java | 1653 ----------------- .../PullToRefreshExpandableListView.java | 103 - .../library/PullToRefreshGridView.java | 102 - .../PullToRefreshHorizontalScrollView.java | 110 -- .../library/PullToRefreshListView.java | 337 ---- .../library/PullToRefreshScrollView.java | 109 -- .../library/PullToRefreshWebView.java | 164 -- .../library/extras/PullToRefreshWebView2.java | 132 -- .../extras/SoundPullEventListener.java | 96 - .../internal/EmptyViewMethodAccessor.java | 43 - .../library/internal/FlipLoadingLayout.java | 146 -- .../library/internal/IndicatorLayout.java | 147 -- .../library/internal/LoadingLayout.java | 393 ---- .../library/internal/RotateLoadingLayout.java | 110 -- .../pulltorefresh/library/internal/Utils.java | 13 - .../library/internal/ViewCompat.java | 70 - .../main/res/anim/slide_in_from_bottom.xml | 21 - .../src/main/res/anim/slide_in_from_top.xml | 21 - .../src/main/res/anim/slide_out_to_bottom.xml | 21 - .../src/main/res/anim/slide_out_to_top.xml | 21 - .../res/drawable-hdpi/default_ptr_flip.png | Bin 1835 -> 0 bytes .../res/drawable-hdpi/default_ptr_rotate.png | Bin 48963 -> 0 bytes .../res/drawable-hdpi/indicator_arrow.png | Bin 390 -> 0 bytes .../res/drawable-mdpi/default_ptr_flip.png | Bin 1612 -> 0 bytes .../res/drawable-mdpi/default_ptr_rotate.png | Bin 49665 -> 0 bytes .../res/drawable-mdpi/indicator_arrow.png | Bin 445 -> 0 bytes .../res/drawable-xhdpi/default_ptr_flip.png | Bin 1983 -> 0 bytes .../res/drawable-xhdpi/default_ptr_rotate.png | Bin 50019 -> 0 bytes .../res/drawable-xhdpi/indicator_arrow.png | Bin 429 -> 0 bytes .../main/res/drawable/indicator_bg_bottom.xml | 18 - .../main/res/drawable/indicator_bg_top.xml | 18 - .../pull_to_refresh_header_horizontal.xml | 29 - .../pull_to_refresh_header_vertical.xml | 59 - .../res/values-ar/pull_refresh_strings.xml | 6 - .../res/values-cs/pull_refresh_strings.xml | 6 - .../res/values-de/pull_refresh_strings.xml | 6 - .../res/values-es/pull_refresh_strings.xml | 6 - .../res/values-fi/pull_refresh_strings.xml | 13 - .../res/values-fr/pull_refresh_strings.xml | 6 - .../res/values-he/pull_refresh_strings.xml | 6 - .../res/values-it/pull_refresh_strings.xml | 6 - .../res/values-iw/pull_refresh_strings.xml | 6 - .../res/values-ja/pull_refresh_strings.xml | 6 - .../res/values-ko/pull_refresh_strings.xml | 6 - .../res/values-nl/pull_refresh_strings.xml | 6 - .../res/values-pl/pull_refresh_strings.xml | 6 - .../values-pt-rBR/pull_refresh_strings.xml | 6 - .../res/values-pt/pull_refresh_strings.xml | 6 - .../res/values-ro/pull_refresh_strings.xml | 6 - .../res/values-ru/pull_refresh_strings.xml | 6 - .../res/values-zh/pull_refresh_strings.xml | 6 - .../src/main/res/values/attrs.xml | 80 - .../src/main/res/values/dimens.xml | 10 - .../pulltorefresh/src/main/res/values/ids.xml | 8 - .../main/res/values/pull_refresh_strings.xml | 13 - settings.gradle | 1 - ultrasonic/build.gradle | 1 - ultrasonic/src/main/assets/html/fr/index.html | 2 +- .../ultrasonic/activity/BookmarkActivity.java | 16 +- .../ultrasonic/activity/ChatActivity.java | 54 +- .../activity/SelectAlbumActivity.java | 46 +- .../activity/SelectArtistActivity.java | 18 +- .../activity/SelectGenreActivity.java | 18 +- .../activity/SelectPlaylistActivity.java | 15 +- .../ultrasonic/activity/ShareActivity.java | 17 +- .../drawable-hdpi/ic_menu_refresh_dark.png | Bin 0 -> 498 bytes .../drawable-hdpi/ic_menu_refresh_light.png | Bin 0 -> 492 bytes .../drawable-mdpi/ic_menu_refresh_dark.png | Bin 0 -> 412 bytes .../drawable-mdpi/ic_menu_refresh_light.png | Bin 0 -> 391 bytes .../drawable-xhdpi/ic_menu_refresh_dark.png | Bin 0 -> 712 bytes .../drawable-xhdpi/ic_menu_refresh_light.png | Bin 0 -> 698 bytes .../drawable-xxhdpi/ic_menu_refresh_dark.png | Bin 0 -> 1017 bytes .../drawable-xxhdpi/ic_menu_refresh_light.png | Bin 0 -> 1002 bytes .../drawable-xxxhdpi/ic_menu_refresh_dark.png | Bin 0 -> 1277 bytes .../ic_menu_refresh_light.png | Bin 0 -> 1277 bytes ultrasonic/src/main/res/layout/chat.xml | 24 +- .../src/main/res/layout/select_album.xml | 22 +- .../src/main/res/layout/select_artist.xml | 22 +- .../src/main/res/layout/select_genre.xml | 22 +- .../src/main/res/layout/select_playlist.xml | 22 +- .../src/main/res/layout/select_share.xml | 29 +- ultrasonic/src/main/res/menu/chat.xml | 9 + ultrasonic/src/main/res/values-de/strings.xml | 1 + ultrasonic/src/main/res/values-es/strings.xml | 1 + ultrasonic/src/main/res/values-fr/strings.xml | 1 + ultrasonic/src/main/res/values-hu/strings.xml | 1 + ultrasonic/src/main/res/values-nl/strings.xml | 1 + ultrasonic/src/main/res/values-pl/strings.xml | 1 + .../src/main/res/values-pt-rBR/strings.xml | 1 + ultrasonic/src/main/res/values-pt/strings.xml | 1 + ultrasonic/src/main/res/values/strings.xml | 1 + ultrasonic/src/main/res/values/styles.xml | 1 + ultrasonic/src/main/res/values/themes.xml | 2 + 101 files changed, 185 insertions(+), 5696 deletions(-) delete mode 100644 core/pulltorefresh/build.gradle delete mode 100644 core/pulltorefresh/lint-baseline.xml delete mode 100644 core/pulltorefresh/src/main/AndroidManifest.xml delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/ILoadingLayout.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/IPullToRefresh.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/LoadingLayoutProxy.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/OverscrollHelper.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshAdapterViewBase.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshBase.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshExpandableListView.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshGridView.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshHorizontalScrollView.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshListView.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshScrollView.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshWebView.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/SoundPullEventListener.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/EmptyViewMethodAccessor.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/FlipLoadingLayout.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/IndicatorLayout.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/LoadingLayout.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/Utils.java delete mode 100644 core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java delete mode 100644 core/pulltorefresh/src/main/res/anim/slide_in_from_bottom.xml delete mode 100644 core/pulltorefresh/src/main/res/anim/slide_in_from_top.xml delete mode 100644 core/pulltorefresh/src/main/res/anim/slide_out_to_bottom.xml delete mode 100644 core/pulltorefresh/src/main/res/anim/slide_out_to_top.xml delete mode 100644 core/pulltorefresh/src/main/res/drawable-hdpi/default_ptr_flip.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-hdpi/default_ptr_rotate.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-hdpi/indicator_arrow.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-mdpi/default_ptr_flip.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-mdpi/default_ptr_rotate.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-mdpi/indicator_arrow.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-xhdpi/default_ptr_flip.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-xhdpi/default_ptr_rotate.png delete mode 100644 core/pulltorefresh/src/main/res/drawable-xhdpi/indicator_arrow.png delete mode 100644 core/pulltorefresh/src/main/res/drawable/indicator_bg_bottom.xml delete mode 100644 core/pulltorefresh/src/main/res/drawable/indicator_bg_top.xml delete mode 100644 core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_horizontal.xml delete mode 100644 core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_vertical.xml delete mode 100644 core/pulltorefresh/src/main/res/values-ar/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-cs/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-de/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-es/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-fi/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-fr/pull_refresh_strings.xml delete mode 100644 core/pulltorefresh/src/main/res/values-he/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-it/pull_refresh_strings.xml delete mode 100644 core/pulltorefresh/src/main/res/values-iw/pull_refresh_strings.xml delete mode 100644 core/pulltorefresh/src/main/res/values-ja/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-ko/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-nl/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-pl/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-pt-rBR/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-pt/pull_refresh_strings.xml delete mode 100644 core/pulltorefresh/src/main/res/values-ro/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-ru/pull_refresh_strings.xml delete mode 100755 core/pulltorefresh/src/main/res/values-zh/pull_refresh_strings.xml delete mode 100644 core/pulltorefresh/src/main/res/values/attrs.xml delete mode 100644 core/pulltorefresh/src/main/res/values/dimens.xml delete mode 100644 core/pulltorefresh/src/main/res/values/ids.xml delete mode 100755 core/pulltorefresh/src/main/res/values/pull_refresh_strings.xml create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_menu_refresh_dark.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_menu_refresh_light.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_menu_refresh_dark.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_menu_refresh_light.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_menu_refresh_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_menu_refresh_light.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_menu_refresh_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_menu_refresh_light.png create mode 100644 ultrasonic/src/main/res/drawable-xxxhdpi/ic_menu_refresh_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xxxhdpi/ic_menu_refresh_light.png create mode 100644 ultrasonic/src/main/res/menu/chat.xml diff --git a/core/pulltorefresh/build.gradle b/core/pulltorefresh/build.gradle deleted file mode 100644 index 102c5711..00000000 --- a/core/pulltorefresh/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -apply from: bootstrap.androidModule - -android { - lintOptions { - baselineFile file("lint-baseline.xml") - abortOnError true - } -} diff --git a/core/pulltorefresh/lint-baseline.xml b/core/pulltorefresh/lint-baseline.xml deleted file mode 100644 index 771b65e4..00000000 --- a/core/pulltorefresh/lint-baseline.xml +++ /dev/null @@ -1,326 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<issues format="4" by="lint 2.3.3"> - - <issue - id="LocaleFolder" - message="The locale folder "`he`" should be called "`iw`" instead; see the `java.util.Locale` documentation"> - <location - file="src/main/res/values-he"/> - </issue> - - <issue - id="OldTargetApi" - message="Not targeting the latest versions of Android; compatibility modes apply. Consider testing and updating this version. Consult the `android.os.Build.VERSION_CODES` javadoc for details." - errorLine1=" <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="16" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/AndroidManifest.xml" - line="7" - column="41"/> - </issue> - - <issue - id="GradleOverrides" - message="This `minSdkVersion` value (`4`) is not used; it is always overridden by the value specified in the Gradle build script (`14`)" - errorLine1=" <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="16" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/AndroidManifest.xml" - line="7" - column="15"/> - </issue> - - <issue - id="GradleOverrides" - message="This `targetSdkVersion` value (`16`) is not used; it is always overridden by the value specified in the Gradle build script (`22`)" - errorLine1=" <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="16" />" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/AndroidManifest.xml" - line="7" - column="41"/> - </issue> - - <issue - id="Deprecated" - message="`android:singleLine` is deprecated: Use `maxLines="1"` instead" - errorLine1=" android:singleLine="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/layout/pull_to_refresh_header_vertical.xml" - line="45" - column="17"/> - </issue> - - <issue - id="Deprecated" - message="`android:singleLine` is deprecated: Use `maxLines="1"` instead" - errorLine1=" android:singleLine="true"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/layout/pull_to_refresh_header_vertical.xml" - line="53" - column="17"/> - </issue> - - <issue - id="MissingTranslation" - message=""`pull_to_refresh_from_bottom_pull_label`" is not translated in "es" (Spanish), "fr" (French), "pt" (Portuguese), "pt-BR" (Portuguese: Brazil)" - errorLine1=" <string name="pull_to_refresh_from_bottom_pull_label">@string/pull_to_refresh_pull_label</string>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/values/pull_refresh_strings.xml" - line="9" - column="13"/> - </issue> - - <issue - id="MissingTranslation" - message=""`pull_to_refresh_from_bottom_release_label`" is not translated in "es" (Spanish), "fr" (French), "pt" (Portuguese), "pt-BR" (Portuguese: Brazil)" - errorLine1=" <string name="pull_to_refresh_from_bottom_release_label">@string/pull_to_refresh_release_label</string>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/values/pull_refresh_strings.xml" - line="10" - column="13"/> - </issue> - - <issue - id="MissingTranslation" - message=""`pull_to_refresh_from_bottom_refreshing_label`" is not translated in "es" (Spanish), "fr" (French), "pt" (Portuguese), "pt-BR" (Portuguese: Brazil)" - errorLine1=" <string name="pull_to_refresh_from_bottom_refreshing_label">@string/pull_to_refresh_refreshing_label</string>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/values/pull_refresh_strings.xml" - line="11" - column="13"/> - </issue> - - <issue - id="AddJavascriptInterface" - message="`WebView.addJavascriptInterface` should not be called with minSdkVersion < 17 for security reasons: JavaScript can use reflection to manipulate application" - errorLine1=" webView.addJavascriptInterface(mJsCallback, JS_INTERFACE_PKG);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java" - line="90" - column="11"/> - </issue> - - <issue - id="JavascriptInterface" - message="None of the methods in the added interface (JsValueCallback) have been annotated with `@android.webkit.JavascriptInterface`; they will not be visible in API 17" - errorLine1=" webView.addJavascriptInterface(mJsCallback, JS_INTERFACE_PKG);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java" - line="90" - column="11"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" return VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD && mOverScrollEnabled" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshBase.java" - line="211" - column="10"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshExpandableListView.java" - line="54" - column="7"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshGridView.java" - line="54" - column="7"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshHorizontalScrollView.java" - line="53" - column="7"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshListView.java" - line="207" - column="7"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshScrollView.java" - line="52" - column="7"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshWebView.java" - line="98" - column="7"/> - </issue> - - <issue - id="ObsoleteSdkInt" - message="Unnecessary; SDK_INT is always >= 14" - errorLine1=" if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java" - line="44" - column="7"/> - </issue> - - <issue - id="FloatMath" - message="Use `java.lang.Math#floor` instead of `android.util.FloatMath#floor()` since it is faster as of API 8" - errorLine1=" float exactContentHeight = FloatMath.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale());" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshWebView.java" - line="115" - column="30"/> - </issue> - - <issue - id="FloatMath" - message="Use `java.lang.Math#floor` instead of `android.util.FloatMath#floor()` since it is faster as of API 8" - errorLine1=" return (int) Math.max(0, FloatMath.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale())" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshWebView.java" - line="161" - column="29"/> - </issue> - - <issue - id="IconMissingDensityFolder" - message="Missing density variation folders in `src/main/res`: drawable-xxhdpi"> - <location - file="src/main/res"/> - </issue> - - <issue - id="ViewConstructor" - message="Custom view `RotateLoadingLayout` is missing constructor used by tools: `(Context)` or `(Context,AttributeSet)` or `(Context,AttributeSet,int)`" - errorLine1="public class RotateLoadingLayout extends LoadingLayout {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java" - line="30" - column="14"/> - </issue> - - <issue - id="ContentDescription" - message="[Accessibility] Missing `contentDescription` attribute on image" - errorLine1=" <ImageView" - errorLine2=" ^"> - <location - file="src/main/res/layout/pull_to_refresh_header_horizontal.xml" - line="13" - column="9"/> - </issue> - - <issue - id="ContentDescription" - message="[Accessibility] Missing `contentDescription` attribute on image" - errorLine1=" <ImageView" - errorLine2=" ^"> - <location - file="src/main/res/layout/pull_to_refresh_header_vertical.xml" - line="18" - column="13"/> - </issue> - - <issue - id="RtlHardcoded" - message="Use "`Gravity.START`" instead of "`Gravity.LEFT`" to ensure correct behavior in right-to-left locales" - errorLine1=" lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.TOP : Gravity.LEFT;" - errorLine2=" ~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/internal/LoadingLayout.java" - line="92" - column="82"/> - </issue> - - <issue - id="RtlHardcoded" - message="Use "`Gravity.END`" instead of "`Gravity.RIGHT`" to ensure correct behavior in right-to-left locales" - errorLine1=" lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.BOTTOM : Gravity.RIGHT;" - errorLine2=" ~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/internal/LoadingLayout.java" - line="102" - column="85"/> - </issue> - - <issue - id="RtlHardcoded" - message="Use "`Gravity.END`" instead of "`Gravity.RIGHT`" to ensure correct behavior in right-to-left locales" - errorLine1=" params.gravity = Gravity.TOP | Gravity.RIGHT;" - errorLine2=" ~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshAdapterViewBase.java" - line="344" - column="43"/> - </issue> - - <issue - id="RtlHardcoded" - message="Use "`Gravity.END`" instead of "`Gravity.RIGHT`" to ensure correct behavior in right-to-left locales" - errorLine1=" params.gravity = Gravity.BOTTOM | Gravity.RIGHT;" - errorLine2=" ~~~~~"> - <location - file="src/main/java/com/handmark/pulltorefresh/library/PullToRefreshAdapterViewBase.java" - line="359" - column="46"/> - </issue> - - <issue - id="RtlHardcoded" - message="Use "`start`" instead of "`left`" to ensure correct behavior in right-to-left locales" - errorLine1=" android:layout_gravity="left|center_vertical" >" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="src/main/res/layout/pull_to_refresh_header_vertical.xml" - line="16" - column="37"/> - </issue> - -</issues> diff --git a/core/pulltorefresh/src/main/AndroidManifest.xml b/core/pulltorefresh/src/main/AndroidManifest.xml deleted file mode 100644 index 2dc1eb5f..00000000 --- a/core/pulltorefresh/src/main/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.handmark.pulltorefresh.library" - android:versionCode="2110" - android:versionName="2.1.1"> -</manifest> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/ILoadingLayout.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/ILoadingLayout.java deleted file mode 100644 index ff2a9572..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/ILoadingLayout.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.handmark.pulltorefresh.library; - -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; - -public interface ILoadingLayout { - - /** - * Set the Last Updated Text. This displayed under the main label when - * Pulling - * - * @param label - Label to set - */ - public void setLastUpdatedLabel(CharSequence label); - - /** - * Set the drawable used in the loading layout. This is the same as calling - * <code>setLoadingDrawable(drawable, Mode.BOTH)</code> - * - * @param drawable - Drawable to display - */ - public void setLoadingDrawable(Drawable drawable); - - /** - * Set Text to show when the Widget is being Pulled - * <code>setPullLabel(releaseLabel, Mode.BOTH)</code> - * - * @param pullLabel - CharSequence to display - */ - public void setPullLabel(CharSequence pullLabel); - - /** - * Set Text to show when the Widget is refreshing - * <code>setRefreshingLabel(releaseLabel, Mode.BOTH)</code> - * - * @param refreshingLabel - CharSequence to display - */ - public void setRefreshingLabel(CharSequence refreshingLabel); - - /** - * Set Text to show when the Widget is being pulled, and will refresh when - * released. This is the same as calling - * <code>setReleaseLabel(releaseLabel, Mode.BOTH)</code> - * - * @param releaseLabel - CharSequence to display - */ - public void setReleaseLabel(CharSequence releaseLabel); - - /** - * Set's the Sets the typeface and style in which the text should be - * displayed. Please see - * {@link android.widget.TextView#setTypeface(Typeface) - * TextView#setTypeface(Typeface)}. - */ - public void setTextTypeface(Typeface tf); - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/IPullToRefresh.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/IPullToRefresh.java deleted file mode 100644 index a06cdd7c..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/IPullToRefresh.java +++ /dev/null @@ -1,246 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.view.View; -import android.view.animation.Interpolator; - -import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnPullEventListener; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener2; -import com.handmark.pulltorefresh.library.PullToRefreshBase.State; - -public interface IPullToRefresh<T extends View> { - - /** - * Demos the Pull-to-Refresh functionality to the user so that they are - * aware it is there. This could be useful when the user first opens your - * app, etc. The animation will only happen if the Refresh View (ListView, - * ScrollView, etc) is in a state where a Pull-to-Refresh could occur by a - * user's touch gesture (i.e. scrolled to the top/bottom). - * - * @return true - if the Demo has been started, false if not. - */ - public boolean demo(); - - /** - * Get the mode that this view is currently in. This is only really useful - * when using <code>Mode.BOTH</code>. - * - * @return Mode that the view is currently in - */ - public Mode getCurrentMode(); - - /** - * Returns whether the Touch Events are filtered or not. If true is - * returned, then the View will only use touch events where the difference - * in the Y-axis is greater than the difference in the X-axis. This means - * that the View will not interfere when it is used in a horizontal - * scrolling View (such as a ViewPager). - * - * @return boolean - true if the View is filtering Touch Events - */ - public boolean getFilterTouchEvents(); - - /** - * Returns a proxy object which allows you to call methods on all of the - * LoadingLayouts (the Views which show when Pulling/Refreshing). - * <p /> - * You should not keep the result of this method any longer than you need - * it. - * - * @return Object which will proxy any calls you make on it, to all of the - * LoadingLayouts. - */ - public ILoadingLayout getLoadingLayoutProxy(); - - /** - * Returns a proxy object which allows you to call methods on the - * LoadingLayouts (the Views which show when Pulling/Refreshing). The actual - * LoadingLayout(s) which will be affected, are chosen by the parameters you - * give. - * <p /> - * You should not keep the result of this method any longer than you need - * it. - * - * @param includeStart - Whether to include the Start/Header Views - * @param includeEnd - Whether to include the End/Footer Views - * @return Object which will proxy any calls you make on it, to the - * LoadingLayouts included. - */ - public ILoadingLayout getLoadingLayoutProxy(boolean includeStart, boolean includeEnd); - - /** - * Get the mode that this view has been set to. If this returns - * <code>Mode.BOTH</code>, you can use <code>getCurrentMode()</code> to - * check which mode the view is currently in - * - * @return Mode that the view has been set to - */ - public Mode getMode(); - - /** - * Get the Wrapped Refreshable View. Anything returned here has already been - * added to the content view. - * - * @return The View which is currently wrapped - */ - public T getRefreshableView(); - - /** - * Get whether the 'Refreshing' View should be automatically shown when - * refreshing. Returns true by default. - * - * @return - true if the Refreshing View will be show - */ - public boolean getShowViewWhileRefreshing(); - - /** - * @return - The state that the View is currently in. - */ - public State getState(); - - /** - * Whether Pull-to-Refresh is enabled - * - * @return enabled - */ - public boolean isPullToRefreshEnabled(); - - /** - * Gets whether Overscroll support is enabled. This is different to - * Android's standard Overscroll support (the edge-glow) which is available - * from GINGERBREAD onwards - * - * @return true - if both PullToRefresh-OverScroll and Android's inbuilt - * OverScroll are enabled - */ - public boolean isPullToRefreshOverScrollEnabled(); - - /** - * Returns whether the Widget is currently in the Refreshing mState - * - * @return true if the Widget is currently refreshing - */ - public boolean isRefreshing(); - - /** - * Returns whether the widget has enabled scrolling on the Refreshable View - * while refreshing. - * - * @return true if the widget has enabled scrolling while refreshing - */ - public boolean isScrollingWhileRefreshingEnabled(); - - /** - * Mark the current Refresh as complete. Will Reset the UI and hide the - * Refreshing View - */ - public void onRefreshComplete(); - - /** - * Set the Touch Events to be filtered or not. If set to true, then the View - * will only use touch events where the difference in the Y-axis is greater - * than the difference in the X-axis. This means that the View will not - * interfere when it is used in a horizontal scrolling View (such as a - * ViewPager), but will restrict which types of finger scrolls will trigger - * the View. - * - * @param filterEvents - true if you want to filter Touch Events. Default is - * true. - */ - public void setFilterTouchEvents(boolean filterEvents); - - /** - * Set the mode of Pull-to-Refresh that this view will use. - * - * @param mode - Mode to set the View to - */ - public void setMode(Mode mode); - - /** - * Set OnPullEventListener for the Widget - * - * @param listener - Listener to be used when the Widget has a pull event to - * propogate. - */ - public void setOnPullEventListener(OnPullEventListener<T> listener); - - /** - * Set OnRefreshListener for the Widget - * - * @param listener - Listener to be used when the Widget is set to Refresh - */ - public void setOnRefreshListener(OnRefreshListener<T> listener); - - /** - * Set OnRefreshListener for the Widget - * - * @param listener - Listener to be used when the Widget is set to Refresh - */ - public void setOnRefreshListener(OnRefreshListener2<T> listener); - - /** - * Sets whether Overscroll support is enabled. This is different to - * Android's standard Overscroll support (the edge-glow). This setting only - * takes effect when running on device with Android v2.3 or greater. - * - * @param enabled - true if you want Overscroll enabled - */ - public void setPullToRefreshOverScrollEnabled(boolean enabled); - - /** - * Sets the Widget to be in the refresh state. The UI will be updated to - * show the 'Refreshing' view, and be scrolled to show such. - */ - public void setRefreshing(); - - /** - * Sets the Widget to be in the refresh state. The UI will be updated to - * show the 'Refreshing' view. - * - * @param doScroll - true if you want to force a scroll to the Refreshing - * view. - */ - public void setRefreshing(boolean doScroll); - - /** - * Sets the Animation Interpolator that is used for animated scrolling. - * Defaults to a DecelerateInterpolator - * - * @param interpolator - Interpolator to use - */ - public void setScrollAnimationInterpolator(Interpolator interpolator); - - /** - * By default the Widget disables scrolling on the Refreshable View while - * refreshing. This method can change this behaviour. - * - * @param scrollingWhileRefreshingEnabled - true if you want to enable - * scrolling while refreshing - */ - public void setScrollingWhileRefreshingEnabled(boolean scrollingWhileRefreshingEnabled); - - /** - * A mutator to enable/disable whether the 'Refreshing' View should be - * automatically shown when refreshing. - * - * @param showView - */ - public void setShowViewWhileRefreshing(boolean showView); - -} \ No newline at end of file diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/LoadingLayoutProxy.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/LoadingLayoutProxy.java deleted file mode 100644 index 5f76645d..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/LoadingLayoutProxy.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.handmark.pulltorefresh.library; - -import java.util.HashSet; - -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; - -import com.handmark.pulltorefresh.library.internal.LoadingLayout; - -public class LoadingLayoutProxy implements ILoadingLayout { - - private final HashSet<LoadingLayout> mLoadingLayouts; - - LoadingLayoutProxy() { - mLoadingLayouts = new HashSet<LoadingLayout>(); - } - - /** - * This allows you to add extra LoadingLayout instances to this proxy. This - * is only necessary if you keep your own instances, and want to have them - * included in any - * {@link PullToRefreshBase#createLoadingLayoutProxy(boolean, boolean) - * createLoadingLayoutProxy(...)} calls. - * - * @param layout - LoadingLayout to have included. - */ - public void addLayout(LoadingLayout layout) { - if (null != layout) { - mLoadingLayouts.add(layout); - } - } - - @Override - public void setLastUpdatedLabel(CharSequence label) { - for (LoadingLayout layout : mLoadingLayouts) { - layout.setLastUpdatedLabel(label); - } - } - - @Override - public void setLoadingDrawable(Drawable drawable) { - for (LoadingLayout layout : mLoadingLayouts) { - layout.setLoadingDrawable(drawable); - } - } - - @Override - public void setRefreshingLabel(CharSequence refreshingLabel) { - for (LoadingLayout layout : mLoadingLayouts) { - layout.setRefreshingLabel(refreshingLabel); - } - } - - @Override - public void setPullLabel(CharSequence label) { - for (LoadingLayout layout : mLoadingLayouts) { - layout.setPullLabel(label); - } - } - - @Override - public void setReleaseLabel(CharSequence label) { - for (LoadingLayout layout : mLoadingLayouts) { - layout.setReleaseLabel(label); - } - } - - public void setTextTypeface(Typeface tf) { - for (LoadingLayout layout : mLoadingLayouts) { - layout.setTextTypeface(tf); - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/OverscrollHelper.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/OverscrollHelper.java deleted file mode 100644 index 52a20de2..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/OverscrollHelper.java +++ /dev/null @@ -1,178 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.annotation.TargetApi; -import android.util.Log; -import android.view.View; - -import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; -import com.handmark.pulltorefresh.library.PullToRefreshBase.State; - -@TargetApi(9) -public final class OverscrollHelper { - - static final String LOG_TAG = "OverscrollHelper"; - static final float DEFAULT_OVERSCROLL_SCALE = 1f; - - /** - * Helper method for Overscrolling that encapsulates all of the necessary - * function. - * <p/> - * This should only be used on AdapterView's such as ListView as it just - * calls through to overScrollBy() with the scrollRange = 0. AdapterView's - * do not have a scroll range (i.e. getScrollY() doesn't work). - * - * @param view - PullToRefreshView that is calling this. - * @param deltaX - Change in X in pixels, passed through from from - * overScrollBy call - * @param scrollX - Current X scroll value in pixels before applying deltaY, - * passed through from from overScrollBy call - * @param deltaY - Change in Y in pixels, passed through from from - * overScrollBy call - * @param scrollY - Current Y scroll value in pixels before applying deltaY, - * passed through from from overScrollBy call - * @param isTouchEvent - true if this scroll operation is the result of a - * touch event, passed through from from overScrollBy call - */ - public static void overScrollBy(final PullToRefreshBase<?> view, final int deltaX, final int scrollX, - final int deltaY, final int scrollY, final boolean isTouchEvent) { - overScrollBy(view, deltaX, scrollX, deltaY, scrollY, 0, isTouchEvent); - } - - /** - * Helper method for Overscrolling that encapsulates all of the necessary - * function. This version of the call is used for Views that need to specify - * a Scroll Range but scroll back to it's edge correctly. - * - * @param view - PullToRefreshView that is calling this. - * @param deltaX - Change in X in pixels, passed through from from - * overScrollBy call - * @param scrollX - Current X scroll value in pixels before applying deltaY, - * passed through from from overScrollBy call - * @param deltaY - Change in Y in pixels, passed through from from - * overScrollBy call - * @param scrollY - Current Y scroll value in pixels before applying deltaY, - * passed through from from overScrollBy call - * @param scrollRange - Scroll Range of the View, specifically needed for - * ScrollView - * @param isTouchEvent - true if this scroll operation is the result of a - * touch event, passed through from from overScrollBy call - */ - public static void overScrollBy(final PullToRefreshBase<?> view, final int deltaX, final int scrollX, - final int deltaY, final int scrollY, final int scrollRange, final boolean isTouchEvent) { - overScrollBy(view, deltaX, scrollX, deltaY, scrollY, scrollRange, 0, DEFAULT_OVERSCROLL_SCALE, isTouchEvent); - } - - /** - * Helper method for Overscrolling that encapsulates all of the necessary - * function. This is the advanced version of the call. - * - * @param view - PullToRefreshView that is calling this. - * @param deltaX - Change in X in pixels, passed through from from - * overScrollBy call - * @param scrollX - Current X scroll value in pixels before applying deltaY, - * passed through from from overScrollBy call - * @param deltaY - Change in Y in pixels, passed through from from - * overScrollBy call - * @param scrollY - Current Y scroll value in pixels before applying deltaY, - * passed through from from overScrollBy call - * @param scrollRange - Scroll Range of the View, specifically needed for - * ScrollView - * @param fuzzyThreshold - Threshold for which the values how fuzzy we - * should treat the other values. Needed for WebView as it - * doesn't always scroll back to it's edge. 0 = no fuzziness. - * @param scaleFactor - Scale Factor for overscroll amount - * @param isTouchEvent - true if this scroll operation is the result of a - * touch event, passed through from from overScrollBy call - */ - public static void overScrollBy(final PullToRefreshBase<?> view, final int deltaX, final int scrollX, - final int deltaY, final int scrollY, final int scrollRange, final int fuzzyThreshold, - final float scaleFactor, final boolean isTouchEvent) { - - final int deltaValue, currentScrollValue, scrollValue; - switch (view.getPullToRefreshScrollDirection()) { - case HORIZONTAL: - deltaValue = deltaX; - scrollValue = scrollX; - currentScrollValue = view.getScrollX(); - break; - case VERTICAL: - default: - deltaValue = deltaY; - scrollValue = scrollY; - currentScrollValue = view.getScrollY(); - break; - } - - // Check that OverScroll is enabled and that we're not currently - // refreshing. - if (view.isPullToRefreshOverScrollEnabled() && !view.isRefreshing()) { - final Mode mode = view.getMode(); - - // Check that Pull-to-Refresh is enabled, and the event isn't from - // touch - if (mode.permitsPullToRefresh() && !isTouchEvent && deltaValue != 0) { - final int newScrollValue = (deltaValue + scrollValue); - - if (PullToRefreshBase.DEBUG) { - Log.d(LOG_TAG, "OverScroll. DeltaX: " + deltaX + ", ScrollX: " + scrollX + ", DeltaY: " + deltaY - + ", ScrollY: " + scrollY + ", NewY: " + newScrollValue + ", ScrollRange: " + scrollRange - + ", CurrentScroll: " + currentScrollValue); - } - - if (newScrollValue < (0 - fuzzyThreshold)) { - // Check the mode supports the overscroll direction, and - // then move scroll - if (mode.showHeaderLoadingLayout()) { - // If we're currently at zero, we're about to start - // overscrolling, so change the state - if (currentScrollValue == 0) { - view.setState(State.OVERSCROLLING); - } - - view.setHeaderScroll((int) (scaleFactor * (currentScrollValue + newScrollValue))); - } - } else if (newScrollValue > (scrollRange + fuzzyThreshold)) { - // Check the mode supports the overscroll direction, and - // then move scroll - if (mode.showFooterLoadingLayout()) { - // If we're currently at zero, we're about to start - // overscrolling, so change the state - if (currentScrollValue == 0) { - view.setState(State.OVERSCROLLING); - } - - view.setHeaderScroll((int) (scaleFactor * (currentScrollValue + newScrollValue - scrollRange))); - } - } else if (Math.abs(newScrollValue) <= fuzzyThreshold - || Math.abs(newScrollValue - scrollRange) <= fuzzyThreshold) { - // Means we've stopped overscrolling, so scroll back to 0 - view.setState(State.RESET); - } - } else if (isTouchEvent && State.OVERSCROLLING == view.getState()) { - // This condition means that we were overscrolling from a fling, - // but the user has touched the View and is now overscrolling - // from touch instead. We need to just reset. - view.setState(State.RESET); - } - } - } - - static boolean isAndroidOverScrollEnabled(View view) { - return view.getOverScrollMode() != View.OVER_SCROLL_NEVER; - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshAdapterViewBase.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshAdapterViewBase.java deleted file mode 100644 index cfff8371..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshAdapterViewBase.java +++ /dev/null @@ -1,475 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Gravity; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewParent; -import android.widget.AbsListView; -import android.widget.AbsListView.OnScrollListener; -import android.widget.Adapter; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.FrameLayout; -import android.widget.LinearLayout; -import android.widget.ListAdapter; - -import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; -import com.handmark.pulltorefresh.library.internal.IndicatorLayout; - -public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extends PullToRefreshBase<T> implements - OnScrollListener { - - private static FrameLayout.LayoutParams convertEmptyViewLayoutParams(ViewGroup.LayoutParams lp) { - FrameLayout.LayoutParams newLp = null; - - if (null != lp) { - newLp = new FrameLayout.LayoutParams(lp); - - if (lp instanceof LinearLayout.LayoutParams) { - newLp.gravity = ((LinearLayout.LayoutParams) lp).gravity; - } else { - newLp.gravity = Gravity.CENTER; - } - } - - return newLp; - } - - private boolean mLastItemVisible; - private OnScrollListener mOnScrollListener; - private OnLastItemVisibleListener mOnLastItemVisibleListener; - private View mEmptyView; - - private IndicatorLayout mIndicatorIvTop; - private IndicatorLayout mIndicatorIvBottom; - - private boolean mShowIndicator; - private boolean mScrollEmptyView = true; - - public PullToRefreshAdapterViewBase(Context context) { - super(context); - mRefreshableView.setOnScrollListener(this); - } - - public PullToRefreshAdapterViewBase(Context context, AttributeSet attrs) { - super(context, attrs); - mRefreshableView.setOnScrollListener(this); - } - - public PullToRefreshAdapterViewBase(Context context, Mode mode) { - super(context, mode); - mRefreshableView.setOnScrollListener(this); - } - - public PullToRefreshAdapterViewBase(Context context, Mode mode, AnimationStyle animStyle) { - super(context, mode, animStyle); - mRefreshableView.setOnScrollListener(this); - } - - /** - * Gets whether an indicator graphic should be displayed when the View is in - * a state where a Pull-to-Refresh can happen. An example of this state is - * when the Adapter View is scrolled to the top and the mode is set to - * {@link Mode#PULL_FROM_START}. The default value is <var>true</var> if - * {@link PullToRefreshBase#isPullToRefreshOverScrollEnabled() - * isPullToRefreshOverScrollEnabled()} returns false. - * - * @return true if the indicators will be shown - */ - public boolean getShowIndicator() { - return mShowIndicator; - } - - public final void onScroll(final AbsListView view, final int firstVisibleItem, final int visibleItemCount, - final int totalItemCount) { - - if (DEBUG) { - Log.d(LOG_TAG, "First Visible: " + firstVisibleItem + ". Visible Count: " + visibleItemCount - + ". Total Items:" + totalItemCount); - } - - /** - * Set whether the Last Item is Visible. lastVisibleItemIndex is a - * zero-based index, so we minus one totalItemCount to check - */ - if (null != mOnLastItemVisibleListener) { - mLastItemVisible = (totalItemCount > 0) && (firstVisibleItem + visibleItemCount >= totalItemCount - 1); - } - - // If we're showing the indicator, check positions... - if (getShowIndicatorInternal()) { - updateIndicatorViewsVisibility(); - } - - // Finally call OnScrollListener if we have one - if (null != mOnScrollListener) { - mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); - } - } - - public final void onScrollStateChanged(final AbsListView view, final int state) { - /** - * Check that the scrolling has stopped, and that the last item is - * visible. - */ - if (state == OnScrollListener.SCROLL_STATE_IDLE && null != mOnLastItemVisibleListener && mLastItemVisible) { - mOnLastItemVisibleListener.onLastItemVisible(); - } - - if (null != mOnScrollListener) { - mOnScrollListener.onScrollStateChanged(view, state); - } - } - - /** - * Pass-through method for {@link PullToRefreshBase#getRefreshableView() - * getRefreshableView()}. - * {@link AdapterView#setAdapter(android.widget.Adapter)} - * setAdapter(adapter)}. This is just for convenience! - * - * @param adapter - Adapter to set - */ - public void setAdapter(ListAdapter adapter) { - ((AdapterView<ListAdapter>) mRefreshableView).setAdapter(adapter); - } - - /** - * Sets the Empty View to be used by the Adapter View. - * <p/> - * We need it handle it ourselves so that we can Pull-to-Refresh when the - * Empty View is shown. - * <p/> - * Please note, you do <strong>not</strong> usually need to call this method - * yourself. Calling setEmptyView on the AdapterView will automatically call - * this method and set everything up. This includes when the Android - * Framework automatically sets the Empty View based on it's ID. - * - * @param newEmptyView - Empty View to be used - */ - public final void setEmptyView(View newEmptyView) { - FrameLayout refreshableViewWrapper = getRefreshableViewWrapper(); - - if (null != newEmptyView) { - // New view needs to be clickable so that Android recognizes it as a - // target for Touch Events - newEmptyView.setClickable(true); - - ViewParent newEmptyViewParent = newEmptyView.getParent(); - if (null != newEmptyViewParent && newEmptyViewParent instanceof ViewGroup) { - ((ViewGroup) newEmptyViewParent).removeView(newEmptyView); - } - - // We need to convert any LayoutParams so that it works in our - // FrameLayout - FrameLayout.LayoutParams lp = convertEmptyViewLayoutParams(newEmptyView.getLayoutParams()); - if (null != lp) { - refreshableViewWrapper.addView(newEmptyView, lp); - } else { - refreshableViewWrapper.addView(newEmptyView); - } - } - - if (mRefreshableView instanceof EmptyViewMethodAccessor) { - ((EmptyViewMethodAccessor) mRefreshableView).setEmptyViewInternal(newEmptyView); - } else { - mRefreshableView.setEmptyView(newEmptyView); - } - mEmptyView = newEmptyView; - } - - /** - * Pass-through method for {@link PullToRefreshBase#getRefreshableView() - * getRefreshableView()}. - * {@link AdapterView#setOnItemClickListener(OnItemClickListener) - * setOnItemClickListener(listener)}. This is just for convenience! - * - * @param listener - OnItemClickListener to use - */ - public void setOnItemClickListener(OnItemClickListener listener) { - mRefreshableView.setOnItemClickListener(listener); - } - - public final void setOnLastItemVisibleListener(OnLastItemVisibleListener listener) { - mOnLastItemVisibleListener = listener; - } - - public final void setOnScrollListener(OnScrollListener listener) { - mOnScrollListener = listener; - } - - public final void setScrollEmptyView(boolean doScroll) { - mScrollEmptyView = doScroll; - } - - /** - * Sets whether an indicator graphic should be displayed when the View is in - * a state where a Pull-to-Refresh can happen. An example of this state is - * when the Adapter View is scrolled to the top and the mode is set to - * {@link Mode#PULL_FROM_START} - * - * @param showIndicator - true if the indicators should be shown. - */ - public void setShowIndicator(boolean showIndicator) { - mShowIndicator = showIndicator; - - if (getShowIndicatorInternal()) { - // If we're set to Show Indicator, add/update them - addIndicatorViews(); - } else { - // If not, then remove then - removeIndicatorViews(); - } - } - - ; - - @Override - protected void onPullToRefresh() { - super.onPullToRefresh(); - - if (getShowIndicatorInternal()) { - switch (getCurrentMode()) { - case PULL_FROM_END: - mIndicatorIvBottom.pullToRefresh(); - break; - case PULL_FROM_START: - mIndicatorIvTop.pullToRefresh(); - break; - default: - // NO-OP - break; - } - } - } - - protected void onRefreshing(boolean doScroll) { - super.onRefreshing(doScroll); - - if (getShowIndicatorInternal()) { - updateIndicatorViewsVisibility(); - } - } - - @Override - protected void onReleaseToRefresh() { - super.onReleaseToRefresh(); - - if (getShowIndicatorInternal()) { - switch (getCurrentMode()) { - case PULL_FROM_END: - mIndicatorIvBottom.releaseToRefresh(); - break; - case PULL_FROM_START: - mIndicatorIvTop.releaseToRefresh(); - break; - default: - // NO-OP - break; - } - } - } - - @Override - protected void onReset() { - super.onReset(); - - if (getShowIndicatorInternal()) { - updateIndicatorViewsVisibility(); - } - } - - @Override - protected void handleStyledAttributes(TypedArray a) { - // Set Show Indicator to the XML value, or default value - mShowIndicator = a.getBoolean(R.styleable.PullToRefresh_ptrShowIndicator, !isPullToRefreshOverScrollEnabled()); - } - - protected boolean isReadyForPullStart() { - return isFirstItemVisible(); - } - - protected boolean isReadyForPullEnd() { - return isLastItemVisible(); - } - - @Override - protected void onScrollChanged(int l, int t, int oldl, int oldt) { - super.onScrollChanged(l, t, oldl, oldt); - if (null != mEmptyView && !mScrollEmptyView) { - mEmptyView.scrollTo(-l, -t); - } - } - - @Override - protected void updateUIForMode() { - super.updateUIForMode(); - - // Check Indicator Views consistent with new Mode - if (getShowIndicatorInternal()) { - addIndicatorViews(); - } else { - removeIndicatorViews(); - } - } - - private void addIndicatorViews() { - Mode mode = getMode(); - FrameLayout refreshableViewWrapper = getRefreshableViewWrapper(); - - if (mode.showHeaderLoadingLayout() && null == mIndicatorIvTop) { - // If the mode can pull down, and we don't have one set already - mIndicatorIvTop = new IndicatorLayout(getContext(), Mode.PULL_FROM_START); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding); - params.gravity = Gravity.TOP | Gravity.RIGHT; - refreshableViewWrapper.addView(mIndicatorIvTop, params); - - } else if (!mode.showHeaderLoadingLayout() && null != mIndicatorIvTop) { - // If we can't pull down, but have a View then remove it - refreshableViewWrapper.removeView(mIndicatorIvTop); - mIndicatorIvTop = null; - } - - if (mode.showFooterLoadingLayout() && null == mIndicatorIvBottom) { - // If the mode can pull down, and we don't have one set already - mIndicatorIvBottom = new IndicatorLayout(getContext(), Mode.PULL_FROM_END); - FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding); - params.gravity = Gravity.BOTTOM | Gravity.RIGHT; - refreshableViewWrapper.addView(mIndicatorIvBottom, params); - - } else if (!mode.showFooterLoadingLayout() && null != mIndicatorIvBottom) { - // If we can't pull down, but have a View then remove it - refreshableViewWrapper.removeView(mIndicatorIvBottom); - mIndicatorIvBottom = null; - } - } - - private boolean getShowIndicatorInternal() { - return mShowIndicator && isPullToRefreshEnabled(); - } - - private boolean isFirstItemVisible() { - final Adapter adapter = mRefreshableView.getAdapter(); - - if (null == adapter || adapter.isEmpty()) { - if (DEBUG) { - Log.d(LOG_TAG, "isFirstItemVisible. Empty View."); - } - return true; - - } else { - - /** - * This check should really just be: - * mRefreshableView.getFirstVisiblePosition() == 0, but PtRListView - * internally use a HeaderView which messes the positions up. For - * now we'll just add one to account for it and rely on the inner - * condition which checks getTop(). - */ - if (mRefreshableView.getFirstVisiblePosition() <= 1) { - final View firstVisibleChild = mRefreshableView.getChildAt(0); - if (firstVisibleChild != null) { - return firstVisibleChild.getTop() >= mRefreshableView.getTop(); - } - } - } - - return false; - } - - private boolean isLastItemVisible() { - final Adapter adapter = mRefreshableView.getAdapter(); - - if (null == adapter || adapter.isEmpty()) { - if (DEBUG) { - Log.d(LOG_TAG, "isLastItemVisible. Empty View."); - } - return true; - } else { - final int lastItemPosition = mRefreshableView.getCount() - 1; - final int lastVisiblePosition = mRefreshableView.getLastVisiblePosition(); - - if (DEBUG) { - Log.d(LOG_TAG, "isLastItemVisible. Last Item Position: " + lastItemPosition + " Last Visible Pos: " - + lastVisiblePosition); - } - - /** - * This check should really just be: lastVisiblePosition == - * lastItemPosition, but PtRListView internally uses a FooterView - * which messes the positions up. For me we'll just subtract one to - * account for it and rely on the inner condition which checks - * getBottom(). - */ - if (lastVisiblePosition >= lastItemPosition - 1) { - final int childIndex = lastVisiblePosition - mRefreshableView.getFirstVisiblePosition(); - final View lastVisibleChild = mRefreshableView.getChildAt(childIndex); - if (lastVisibleChild != null) { - return lastVisibleChild.getBottom() <= mRefreshableView.getBottom(); - } - } - } - - return false; - } - - private void removeIndicatorViews() { - if (null != mIndicatorIvTop) { - getRefreshableViewWrapper().removeView(mIndicatorIvTop); - mIndicatorIvTop = null; - } - - if (null != mIndicatorIvBottom) { - getRefreshableViewWrapper().removeView(mIndicatorIvBottom); - mIndicatorIvBottom = null; - } - } - - private void updateIndicatorViewsVisibility() { - if (null != mIndicatorIvTop) { - if (!isRefreshing() && isReadyForPullStart()) { - if (!mIndicatorIvTop.isVisible()) { - mIndicatorIvTop.show(); - } - } else { - if (mIndicatorIvTop.isVisible()) { - mIndicatorIvTop.hide(); - } - } - } - - if (null != mIndicatorIvBottom) { - if (!isRefreshing() && isReadyForPullEnd()) { - if (!mIndicatorIvBottom.isVisible()) { - mIndicatorIvBottom.show(); - } - } else { - if (mIndicatorIvBottom.isVisible()) { - mIndicatorIvBottom.hide(); - } - } - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshBase.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshBase.java deleted file mode 100644 index e76b234f..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshBase.java +++ /dev/null @@ -1,1653 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.os.Bundle; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.util.Log; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; -import android.widget.FrameLayout; -import android.widget.LinearLayout; - -import com.handmark.pulltorefresh.library.internal.FlipLoadingLayout; -import com.handmark.pulltorefresh.library.internal.LoadingLayout; -import com.handmark.pulltorefresh.library.internal.RotateLoadingLayout; -import com.handmark.pulltorefresh.library.internal.Utils; -import com.handmark.pulltorefresh.library.internal.ViewCompat; - -public abstract class PullToRefreshBase<T extends View> extends LinearLayout implements IPullToRefresh<T> { - - // =========================================================== - // Constants - // =========================================================== - - static final boolean DEBUG = true; - - static final boolean USE_HW_LAYERS = false; - - static final String LOG_TAG = "PullToRefresh"; - - static final float FRICTION = 2.0f; - - public static final int SMOOTH_SCROLL_DURATION_MS = 200; - public static final int SMOOTH_SCROLL_LONG_DURATION_MS = 325; - static final int DEMO_SCROLL_INTERVAL = 225; - - static final String STATE_STATE = "ptr_state"; - static final String STATE_MODE = "ptr_mode"; - static final String STATE_CURRENT_MODE = "ptr_current_mode"; - static final String STATE_SCROLLING_REFRESHING_ENABLED = "ptr_disable_scrolling"; - static final String STATE_SHOW_REFRESHING_VIEW = "ptr_show_refreshing_view"; - static final String STATE_SUPER = "ptr_super"; - - // =========================================================== - // Fields - // =========================================================== - - private int mTouchSlop; - private float mLastMotionX, mLastMotionY; - private float mInitialMotionX, mInitialMotionY; - - private boolean mIsBeingDragged = false; - private State mState = State.RESET; - private Mode mMode = Mode.getDefault(); - - private Mode mCurrentMode; - T mRefreshableView; - private FrameLayout mRefreshableViewWrapper; - - private boolean mShowViewWhileRefreshing = true; - private boolean mScrollingWhileRefreshingEnabled = false; - private boolean mFilterTouchEvents = true; - private boolean mOverScrollEnabled = true; - private boolean mLayoutVisibilityChangesEnabled = true; - - private Interpolator mScrollAnimationInterpolator; - private AnimationStyle mLoadingAnimationStyle = AnimationStyle.getDefault(); - - private LoadingLayout mHeaderLayout; - private LoadingLayout mFooterLayout; - - private OnRefreshListener<T> mOnRefreshListener; - private OnRefreshListener2<T> mOnRefreshListener2; - private OnPullEventListener<T> mOnPullEventListener; - - private SmoothScrollRunnable mCurrentSmoothScrollRunnable; - - // =========================================================== - // Constructors - // =========================================================== - - public PullToRefreshBase(Context context) { - super(context); - init(context, null); - } - - public PullToRefreshBase(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs); - } - - public PullToRefreshBase(Context context, Mode mode) { - super(context); - mMode = mode; - init(context, null); - } - - public PullToRefreshBase(Context context, Mode mode, AnimationStyle animStyle) { - super(context); - mMode = mode; - mLoadingAnimationStyle = animStyle; - init(context, null); - } - - @Override - public void addView(View child, int index, ViewGroup.LayoutParams params) { - if (DEBUG) { - Log.d(LOG_TAG, "addView: " + child.getClass().getSimpleName()); - } - - final T refreshableView = getRefreshableView(); - - if (refreshableView instanceof ViewGroup) { - ((ViewGroup) refreshableView).addView(child, index, params); - } else { - throw new UnsupportedOperationException("Refreshable View is not a ViewGroup so can't addView"); - } - } - - @Override - public final boolean demo() { - if (mMode.showHeaderLoadingLayout() && isReadyForPullStart()) { - smoothScrollToAndBack(-getHeaderSize() * 2); - return true; - } else if (mMode.showFooterLoadingLayout() && isReadyForPullEnd()) { - smoothScrollToAndBack(getFooterSize() * 2); - return true; - } - - return false; - } - - @Override - public final Mode getCurrentMode() { - return mCurrentMode; - } - - @Override - public final boolean getFilterTouchEvents() { - return mFilterTouchEvents; - } - - @Override - public final ILoadingLayout getLoadingLayoutProxy() { - return getLoadingLayoutProxy(true, true); - } - - @Override - public final ILoadingLayout getLoadingLayoutProxy(boolean includeStart, boolean includeEnd) { - return createLoadingLayoutProxy(includeStart, includeEnd); - } - - @Override - public final Mode getMode() { - return mMode; - } - - @Override - public final T getRefreshableView() { - return mRefreshableView; - } - - @Override - public final boolean getShowViewWhileRefreshing() { - return mShowViewWhileRefreshing; - } - - @Override - public final State getState() { - return mState; - } - - /** - * @deprecated See {@link #isScrollingWhileRefreshingEnabled()}. - */ - public final boolean isDisableScrollingWhileRefreshing() { - return !isScrollingWhileRefreshingEnabled(); - } - - @Override - public final boolean isPullToRefreshEnabled() { - return mMode.permitsPullToRefresh(); - } - - @Override - public final boolean isPullToRefreshOverScrollEnabled() { - return VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD && mOverScrollEnabled - && OverscrollHelper.isAndroidOverScrollEnabled(mRefreshableView); - } - - @Override - public final boolean isRefreshing() { - return mState == State.REFRESHING || mState == State.MANUAL_REFRESHING; - } - - @Override - public final boolean isScrollingWhileRefreshingEnabled() { - return mScrollingWhileRefreshingEnabled; - } - - @Override - public final boolean onInterceptTouchEvent(MotionEvent event) { - - if (!isPullToRefreshEnabled()) { - return false; - } - - final int action = event.getAction(); - - if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { - mIsBeingDragged = false; - return false; - } - - if (action != MotionEvent.ACTION_DOWN && mIsBeingDragged) { - return true; - } - - switch (action) { - case MotionEvent.ACTION_MOVE: { - // If we're refreshing, and the flag is set. Eat all MOVE events - if (!mScrollingWhileRefreshingEnabled && isRefreshing()) { - return true; - } - - if (isReadyForPull()) { - final float y = event.getY(), x = event.getX(); - final float diff, oppositeDiff, absDiff; - - // We need to use the correct values, based on scroll - // direction - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - diff = x - mLastMotionX; - oppositeDiff = y - mLastMotionY; - break; - case VERTICAL: - default: - diff = y - mLastMotionY; - oppositeDiff = x - mLastMotionX; - break; - } - absDiff = Math.abs(diff); - - if (absDiff > mTouchSlop && (!mFilterTouchEvents || absDiff > Math.abs(oppositeDiff))) { - if (mMode.showHeaderLoadingLayout() && diff >= 1f && isReadyForPullStart()) { - mLastMotionY = y; - mLastMotionX = x; - mIsBeingDragged = true; - if (mMode == Mode.BOTH) { - mCurrentMode = Mode.PULL_FROM_START; - } - } else if (mMode.showFooterLoadingLayout() && diff <= -1f && isReadyForPullEnd()) { - mLastMotionY = y; - mLastMotionX = x; - mIsBeingDragged = true; - if (mMode == Mode.BOTH) { - mCurrentMode = Mode.PULL_FROM_END; - } - } - } - } - break; - } - case MotionEvent.ACTION_DOWN: { - if (isReadyForPull()) { - mLastMotionY = mInitialMotionY = event.getY(); - mLastMotionX = mInitialMotionX = event.getX(); - mIsBeingDragged = false; - } - break; - } - } - - return mIsBeingDragged; - } - - @Override - public final void onRefreshComplete() { - if (isRefreshing()) { - setState(State.RESET); - } - } - - @Override - public final boolean onTouchEvent(MotionEvent event) { - - if (!isPullToRefreshEnabled()) { - return false; - } - - // If we're refreshing, and the flag is set. Eat the event - if (!mScrollingWhileRefreshingEnabled && isRefreshing()) { - return true; - } - - if (event.getAction() == MotionEvent.ACTION_DOWN && event.getEdgeFlags() != 0) { - return false; - } - - switch (event.getAction()) { - case MotionEvent.ACTION_MOVE: { - if (mIsBeingDragged) { - mLastMotionY = event.getY(); - mLastMotionX = event.getX(); - pullEvent(); - return true; - } - break; - } - - case MotionEvent.ACTION_DOWN: { - if (isReadyForPull()) { - mLastMotionY = mInitialMotionY = event.getY(); - mLastMotionX = mInitialMotionX = event.getX(); - return true; - } - break; - } - - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: { - if (mIsBeingDragged) { - mIsBeingDragged = false; - - if (mState == State.RELEASE_TO_REFRESH - && (null != mOnRefreshListener || null != mOnRefreshListener2)) { - setState(State.REFRESHING, true); - return true; - } - - // If we're already refreshing, just scroll back to the top - if (isRefreshing()) { - smoothScrollTo(0); - return true; - } - - // If we haven't returned by here, then we're not in a state - // to pull, so just reset - setState(State.RESET); - - return true; - } - break; - } - } - - return false; - } - - public final void setScrollingWhileRefreshingEnabled(boolean allowScrollingWhileRefreshing) { - mScrollingWhileRefreshingEnabled = allowScrollingWhileRefreshing; - } - - /** - * @deprecated See {@link #setScrollingWhileRefreshingEnabled(boolean)} - */ - public void setDisableScrollingWhileRefreshing(boolean disableScrollingWhileRefreshing) { - setScrollingWhileRefreshingEnabled(!disableScrollingWhileRefreshing); - } - - @Override - public final void setFilterTouchEvents(boolean filterEvents) { - mFilterTouchEvents = filterEvents; - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy()}. - */ - public void setLastUpdatedLabel(CharSequence label) { - getLoadingLayoutProxy().setLastUpdatedLabel(label); - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy()}. - */ - public void setLoadingDrawable(Drawable drawable) { - getLoadingLayoutProxy().setLoadingDrawable(drawable); - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy(boolean, boolean)}. - */ - public void setLoadingDrawable(Drawable drawable, Mode mode) { - getLoadingLayoutProxy(mode.showHeaderLoadingLayout(), mode.showFooterLoadingLayout()).setLoadingDrawable( - drawable); - } - - @Override - public void setLongClickable(boolean longClickable) { - getRefreshableView().setLongClickable(longClickable); - } - - @Override - public final void setMode(Mode mode) { - if (mode != mMode) { - if (DEBUG) { - Log.d(LOG_TAG, "Setting mode to: " + mode); - } - mMode = mode; - updateUIForMode(); - } - } - - public void setOnPullEventListener(OnPullEventListener<T> listener) { - mOnPullEventListener = listener; - } - - @Override - public final void setOnRefreshListener(OnRefreshListener<T> listener) { - mOnRefreshListener = listener; - mOnRefreshListener2 = null; - } - - @Override - public final void setOnRefreshListener(OnRefreshListener2<T> listener) { - mOnRefreshListener2 = listener; - mOnRefreshListener = null; - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy()}. - */ - public void setPullLabel(CharSequence pullLabel) { - getLoadingLayoutProxy().setPullLabel(pullLabel); - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy(boolean, boolean)}. - */ - public void setPullLabel(CharSequence pullLabel, Mode mode) { - getLoadingLayoutProxy(mode.showHeaderLoadingLayout(), mode.showFooterLoadingLayout()).setPullLabel(pullLabel); - } - - /** - * @param enable Whether Pull-To-Refresh should be used - * @deprecated This simple calls setMode with an appropriate mode based on - * the passed value. - */ - public final void setPullToRefreshEnabled(boolean enable) { - setMode(enable ? Mode.getDefault() : Mode.DISABLED); - } - - @Override - public final void setPullToRefreshOverScrollEnabled(boolean enabled) { - mOverScrollEnabled = enabled; - } - - @Override - public final void setRefreshing() { - setRefreshing(true); - } - - @Override - public final void setRefreshing(boolean doScroll) { - if (!isRefreshing()) { - setState(State.MANUAL_REFRESHING, doScroll); - } - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy()}. - */ - public void setRefreshingLabel(CharSequence refreshingLabel) { - getLoadingLayoutProxy().setRefreshingLabel(refreshingLabel); - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy(boolean, boolean)}. - */ - public void setRefreshingLabel(CharSequence refreshingLabel, Mode mode) { - getLoadingLayoutProxy(mode.showHeaderLoadingLayout(), mode.showFooterLoadingLayout()).setRefreshingLabel( - refreshingLabel); - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy()}. - */ - public void setReleaseLabel(CharSequence releaseLabel) { - setReleaseLabel(releaseLabel, Mode.BOTH); - } - - /** - * @deprecated You should now call this method on the result of - * {@link #getLoadingLayoutProxy(boolean, boolean)}. - */ - public void setReleaseLabel(CharSequence releaseLabel, Mode mode) { - getLoadingLayoutProxy(mode.showHeaderLoadingLayout(), mode.showFooterLoadingLayout()).setReleaseLabel( - releaseLabel); - } - - public void setScrollAnimationInterpolator(Interpolator interpolator) { - mScrollAnimationInterpolator = interpolator; - } - - @Override - public final void setShowViewWhileRefreshing(boolean showView) { - mShowViewWhileRefreshing = showView; - } - - /** - * @return Either {@link Orientation#VERTICAL} or - * {@link Orientation#HORIZONTAL} depending on the scroll direction. - */ - public abstract Orientation getPullToRefreshScrollDirection(); - - final void setState(State state, final boolean... params) { - mState = state; - if (DEBUG) { - Log.d(LOG_TAG, "State: " + mState.name()); - } - - switch (mState) { - case RESET: - onReset(); - break; - case PULL_TO_REFRESH: - onPullToRefresh(); - break; - case RELEASE_TO_REFRESH: - onReleaseToRefresh(); - break; - case REFRESHING: - case MANUAL_REFRESHING: - onRefreshing(params[0]); - break; - case OVERSCROLLING: - // NO-OP - break; - } - - // Call OnPullEventListener - if (null != mOnPullEventListener) { - mOnPullEventListener.onPullEvent(this, mState, mCurrentMode); - } - } - - /** - * Used internally for adding view. Need because we override addView to - * pass-through to the Refreshable View - */ - protected final void addViewInternal(View child, int index, ViewGroup.LayoutParams params) { - super.addView(child, index, params); - } - - /** - * Used internally for adding view. Need because we override addView to - * pass-through to the Refreshable View - */ - protected final void addViewInternal(View child, ViewGroup.LayoutParams params) { - super.addView(child, -1, params); - } - - protected LoadingLayout createLoadingLayout(Context context, Mode mode, TypedArray attrs) { - LoadingLayout layout = mLoadingAnimationStyle.createLoadingLayout(context, mode, - getPullToRefreshScrollDirection(), attrs); - layout.setVisibility(View.INVISIBLE); - return layout; - } - - /** - * Used internally for {@link #getLoadingLayoutProxy(boolean, boolean)}. - * Allows derivative classes to include any extra LoadingLayouts. - */ - protected LoadingLayoutProxy createLoadingLayoutProxy(final boolean includeStart, final boolean includeEnd) { - LoadingLayoutProxy proxy = new LoadingLayoutProxy(); - - if (includeStart && mMode.showHeaderLoadingLayout()) { - proxy.addLayout(mHeaderLayout); - } - if (includeEnd && mMode.showFooterLoadingLayout()) { - proxy.addLayout(mFooterLayout); - } - - return proxy; - } - - /** - * This is implemented by derived classes to return the created View. If you - * need to use a custom View (such as a custom ListView), override this - * method and return an instance of your custom class. - * <p/> - * Be sure to set the ID of the view in this method, especially if you're - * using a ListActivity or ListFragment. - * - * @param context Context to create view with - * @param attrs AttributeSet from wrapped class. Means that anything you - * include in the XML layout declaration will be routed to the - * created View - * @return New instance of the Refreshable View - */ - protected abstract T createRefreshableView(Context context, AttributeSet attrs); - - protected final void disableLoadingLayoutVisibilityChanges() { - mLayoutVisibilityChangesEnabled = false; - } - - protected final LoadingLayout getFooterLayout() { - return mFooterLayout; - } - - protected final int getFooterSize() { - return mFooterLayout.getContentSize(); - } - - protected final LoadingLayout getHeaderLayout() { - return mHeaderLayout; - } - - protected final int getHeaderSize() { - return mHeaderLayout.getContentSize(); - } - - protected int getPullToRefreshScrollDuration() { - return SMOOTH_SCROLL_DURATION_MS; - } - - protected int getPullToRefreshScrollDurationLonger() { - return SMOOTH_SCROLL_LONG_DURATION_MS; - } - - protected FrameLayout getRefreshableViewWrapper() { - return mRefreshableViewWrapper; - } - - /** - * Allows Derivative classes to handle the XML Attrs without creating a - * TypedArray themsevles - * - * @param a - TypedArray of PullToRefresh Attributes - */ - protected void handleStyledAttributes(TypedArray a) { - } - - /** - * Implemented by derived class to return whether the View is in a state - * where the user can Pull to Refresh by scrolling from the end. - * - * @return true if the View is currently in the correct state (for example, - * bottom of a ListView) - */ - protected abstract boolean isReadyForPullEnd(); - - /** - * Implemented by derived class to return whether the View is in a state - * where the user can Pull to Refresh by scrolling from the start. - * - * @return true if the View is currently the correct state (for example, top - * of a ListView) - */ - protected abstract boolean isReadyForPullStart(); - - /** - * Called by {@link #onRestoreInstanceState(Parcelable)} so that derivative - * classes can handle their saved instance state. - * - * @param savedInstanceState - Bundle which contains saved instance state. - */ - protected void onPtrRestoreInstanceState(Bundle savedInstanceState) { - } - - /** - * Called by {@link #onSaveInstanceState()} so that derivative classes can - * save their instance state. - * - * @param saveState - Bundle to be updated with saved state. - */ - protected void onPtrSaveInstanceState(Bundle saveState) { - } - - /** - * Called when the UI has been to be updated to be in the - * {@link State#PULL_TO_REFRESH} state. - */ - protected void onPullToRefresh() { - switch (mCurrentMode) { - case PULL_FROM_END: - mFooterLayout.pullToRefresh(); - break; - case PULL_FROM_START: - mHeaderLayout.pullToRefresh(); - break; - default: - // NO-OP - break; - } - } - - /** - * Called when the UI has been to be updated to be in the - * {@link State#REFRESHING} or {@link State#MANUAL_REFRESHING} state. - * - * @param doScroll - Whether the UI should scroll for this event. - */ - protected void onRefreshing(final boolean doScroll) { - if (mMode.showHeaderLoadingLayout()) { - mHeaderLayout.refreshing(); - } - if (mMode.showFooterLoadingLayout()) { - mFooterLayout.refreshing(); - } - - if (doScroll) { - if (mShowViewWhileRefreshing) { - - // Call Refresh Listener when the Scroll has finished - OnSmoothScrollFinishedListener listener = new OnSmoothScrollFinishedListener() { - @Override - public void onSmoothScrollFinished() { - callRefreshListener(); - } - }; - - switch (mCurrentMode) { - case MANUAL_REFRESH_ONLY: - case PULL_FROM_END: - smoothScrollTo(getFooterSize(), listener); - break; - default: - case PULL_FROM_START: - smoothScrollTo(-getHeaderSize(), listener); - break; - } - } else { - smoothScrollTo(0); - } - } else { - // We're not scrolling, so just call Refresh Listener now - callRefreshListener(); - } - } - - /** - * Called when the UI has been to be updated to be in the - * {@link State#RELEASE_TO_REFRESH} state. - */ - protected void onReleaseToRefresh() { - switch (mCurrentMode) { - case PULL_FROM_END: - mFooterLayout.releaseToRefresh(); - break; - case PULL_FROM_START: - mHeaderLayout.releaseToRefresh(); - break; - default: - // NO-OP - break; - } - } - - /** - * Called when the UI has been to be updated to be in the - * {@link State#RESET} state. - */ - protected void onReset() { - mIsBeingDragged = false; - mLayoutVisibilityChangesEnabled = true; - - // Always reset both layouts, just in case... - mHeaderLayout.reset(); - mFooterLayout.reset(); - - smoothScrollTo(0); - } - - @Override - protected final void onRestoreInstanceState(Parcelable state) { - if (state instanceof Bundle) { - Bundle bundle = (Bundle) state; - - setMode(Mode.mapIntToValue(bundle.getInt(STATE_MODE, 0))); - mCurrentMode = Mode.mapIntToValue(bundle.getInt(STATE_CURRENT_MODE, 0)); - - mScrollingWhileRefreshingEnabled = bundle.getBoolean(STATE_SCROLLING_REFRESHING_ENABLED, false); - mShowViewWhileRefreshing = bundle.getBoolean(STATE_SHOW_REFRESHING_VIEW, true); - - // Let super Restore Itself - super.onRestoreInstanceState(bundle.getParcelable(STATE_SUPER)); - - State viewState = State.mapIntToValue(bundle.getInt(STATE_STATE, 0)); - if (viewState == State.REFRESHING || viewState == State.MANUAL_REFRESHING) { - setState(viewState, true); - } - - // Now let derivative classes restore their state - onPtrRestoreInstanceState(bundle); - return; - } - - super.onRestoreInstanceState(state); - } - - @Override - protected final Parcelable onSaveInstanceState() { - Bundle bundle = new Bundle(); - - // Let derivative classes get a chance to save state first, that way we - // can make sure they don't overrite any of our values - onPtrSaveInstanceState(bundle); - - bundle.putInt(STATE_STATE, mState.getIntValue()); - bundle.putInt(STATE_MODE, mMode.getIntValue()); - bundle.putInt(STATE_CURRENT_MODE, mCurrentMode.getIntValue()); - bundle.putBoolean(STATE_SCROLLING_REFRESHING_ENABLED, mScrollingWhileRefreshingEnabled); - bundle.putBoolean(STATE_SHOW_REFRESHING_VIEW, mShowViewWhileRefreshing); - bundle.putParcelable(STATE_SUPER, super.onSaveInstanceState()); - - return bundle; - } - - @Override - protected final void onSizeChanged(int w, int h, int oldw, int oldh) { - if (DEBUG) { - Log.d(LOG_TAG, String.format("onSizeChanged. W: %d, H: %d", w, h)); - } - - super.onSizeChanged(w, h, oldw, oldh); - - // We need to update the header/footer when our size changes - refreshLoadingViewsSize(); - - // Update the Refreshable View layout - refreshRefreshableViewSize(w, h); - - /** - * As we're currently in a Layout Pass, we need to schedule another one - * to layout any changes we've made here - */ - post(new Runnable() { - @Override - public void run() { - requestLayout(); - } - }); - } - - /** - * Re-measure the Loading Views height, and adjust internal padding as - * necessary - */ - protected final void refreshLoadingViewsSize() { - final int maximumPullScroll = (int) (getMaximumPullScroll() * 1.2f); - - int pLeft = getPaddingLeft(); - int pTop = getPaddingTop(); - int pRight = getPaddingRight(); - int pBottom = getPaddingBottom(); - - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - if (mMode.showHeaderLoadingLayout()) { - mHeaderLayout.setWidth(maximumPullScroll); - pLeft = -maximumPullScroll; - } else { - pLeft = 0; - } - - if (mMode.showFooterLoadingLayout()) { - mFooterLayout.setWidth(maximumPullScroll); - pRight = -maximumPullScroll; - } else { - pRight = 0; - } - break; - - case VERTICAL: - if (mMode.showHeaderLoadingLayout()) { - mHeaderLayout.setHeight(maximumPullScroll); - pTop = -maximumPullScroll; - } else { - pTop = 0; - } - - if (mMode.showFooterLoadingLayout()) { - mFooterLayout.setHeight(maximumPullScroll); - pBottom = -maximumPullScroll; - } else { - pBottom = 0; - } - break; - } - - if (DEBUG) { - Log.d(LOG_TAG, String.format("Setting Padding. L: %d, T: %d, R: %d, B: %d", pLeft, pTop, pRight, pBottom)); - } - setPadding(pLeft, pTop, pRight, pBottom); - } - - protected final void refreshRefreshableViewSize(int width, int height) { - // We need to set the Height of the Refreshable View to the same as - // this layout - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mRefreshableViewWrapper.getLayoutParams(); - - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - if (lp.width != width) { - lp.width = width; - mRefreshableViewWrapper.requestLayout(); - } - break; - case VERTICAL: - if (lp.height != height) { - lp.height = height; - mRefreshableViewWrapper.requestLayout(); - } - break; - } - } - - /** - * Helper method which just calls scrollTo() in the correct scrolling - * direction. - * - * @param value - New Scroll value - */ - protected final void setHeaderScroll(int value) { - if (DEBUG) { - Log.d(LOG_TAG, "setHeaderScroll: " + value); - } - - // Clamp value to with pull scroll range - final int maximumPullScroll = getMaximumPullScroll(); - value = Math.min(maximumPullScroll, Math.max(-maximumPullScroll, value)); - - if (mLayoutVisibilityChangesEnabled) { - if (value < 0) { - mHeaderLayout.setVisibility(View.VISIBLE); - } else if (value > 0) { - mFooterLayout.setVisibility(View.VISIBLE); - } else { - mHeaderLayout.setVisibility(View.INVISIBLE); - mFooterLayout.setVisibility(View.INVISIBLE); - } - } - - if (USE_HW_LAYERS) { - /** - * Use a Hardware Layer on the Refreshable View if we've scrolled at - * all. We don't use them on the Header/Footer Views as they change - * often, which would negate any HW layer performance boost. - */ - ViewCompat.setLayerType(mRefreshableViewWrapper, value != 0 ? View.LAYER_TYPE_HARDWARE - : View.LAYER_TYPE_NONE); - } - - switch (getPullToRefreshScrollDirection()) { - case VERTICAL: - scrollTo(0, value); - break; - case HORIZONTAL: - scrollTo(value, 0); - break; - } - } - - /** - * Smooth Scroll to position using the default duration of - * {@value #SMOOTH_SCROLL_DURATION_MS} ms. - * - * @param scrollValue - Position to scroll to - */ - protected final void smoothScrollTo(int scrollValue) { - smoothScrollTo(scrollValue, getPullToRefreshScrollDuration()); - } - - /** - * Smooth Scroll to position using the default duration of - * {@value #SMOOTH_SCROLL_DURATION_MS} ms. - * - * @param scrollValue - Position to scroll to - * @param listener - Listener for scroll - */ - protected final void smoothScrollTo(int scrollValue, OnSmoothScrollFinishedListener listener) { - smoothScrollTo(scrollValue, getPullToRefreshScrollDuration(), 0, listener); - } - - /** - * Smooth Scroll to position using the longer default duration of - * {@value #SMOOTH_SCROLL_LONG_DURATION_MS} ms. - * - * @param scrollValue - Position to scroll to - */ - protected final void smoothScrollToLonger(int scrollValue) { - smoothScrollTo(scrollValue, getPullToRefreshScrollDurationLonger()); - } - - /** - * Updates the View State when the mode has been set. This does not do any - * checking that the mode is different to current state so always updates. - */ - protected void updateUIForMode() { - // We need to use the correct LayoutParam values, based on scroll - // direction - final LinearLayout.LayoutParams lp = getLoadingLayoutLayoutParams(); - - // Remove Header, and then add Header Loading View again if needed - if (this == mHeaderLayout.getParent()) { - removeView(mHeaderLayout); - } - if (mMode.showHeaderLoadingLayout()) { - addViewInternal(mHeaderLayout, 0, lp); - } - - // Remove Footer, and then add Footer Loading View again if needed - if (this == mFooterLayout.getParent()) { - removeView(mFooterLayout); - } - if (mMode.showFooterLoadingLayout()) { - addViewInternal(mFooterLayout, lp); - } - - // Hide Loading Views - refreshLoadingViewsSize(); - - // If we're not using Mode.BOTH, set mCurrentMode to mMode, otherwise - // set it to pull down - mCurrentMode = (mMode != Mode.BOTH) ? mMode : Mode.PULL_FROM_START; - } - - private void addRefreshableView(Context context, T refreshableView) { - mRefreshableViewWrapper = new FrameLayout(context); - mRefreshableViewWrapper.addView(refreshableView, ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT); - - addViewInternal(mRefreshableViewWrapper, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT)); - } - - private void callRefreshListener() { - if (null != mOnRefreshListener) { - mOnRefreshListener.onRefresh(this); - } else if (null != mOnRefreshListener2) { - if (mCurrentMode == Mode.PULL_FROM_START) { - mOnRefreshListener2.onPullDownToRefresh(this); - } else if (mCurrentMode == Mode.PULL_FROM_END) { - mOnRefreshListener2.onPullUpToRefresh(this); - } - } - } - - @SuppressWarnings("deprecation") - private void init(Context context, AttributeSet attrs) { - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - setOrientation(LinearLayout.HORIZONTAL); - break; - case VERTICAL: - default: - setOrientation(LinearLayout.VERTICAL); - break; - } - - setGravity(Gravity.CENTER); - - ViewConfiguration config = ViewConfiguration.get(context); - mTouchSlop = config.getScaledTouchSlop(); - - // Styleables from XML - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PullToRefresh); - - if (a.hasValue(R.styleable.PullToRefresh_ptrMode)) { - mMode = Mode.mapIntToValue(a.getInteger(R.styleable.PullToRefresh_ptrMode, 0)); - } - - if (a.hasValue(R.styleable.PullToRefresh_ptrAnimationStyle)) { - mLoadingAnimationStyle = AnimationStyle.mapIntToValue(a.getInteger( - R.styleable.PullToRefresh_ptrAnimationStyle, 0)); - } - - // Refreshable View - // By passing the attrs, we can add ListView/GridView params via XML - mRefreshableView = createRefreshableView(context, attrs); - addRefreshableView(context, mRefreshableView); - - // We need to create now layouts now - mHeaderLayout = createLoadingLayout(context, Mode.PULL_FROM_START, a); - mFooterLayout = createLoadingLayout(context, Mode.PULL_FROM_END, a); - - /** - * Styleables from XML - */ - if (a.hasValue(R.styleable.PullToRefresh_ptrRefreshableViewBackground)) { - Drawable background = a.getDrawable(R.styleable.PullToRefresh_ptrRefreshableViewBackground); - if (null != background) { - mRefreshableView.setBackgroundDrawable(background); - } - } else if (a.hasValue(R.styleable.PullToRefresh_ptrAdapterViewBackground)) { - Utils.warnDeprecation("ptrAdapterViewBackground", "ptrRefreshableViewBackground"); - Drawable background = a.getDrawable(R.styleable.PullToRefresh_ptrAdapterViewBackground); - if (null != background) { - mRefreshableView.setBackgroundDrawable(background); - } - } - - if (a.hasValue(R.styleable.PullToRefresh_ptrOverScroll)) { - mOverScrollEnabled = a.getBoolean(R.styleable.PullToRefresh_ptrOverScroll, true); - } - - if (a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) { - mScrollingWhileRefreshingEnabled = a.getBoolean( - R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled, false); - } - - // Let the derivative classes have a go at handling attributes, then - // recycle them... - handleStyledAttributes(a); - a.recycle(); - - // Finally update the UI for the modes - updateUIForMode(); - } - - private boolean isReadyForPull() { - switch (mMode) { - case PULL_FROM_START: - return isReadyForPullStart(); - case PULL_FROM_END: - return isReadyForPullEnd(); - case BOTH: - return isReadyForPullEnd() || isReadyForPullStart(); - default: - return false; - } - } - - /** - * Actions a Pull Event - * - * @return true if the Event has been handled, false if there has been no - * change - */ - private void pullEvent() { - final int newScrollValue; - final int itemDimension; - final float initialMotionValue, lastMotionValue; - - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - initialMotionValue = mInitialMotionX; - lastMotionValue = mLastMotionX; - break; - case VERTICAL: - default: - initialMotionValue = mInitialMotionY; - lastMotionValue = mLastMotionY; - break; - } - - switch (mCurrentMode) { - case PULL_FROM_END: - newScrollValue = Math.round(Math.max(initialMotionValue - lastMotionValue, 0) / FRICTION); - itemDimension = getFooterSize(); - break; - case PULL_FROM_START: - default: - newScrollValue = Math.round(Math.min(initialMotionValue - lastMotionValue, 0) / FRICTION); - itemDimension = getHeaderSize(); - break; - } - - setHeaderScroll(newScrollValue); - - if (newScrollValue != 0 && !isRefreshing()) { - float scale = Math.abs(newScrollValue) / (float) itemDimension; - switch (mCurrentMode) { - case PULL_FROM_END: - mFooterLayout.onPull(scale); - break; - case PULL_FROM_START: - default: - mHeaderLayout.onPull(scale); - break; - } - - if (mState != State.PULL_TO_REFRESH && itemDimension >= Math.abs(newScrollValue)) { - setState(State.PULL_TO_REFRESH); - } else if (mState == State.PULL_TO_REFRESH && itemDimension < Math.abs(newScrollValue)) { - setState(State.RELEASE_TO_REFRESH); - } - } - } - - private LinearLayout.LayoutParams getLoadingLayoutLayoutParams() { - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - return new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, - LinearLayout.LayoutParams.MATCH_PARENT); - case VERTICAL: - default: - return new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, - LinearLayout.LayoutParams.WRAP_CONTENT); - } - } - - private int getMaximumPullScroll() { - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - return Math.round(getWidth() / FRICTION); - case VERTICAL: - default: - return Math.round(getHeight() / FRICTION); - } - } - - /** - * Smooth Scroll to position using the specific duration - * - * @param scrollValue - Position to scroll to - * @param duration - Duration of animation in milliseconds - */ - private final void smoothScrollTo(int scrollValue, long duration) { - smoothScrollTo(scrollValue, duration, 0, null); - } - - private final void smoothScrollTo(int newScrollValue, long duration, long delayMillis, - OnSmoothScrollFinishedListener listener) { - if (null != mCurrentSmoothScrollRunnable) { - mCurrentSmoothScrollRunnable.stop(); - } - - final int oldScrollValue; - switch (getPullToRefreshScrollDirection()) { - case HORIZONTAL: - oldScrollValue = getScrollX(); - break; - case VERTICAL: - default: - oldScrollValue = getScrollY(); - break; - } - - if (oldScrollValue != newScrollValue) { - if (null == mScrollAnimationInterpolator) { - // Default interpolator is a Decelerate Interpolator - mScrollAnimationInterpolator = new DecelerateInterpolator(); - } - mCurrentSmoothScrollRunnable = new SmoothScrollRunnable(oldScrollValue, newScrollValue, duration, listener); - - if (delayMillis > 0) { - postDelayed(mCurrentSmoothScrollRunnable, delayMillis); - } else { - post(mCurrentSmoothScrollRunnable); - } - } - } - - private final void smoothScrollToAndBack(int y) { - smoothScrollTo(y, SMOOTH_SCROLL_DURATION_MS, 0, new OnSmoothScrollFinishedListener() { - - @Override - public void onSmoothScrollFinished() { - smoothScrollTo(0, SMOOTH_SCROLL_DURATION_MS, DEMO_SCROLL_INTERVAL, null); - } - }); - } - - public static enum AnimationStyle { - /** - * This is the default for Android-PullToRefresh. Allows you to use any - * drawable, which is automatically rotated and used as a Progress Bar. - */ - ROTATE, - - /** - * This is the old default, and what is commonly used on iOS. Uses an - * arrow image which flips depending on where the user has scrolled. - */ - FLIP; - - static AnimationStyle getDefault() { - return ROTATE; - } - - /** - * Maps an int to a specific mode. This is needed when saving state, or - * inflating the view from XML where the mode is given through a attr - * int. - * - * @param modeInt - int to map a Mode to - * @return Mode that modeInt maps to, or ROTATE by default. - */ - static AnimationStyle mapIntToValue(int modeInt) { - switch (modeInt) { - case 0x0: - default: - return ROTATE; - case 0x1: - return FLIP; - } - } - - LoadingLayout createLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) { - switch (this) { - case ROTATE: - default: - return new RotateLoadingLayout(context, mode, scrollDirection, attrs); - case FLIP: - return new FlipLoadingLayout(context, mode, scrollDirection, attrs); - } - } - } - - public static enum Mode { - - /** - * Disable all Pull-to-Refresh gesture and Refreshing handling - */ - DISABLED(0x0), - - /** - * Only allow the user to Pull from the start of the Refreshable View to - * refresh. The start is either the Top or Left, depending on the - * scrolling direction. - */ - PULL_FROM_START(0x1), - - /** - * Only allow the user to Pull from the end of the Refreshable View to - * refresh. The start is either the Bottom or Right, depending on the - * scrolling direction. - */ - PULL_FROM_END(0x2), - - /** - * Allow the user to both Pull from the start, from the end to refresh. - */ - BOTH(0x3), - - /** - * Disables Pull-to-Refresh gesture handling, but allows manually - * setting the Refresh state via - * {@link PullToRefreshBase#setRefreshing() setRefreshing()}. - */ - MANUAL_REFRESH_ONLY(0x4); - - /** - * @deprecated Use {@link #PULL_FROM_START} from now on. - */ - public static Mode PULL_DOWN_TO_REFRESH = Mode.PULL_FROM_START; - - /** - * @deprecated Use {@link #PULL_FROM_END} from now on. - */ - public static Mode PULL_UP_TO_REFRESH = Mode.PULL_FROM_END; - - /** - * Maps an int to a specific mode. This is needed when saving state, or - * inflating the view from XML where the mode is given through a attr - * int. - * - * @param modeInt - int to map a Mode to - * @return Mode that modeInt maps to, or PULL_FROM_START by default. - */ - static Mode mapIntToValue(final int modeInt) { - for (Mode value : Mode.values()) { - if (modeInt == value.getIntValue()) { - return value; - } - } - - // If not, return default - return getDefault(); - } - - static Mode getDefault() { - return PULL_FROM_START; - } - - private int mIntValue; - - // The modeInt values need to match those from attrs.xml - Mode(int modeInt) { - mIntValue = modeInt; - } - - /** - * @return true if the mode permits Pull-to-Refresh - */ - boolean permitsPullToRefresh() { - return !(this == DISABLED || this == MANUAL_REFRESH_ONLY); - } - - /** - * @return true if this mode wants the Loading Layout Header to be shown - */ - public boolean showHeaderLoadingLayout() { - return this == PULL_FROM_START || this == BOTH; - } - - /** - * @return true if this mode wants the Loading Layout Footer to be shown - */ - public boolean showFooterLoadingLayout() { - return this == PULL_FROM_END || this == BOTH || this == MANUAL_REFRESH_ONLY; - } - - int getIntValue() { - return mIntValue; - } - - } - - // =========================================================== - // Inner, Anonymous Classes, and Enumerations - // =========================================================== - - /** - * Simple Listener that allows you to be notified when the user has scrolled - * to the end of the AdapterView. See ( - * {@link PullToRefreshAdapterViewBase#setOnLastItemVisibleListener}. - * - * @author Chris Banes - */ - public static interface OnLastItemVisibleListener { - - /** - * Called when the user has scrolled to the end of the list - */ - public void onLastItemVisible(); - - } - - /** - * Listener that allows you to be notified when the user has started or - * finished a touch event. Useful when you want to append extra UI events - * (such as sounds). See ( - * {@link PullToRefreshAdapterViewBase#setOnPullEventListener}. - * - * @author Chris Banes - */ - public static interface OnPullEventListener<V extends View> { - - /** - * Called when the internal state has been changed, usually by the user - * pulling. - * - * @param refreshView - View which has had it's state change. - * @param state - The new state of View. - * @param direction - One of {@link Mode#PULL_FROM_START} or - * {@link Mode#PULL_FROM_END} depending on which direction - * the user is pulling. Only useful when <var>state</var> is - * {@link State#PULL_TO_REFRESH} or - * {@link State#RELEASE_TO_REFRESH}. - */ - public void onPullEvent(final PullToRefreshBase<V> refreshView, State state, Mode direction); - - } - - /** - * Simple Listener to listen for any callbacks to Refresh. - * - * @author Chris Banes - */ - public static interface OnRefreshListener<V extends View> { - - /** - * onRefresh will be called for both a Pull from start, and Pull from - * end - */ - public void onRefresh(final PullToRefreshBase<V> refreshView); - - } - - /** - * An advanced version of the Listener to listen for callbacks to Refresh. - * This listener is different as it allows you to differentiate between Pull - * Ups, and Pull Downs. - * - * @author Chris Banes - */ - public static interface OnRefreshListener2<V extends View> { - // TODO These methods need renaming to START/END rather than DOWN/UP - - /** - * onPullDownToRefresh will be called only when the user has Pulled from - * the start, and released. - */ - public void onPullDownToRefresh(final PullToRefreshBase<V> refreshView); - - /** - * onPullUpToRefresh will be called only when the user has Pulled from - * the end, and released. - */ - public void onPullUpToRefresh(final PullToRefreshBase<V> refreshView); - - } - - public static enum Orientation { - VERTICAL, HORIZONTAL; - } - - public static enum State { - - /** - * When the UI is in a state which means that user is not interacting - * with the Pull-to-Refresh function. - */ - RESET(0x0), - - /** - * When the UI is being pulled by the user, but has not been pulled far - * enough so that it refreshes when released. - */ - PULL_TO_REFRESH(0x1), - - /** - * When the UI is being pulled by the user, and <strong>has</strong> - * been pulled far enough so that it will refresh when released. - */ - RELEASE_TO_REFRESH(0x2), - - /** - * When the UI is currently refreshing, caused by a pull gesture. - */ - REFRESHING(0x8), - - /** - * When the UI is currently refreshing, caused by a call to - * {@link PullToRefreshBase#setRefreshing() setRefreshing()}. - */ - MANUAL_REFRESHING(0x9), - - /** - * When the UI is currently overscrolling, caused by a fling on the - * Refreshable View. - */ - OVERSCROLLING(0x10); - - /** - * Maps an int to a specific state. This is needed when saving state. - * - * @param stateInt - int to map a State to - * @return State that stateInt maps to - */ - static State mapIntToValue(final int stateInt) { - for (State value : State.values()) { - if (stateInt == value.getIntValue()) { - return value; - } - } - - // If not, return default - return RESET; - } - - private int mIntValue; - - State(int intValue) { - mIntValue = intValue; - } - - int getIntValue() { - return mIntValue; - } - } - - final class SmoothScrollRunnable implements Runnable { - private final Interpolator mInterpolator; - private final int mScrollToY; - private final int mScrollFromY; - private final long mDuration; - private OnSmoothScrollFinishedListener mListener; - - private boolean mContinueRunning = true; - private long mStartTime = -1; - private int mCurrentY = -1; - - public SmoothScrollRunnable(int fromY, int toY, long duration, OnSmoothScrollFinishedListener listener) { - mScrollFromY = fromY; - mScrollToY = toY; - mInterpolator = mScrollAnimationInterpolator; - mDuration = duration; - mListener = listener; - } - - @Override - public void run() { - - /** - * Only set mStartTime if this is the first time we're starting, - * else actually calculate the Y delta - */ - if (mStartTime == -1) { - mStartTime = System.currentTimeMillis(); - } else { - - /** - * We do do all calculations in long to reduce software float - * calculations. We use 1000 as it gives us good accuracy and - * small rounding errors - */ - long normalizedTime = (1000 * (System.currentTimeMillis() - mStartTime)) / mDuration; - normalizedTime = Math.max(Math.min(normalizedTime, 1000), 0); - - final int deltaY = Math.round((mScrollFromY - mScrollToY) - * mInterpolator.getInterpolation(normalizedTime / 1000f)); - mCurrentY = mScrollFromY - deltaY; - setHeaderScroll(mCurrentY); - } - - // If we're not at the target Y, keep going... - if (mContinueRunning && mScrollToY != mCurrentY) { - ViewCompat.postOnAnimation(PullToRefreshBase.this, this); - } else { - if (null != mListener) { - mListener.onSmoothScrollFinished(); - } - } - } - - public void stop() { - mContinueRunning = false; - removeCallbacks(this); - } - } - - static interface OnSmoothScrollFinishedListener { - void onSmoothScrollFinished(); - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshExpandableListView.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshExpandableListView.java deleted file mode 100644 index 649020c6..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshExpandableListView.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.util.AttributeSet; -import android.view.View; -import android.widget.ExpandableListView; - -import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; - -public class PullToRefreshExpandableListView extends PullToRefreshAdapterViewBase<ExpandableListView> { - - public PullToRefreshExpandableListView(Context context) { - super(context); - } - - public PullToRefreshExpandableListView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public PullToRefreshExpandableListView(Context context, Mode mode) { - super(context, mode); - } - - public PullToRefreshExpandableListView(Context context, Mode mode, AnimationStyle style) { - super(context, mode, style); - } - - @Override - public final Orientation getPullToRefreshScrollDirection() { - return Orientation.VERTICAL; - } - - @Override - protected ExpandableListView createRefreshableView(Context context, AttributeSet attrs) { - final ExpandableListView lv; - if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { - lv = new InternalExpandableListViewSDK9(context, attrs); - } else { - lv = new InternalExpandableListView(context, attrs); - } - - // Set it to this so it can be used in ListActivity/ListFragment - lv.setId(android.R.id.list); - return lv; - } - - class InternalExpandableListView extends ExpandableListView implements EmptyViewMethodAccessor { - - public InternalExpandableListView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - public void setEmptyView(View emptyView) { - PullToRefreshExpandableListView.this.setEmptyView(emptyView); - } - - @Override - public void setEmptyViewInternal(View emptyView) { - super.setEmptyView(emptyView); - } - } - - @TargetApi(9) - final class InternalExpandableListViewSDK9 extends InternalExpandableListView { - - public InternalExpandableListViewSDK9(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, - int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { - - final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, - scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); - - // Does all of the hard work... - OverscrollHelper.overScrollBy(PullToRefreshExpandableListView.this, deltaX, scrollX, deltaY, scrollY, - isTouchEvent); - - return returnValue; - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshGridView.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshGridView.java deleted file mode 100644 index f9506889..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshGridView.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.util.AttributeSet; -import android.view.View; -import android.widget.GridView; - -import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; - -public class PullToRefreshGridView extends PullToRefreshAdapterViewBase<GridView> { - - public PullToRefreshGridView(Context context) { - super(context); - } - - public PullToRefreshGridView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public PullToRefreshGridView(Context context, Mode mode) { - super(context, mode); - } - - public PullToRefreshGridView(Context context, Mode mode, AnimationStyle style) { - super(context, mode, style); - } - - @Override - public final Orientation getPullToRefreshScrollDirection() { - return Orientation.VERTICAL; - } - - @Override - protected final GridView createRefreshableView(Context context, AttributeSet attrs) { - final GridView gv; - if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { - gv = new InternalGridViewSDK9(context, attrs); - } else { - gv = new InternalGridView(context, attrs); - } - - // Use Generated ID (from res/values/ids.xml) - gv.setId(R.id.gridview); - return gv; - } - - class InternalGridView extends GridView implements EmptyViewMethodAccessor { - - public InternalGridView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - public void setEmptyView(View emptyView) { - PullToRefreshGridView.this.setEmptyView(emptyView); - } - - @Override - public void setEmptyViewInternal(View emptyView) { - super.setEmptyView(emptyView); - } - } - - @TargetApi(9) - final class InternalGridViewSDK9 extends InternalGridView { - - public InternalGridViewSDK9(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, - int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { - - final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, - scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); - - // Does all of the hard work... - OverscrollHelper.overScrollBy(PullToRefreshGridView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent); - - return returnValue; - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshHorizontalScrollView.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshHorizontalScrollView.java deleted file mode 100644 index a70f7ad2..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshHorizontalScrollView.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.util.AttributeSet; -import android.view.View; -import android.widget.HorizontalScrollView; - -public class PullToRefreshHorizontalScrollView extends PullToRefreshBase<HorizontalScrollView> { - - public PullToRefreshHorizontalScrollView(Context context) { - super(context); - } - - public PullToRefreshHorizontalScrollView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public PullToRefreshHorizontalScrollView(Context context, Mode mode) { - super(context, mode); - } - - public PullToRefreshHorizontalScrollView(Context context, Mode mode, AnimationStyle style) { - super(context, mode, style); - } - - @Override - public final Orientation getPullToRefreshScrollDirection() { - return Orientation.HORIZONTAL; - } - - @Override - protected HorizontalScrollView createRefreshableView(Context context, AttributeSet attrs) { - HorizontalScrollView scrollView; - - if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { - scrollView = new InternalHorizontalScrollViewSDK9(context, attrs); - } else { - scrollView = new HorizontalScrollView(context, attrs); - } - - scrollView.setId(R.id.scrollview); - return scrollView; - } - - @Override - protected boolean isReadyForPullStart() { - return mRefreshableView.getScrollX() == 0; - } - - @Override - protected boolean isReadyForPullEnd() { - View scrollViewChild = mRefreshableView.getChildAt(0); - if (null != scrollViewChild) { - return mRefreshableView.getScrollX() >= (scrollViewChild.getWidth() - getWidth()); - } - return false; - } - - @TargetApi(9) - final class InternalHorizontalScrollViewSDK9 extends HorizontalScrollView { - - public InternalHorizontalScrollViewSDK9(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, - int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { - - final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, - scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); - - // Does all of the hard work... - OverscrollHelper.overScrollBy(PullToRefreshHorizontalScrollView.this, deltaX, scrollX, deltaY, scrollY, - getScrollRange(), isTouchEvent); - - return returnValue; - } - - /** - * Taken from the AOSP ScrollView source - */ - private int getScrollRange() { - int scrollRange = 0; - if (getChildCount() > 0) { - View child = getChildAt(0); - scrollRange = Math.max(0, child.getWidth() - (getWidth() - getPaddingLeft() - getPaddingRight())); - } - return scrollRange; - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshListView.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshListView.java deleted file mode 100644 index 0aa9a27d..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshListView.java +++ /dev/null @@ -1,337 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.widget.FrameLayout; -import android.widget.ListAdapter; -import android.widget.ListView; - -import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor; -import com.handmark.pulltorefresh.library.internal.LoadingLayout; - -public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView> { - - private LoadingLayout mHeaderLoadingView; - private LoadingLayout mFooterLoadingView; - - private FrameLayout mLvFooterLoadingFrame; - - private boolean mListViewExtrasEnabled; - - public PullToRefreshListView(Context context) { - super(context); - } - - public PullToRefreshListView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public PullToRefreshListView(Context context, Mode mode) { - super(context, mode); - } - - public PullToRefreshListView(Context context, Mode mode, AnimationStyle style) { - super(context, mode, style); - } - - @Override - public final Orientation getPullToRefreshScrollDirection() { - return Orientation.VERTICAL; - } - - @Override - protected void onRefreshing(final boolean doScroll) { - /** - * If we're not showing the Refreshing view, or the list is empty, the - * the header/footer views won't show so we use the normal method. - */ - ListAdapter adapter = mRefreshableView.getAdapter(); - if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) { - super.onRefreshing(doScroll); - return; - } - - super.onRefreshing(false); - - final LoadingLayout origLoadingView, listViewLoadingView, oppositeListViewLoadingView; - final int selection, scrollToY; - - switch (getCurrentMode()) { - case MANUAL_REFRESH_ONLY: - case PULL_FROM_END: - origLoadingView = getFooterLayout(); - listViewLoadingView = mFooterLoadingView; - oppositeListViewLoadingView = mHeaderLoadingView; - selection = mRefreshableView.getCount() - 1; - scrollToY = getScrollY() - getFooterSize(); - break; - case PULL_FROM_START: - default: - origLoadingView = getHeaderLayout(); - listViewLoadingView = mHeaderLoadingView; - oppositeListViewLoadingView = mFooterLoadingView; - selection = 0; - scrollToY = getScrollY() + getHeaderSize(); - break; - } - - // Hide our original Loading View - origLoadingView.reset(); - origLoadingView.hideAllViews(); - - // Make sure the opposite end is hidden too - oppositeListViewLoadingView.setVisibility(View.GONE); - - // Show the ListView Loading View and set it to refresh. - listViewLoadingView.setVisibility(View.VISIBLE); - listViewLoadingView.refreshing(); - - if (doScroll) { - // We need to disable the automatic visibility changes for now - disableLoadingLayoutVisibilityChanges(); - - // We scroll slightly so that the ListView's header/footer is at the - // same Y position as our normal header/footer - setHeaderScroll(scrollToY); - - // Make sure the ListView is scrolled to show the loading - // header/footer - mRefreshableView.setSelection(selection); - - // Smooth scroll as normal - smoothScrollTo(0); - } - } - - @Override - protected void onReset() { - /** - * If the extras are not enabled, just call up to super and return. - */ - if (!mListViewExtrasEnabled) { - super.onReset(); - return; - } - - final LoadingLayout originalLoadingLayout, listViewLoadingLayout; - final int scrollToHeight, selection; - final boolean scrollLvToEdge; - - switch (getCurrentMode()) { - case MANUAL_REFRESH_ONLY: - case PULL_FROM_END: - originalLoadingLayout = getFooterLayout(); - listViewLoadingLayout = mFooterLoadingView; - selection = mRefreshableView.getCount() - 1; - scrollToHeight = getFooterSize(); - scrollLvToEdge = Math.abs(mRefreshableView.getLastVisiblePosition() - selection) <= 1; - break; - case PULL_FROM_START: - default: - originalLoadingLayout = getHeaderLayout(); - listViewLoadingLayout = mHeaderLoadingView; - scrollToHeight = -getHeaderSize(); - selection = 0; - scrollLvToEdge = Math.abs(mRefreshableView.getFirstVisiblePosition() - selection) <= 1; - break; - } - - // If the ListView header loading layout is showing, then we need to - // flip so that the original one is showing instead - if (listViewLoadingLayout.getVisibility() == View.VISIBLE) { - - // Set our Original View to Visible - originalLoadingLayout.showInvisibleViews(); - - // Hide the ListView Header/Footer - listViewLoadingLayout.setVisibility(View.GONE); - - /** - * Scroll so the View is at the same Y as the ListView - * header/footer, but only scroll if: we've pulled to refresh, it's - * positioned correctly - */ - if (scrollLvToEdge && getState() != State.MANUAL_REFRESHING) { - mRefreshableView.setSelection(selection); - setHeaderScroll(scrollToHeight); - } - } - - // Finally, call up to super - super.onReset(); - } - - @Override - protected LoadingLayoutProxy createLoadingLayoutProxy(final boolean includeStart, final boolean includeEnd) { - LoadingLayoutProxy proxy = super.createLoadingLayoutProxy(includeStart, includeEnd); - - if (mListViewExtrasEnabled) { - final Mode mode = getMode(); - - if (includeStart && mode.showHeaderLoadingLayout()) { - proxy.addLayout(mHeaderLoadingView); - } - if (includeEnd && mode.showFooterLoadingLayout()) { - proxy.addLayout(mFooterLoadingView); - } - } - - return proxy; - } - - protected ListView createListView(Context context, AttributeSet attrs) { - final ListView lv; - if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { - lv = new InternalListViewSDK9(context, attrs); - } else { - lv = new InternalListView(context, attrs); - } - return lv; - } - - @Override - protected ListView createRefreshableView(Context context, AttributeSet attrs) { - ListView lv = createListView(context, attrs); - - // Set it to this so it can be used in ListActivity/ListFragment - lv.setId(android.R.id.list); - return lv; - } - - @Override - protected void handleStyledAttributes(TypedArray a) { - super.handleStyledAttributes(a); - - mListViewExtrasEnabled = a.getBoolean(R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true); - - if (mListViewExtrasEnabled) { - final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, - FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL); - - // Create Loading Views ready for use later - FrameLayout frame = new FrameLayout(getContext()); - mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a); - mHeaderLoadingView.setVisibility(View.GONE); - frame.addView(mHeaderLoadingView, lp); - mRefreshableView.addHeaderView(frame, null, false); - - mLvFooterLoadingFrame = new FrameLayout(getContext()); - mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a); - mFooterLoadingView.setVisibility(View.GONE); - mLvFooterLoadingFrame.addView(mFooterLoadingView, lp); - - /** - * If the value for Scrolling While Refreshing hasn't been - * explicitly set via XML, enable Scrolling While Refreshing. - */ - if (!a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) { - setScrollingWhileRefreshingEnabled(true); - } - } - } - - @TargetApi(9) - final class InternalListViewSDK9 extends InternalListView { - - public InternalListViewSDK9(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, - int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { - - final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, - scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); - - // Does all of the hard work... - OverscrollHelper.overScrollBy(PullToRefreshListView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent); - - return returnValue; - } - } - - protected class InternalListView extends ListView implements EmptyViewMethodAccessor { - - private boolean mAddedLvFooter = false; - - public InternalListView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void dispatchDraw(Canvas canvas) { - /** - * This is a bit hacky, but Samsung's ListView has got a bug in it - * when using Header/Footer Views and the list is empty. This masks - * the issue so that it doesn't cause an FC. See Issue #66. - */ - try { - super.dispatchDraw(canvas); - } catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - } - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - /** - * This is a bit hacky, but Samsung's ListView has got a bug in it - * when using Header/Footer Views and the list is empty. This masks - * the issue so that it doesn't cause an FC. See Issue #66. - */ - try { - return super.dispatchTouchEvent(ev); - } catch (IndexOutOfBoundsException e) { - e.printStackTrace(); - return false; - } - } - - @Override - public void setAdapter(ListAdapter adapter) { - // Add the Footer View at the last possible moment - if (null != mLvFooterLoadingFrame && !mAddedLvFooter) { - addFooterView(mLvFooterLoadingFrame, null, false); - mAddedLvFooter = true; - } - - super.setAdapter(adapter); - } - - @Override - public void setEmptyView(View emptyView) { - PullToRefreshListView.this.setEmptyView(emptyView); - } - - @Override - public void setEmptyViewInternal(View emptyView) { - super.setEmptyView(emptyView); - } - - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshScrollView.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshScrollView.java deleted file mode 100644 index 3ae3627f..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshScrollView.java +++ /dev/null @@ -1,109 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.util.AttributeSet; -import android.view.View; -import android.widget.ScrollView; - -public class PullToRefreshScrollView extends PullToRefreshBase<ScrollView> { - - public PullToRefreshScrollView(Context context) { - super(context); - } - - public PullToRefreshScrollView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public PullToRefreshScrollView(Context context, Mode mode) { - super(context, mode); - } - - public PullToRefreshScrollView(Context context, Mode mode, AnimationStyle style) { - super(context, mode, style); - } - - @Override - public final Orientation getPullToRefreshScrollDirection() { - return Orientation.VERTICAL; - } - - @Override - protected ScrollView createRefreshableView(Context context, AttributeSet attrs) { - ScrollView scrollView; - if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { - scrollView = new InternalScrollViewSDK9(context, attrs); - } else { - scrollView = new ScrollView(context, attrs); - } - - scrollView.setId(R.id.scrollview); - return scrollView; - } - - @Override - protected boolean isReadyForPullStart() { - return mRefreshableView.getScrollY() == 0; - } - - @Override - protected boolean isReadyForPullEnd() { - View scrollViewChild = mRefreshableView.getChildAt(0); - if (null != scrollViewChild) { - return mRefreshableView.getScrollY() >= (scrollViewChild.getHeight() - getHeight()); - } - return false; - } - - @TargetApi(9) - final class InternalScrollViewSDK9 extends ScrollView { - - public InternalScrollViewSDK9(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, - int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { - - final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, - scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); - - // Does all of the hard work... - OverscrollHelper.overScrollBy(PullToRefreshScrollView.this, deltaX, scrollX, deltaY, scrollY, - getScrollRange(), isTouchEvent); - - return returnValue; - } - - /** - * Taken from the AOSP ScrollView source - */ - private int getScrollRange() { - int scrollRange = 0; - if (getChildCount() > 0) { - View child = getChildAt(0); - scrollRange = Math.max(0, child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop())); - } - return scrollRange; - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshWebView.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshWebView.java deleted file mode 100644 index a008e424..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/PullToRefreshWebView.java +++ /dev/null @@ -1,164 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.os.Bundle; -import android.util.AttributeSet; -import android.webkit.WebChromeClient; -import android.webkit.WebView; - -public class PullToRefreshWebView extends PullToRefreshBase<WebView> { - - private static final OnRefreshListener<WebView> defaultOnRefreshListener = new OnRefreshListener<WebView>() { - - @Override - public void onRefresh(PullToRefreshBase<WebView> refreshView) { - refreshView.getRefreshableView().reload(); - } - - }; - - private final WebChromeClient defaultWebChromeClient = new WebChromeClient() { - - @Override - public void onProgressChanged(WebView view, int newProgress) { - if (newProgress == 100) { - onRefreshComplete(); - } - } - - }; - - public PullToRefreshWebView(Context context) { - super(context); - - /** - * Added so that by default, Pull-to-Refresh refreshes the page - */ - setOnRefreshListener(defaultOnRefreshListener); - mRefreshableView.setWebChromeClient(defaultWebChromeClient); - } - - public PullToRefreshWebView(Context context, AttributeSet attrs) { - super(context, attrs); - - /** - * Added so that by default, Pull-to-Refresh refreshes the page - */ - setOnRefreshListener(defaultOnRefreshListener); - mRefreshableView.setWebChromeClient(defaultWebChromeClient); - } - - public PullToRefreshWebView(Context context, Mode mode) { - super(context, mode); - - /** - * Added so that by default, Pull-to-Refresh refreshes the page - */ - setOnRefreshListener(defaultOnRefreshListener); - mRefreshableView.setWebChromeClient(defaultWebChromeClient); - } - - public PullToRefreshWebView(Context context, Mode mode, AnimationStyle style) { - super(context, mode, style); - - /** - * Added so that by default, Pull-to-Refresh refreshes the page - */ - setOnRefreshListener(defaultOnRefreshListener); - mRefreshableView.setWebChromeClient(defaultWebChromeClient); - } - - @Override - public final Orientation getPullToRefreshScrollDirection() { - return Orientation.VERTICAL; - } - - @Override - protected WebView createRefreshableView(Context context, AttributeSet attrs) { - WebView webView; - if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { - webView = new InternalWebViewSDK9(context, attrs); - } else { - webView = new WebView(context, attrs); - } - - webView.setId(R.id.webview); - return webView; - } - - @Override - protected boolean isReadyForPullStart() { - return mRefreshableView.getScrollY() == 0; - } - - @Override - protected boolean isReadyForPullEnd() { - float exactContentHeight = (float) Math.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale()); - return mRefreshableView.getScrollY() >= (exactContentHeight - mRefreshableView.getHeight()); - } - - @Override - protected void onPtrRestoreInstanceState(Bundle savedInstanceState) { - super.onPtrRestoreInstanceState(savedInstanceState); - mRefreshableView.restoreState(savedInstanceState); - } - - @Override - protected void onPtrSaveInstanceState(Bundle saveState) { - super.onPtrSaveInstanceState(saveState); - mRefreshableView.saveState(saveState); - } - - @TargetApi(9) - final class InternalWebViewSDK9 extends WebView { - - // WebView doesn't always scroll back to it's edge so we add some - // fuzziness - static final int OVERSCROLL_FUZZY_THRESHOLD = 2; - - // WebView seems quite reluctant to overscroll so we use the scale - // factor to scale it's value - static final float OVERSCROLL_SCALE_FACTOR = 1.5f; - - public InternalWebViewSDK9(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, - int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { - - final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, - scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); - - // Does all of the hard work... - OverscrollHelper.overScrollBy(PullToRefreshWebView.this, deltaX, scrollX, deltaY, scrollY, - getScrollRange(), OVERSCROLL_FUZZY_THRESHOLD, OVERSCROLL_SCALE_FACTOR, isTouchEvent); - - return returnValue; - } - - private int getScrollRange() { - return (int) Math.max(0, Math.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale()) - - (getHeight() - getPaddingBottom() - getPaddingTop())); - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java deleted file mode 100644 index 78192037..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java +++ /dev/null @@ -1,132 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.extras; - -import java.util.concurrent.atomic.AtomicBoolean; - -import android.content.Context; -import android.util.AttributeSet; -import android.webkit.WebView; - -import com.handmark.pulltorefresh.library.PullToRefreshWebView; - -/** - * An advanced version of {@link PullToRefreshWebView} which delegates the - * triggering of the PullToRefresh gesture to the Javascript running within the - * WebView. This means that you should only use this class if: - * <p/> - * <ul> - * <li>{@link PullToRefreshWebView} doesn't work correctly because you're using - * <code>overflow:scroll</code> or something else which means - * {@link WebView#getScrollY()} doesn't return correct values.</li> - * <li>You control the web content being displayed, as you need to write some - * Javascript callbacks.</li> - * </ul> - * <p/> - * <p/> - * The way this call works is that when a PullToRefresh gesture is in action, - * the following Javascript methods will be called: - * <code>isReadyForPullDown()</code> and <code>isReadyForPullUp()</code>, it is - * your job to calculate whether the view is in a state where a PullToRefresh - * can happen, and return the result via the callback mechanism. An example can - * be seen below: - * <p/> - * - * <pre> - * function isReadyForPullDown() { - * var result = ... // Probably using the .scrollTop DOM attribute - * ptr.isReadyForPullDownResponse(result); - * } - * - * function isReadyForPullUp() { - * var result = ... // Probably using the .scrollBottom DOM attribute - * ptr.isReadyForPullUpResponse(result); - * } - * </pre> - * - * @author Chris Banes - */ -public class PullToRefreshWebView2 extends PullToRefreshWebView { - - static final String JS_INTERFACE_PKG = "ptr"; - static final String DEF_JS_READY_PULL_DOWN_CALL = "javascript:isReadyForPullDown();"; - static final String DEF_JS_READY_PULL_UP_CALL = "javascript:isReadyForPullUp();"; - - public PullToRefreshWebView2(Context context) { - super(context); - } - - public PullToRefreshWebView2(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public PullToRefreshWebView2(Context context, Mode mode) { - super(context, mode); - } - - private JsValueCallback mJsCallback; - private final AtomicBoolean mIsReadyForPullDown = new AtomicBoolean(false); - private final AtomicBoolean mIsReadyForPullUp = new AtomicBoolean(false); - - @Override - protected WebView createRefreshableView(Context context, AttributeSet attrs) { - WebView webView = super.createRefreshableView(context, attrs); - - // Need to add JS Interface so we can get the response back - mJsCallback = new JsValueCallback(); - webView.addJavascriptInterface(mJsCallback, JS_INTERFACE_PKG); - - return webView; - } - - @Override - protected boolean isReadyForPullStart() { - // Call Javascript... - getRefreshableView().loadUrl(DEF_JS_READY_PULL_DOWN_CALL); - - // Response will be given to JsValueCallback, which will update - // mIsReadyForPullDown - - return mIsReadyForPullDown.get(); - } - - @Override - protected boolean isReadyForPullEnd() { - // Call Javascript... - getRefreshableView().loadUrl(DEF_JS_READY_PULL_UP_CALL); - - // Response will be given to JsValueCallback, which will update - // mIsReadyForPullUp - - return mIsReadyForPullUp.get(); - } - - /** - * Used for response from Javascript - * - * @author Chris Banes - */ - final class JsValueCallback { - - public void isReadyForPullUpResponse(boolean response) { - mIsReadyForPullUp.set(response); - } - - public void isReadyForPullDownResponse(boolean response) { - mIsReadyForPullDown.set(response); - } - } -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/SoundPullEventListener.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/SoundPullEventListener.java deleted file mode 100644 index a7aac306..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/extras/SoundPullEventListener.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.extras; - -import java.util.HashMap; - -import android.content.Context; -import android.media.MediaPlayer; -import android.view.View; - -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; -import com.handmark.pulltorefresh.library.PullToRefreshBase.State; - -public class SoundPullEventListener<V extends View> implements PullToRefreshBase.OnPullEventListener<V> { - - private final Context mContext; - private final HashMap<State, Integer> mSoundMap; - - private MediaPlayer mCurrentMediaPlayer; - - /** - * Constructor - * - * @param context - Context - */ - public SoundPullEventListener(Context context) { - mContext = context; - mSoundMap = new HashMap<State, Integer>(); - } - - @Override - public final void onPullEvent(PullToRefreshBase<V> refreshView, State event, Mode direction) { - Integer soundResIdObj = mSoundMap.get(event); - if (null != soundResIdObj) { - playSound(soundResIdObj.intValue()); - } - } - - /** - * Set the Sounds to be played when a Pull Event happens. You specify which - * sound plays for which events by calling this method multiple times for - * each event. - * <p/> - * If you've already set a sound for a certain event, and add another sound - * for that event, only the new sound will be played. - * - * @param event - The event for which the sound will be played. - * @param resId - Resource Id of the sound file to be played (e.g. - * <var>R.raw.pull_sound</var>) - */ - public void addSoundEvent(State event, int resId) { - mSoundMap.put(event, resId); - } - - /** - * Clears all of the previously set sounds and events. - */ - public void clearSounds() { - mSoundMap.clear(); - } - - /** - * Gets the current (or last) MediaPlayer instance. - */ - public MediaPlayer getCurrentMediaPlayer() { - return mCurrentMediaPlayer; - } - - private void playSound(int resId) { - // Stop current player, if there's one playing - if (null != mCurrentMediaPlayer) { - mCurrentMediaPlayer.stop(); - mCurrentMediaPlayer.release(); - } - - mCurrentMediaPlayer = MediaPlayer.create(mContext, resId); - if (null != mCurrentMediaPlayer) { - mCurrentMediaPlayer.start(); - } - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/EmptyViewMethodAccessor.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/EmptyViewMethodAccessor.java deleted file mode 100644 index 369f21e8..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/EmptyViewMethodAccessor.java +++ /dev/null @@ -1,43 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.internal; - -import android.view.View; - -/** - * Interface that allows PullToRefreshBase to hijack the call to - * AdapterView.setEmptyView() - * - * @author chris - */ -public interface EmptyViewMethodAccessor { - - /** - * Calls upto AdapterView.setEmptyView() - * - * @param emptyView - to set as Empty View - */ - public void setEmptyViewInternal(View emptyView); - - /** - * Should call PullToRefreshBase.setEmptyView() which will then - * automatically call through to setEmptyViewInternal() - * - * @param emptyView - to set as Empty View - */ - public void setEmptyView(View emptyView); - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/FlipLoadingLayout.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/FlipLoadingLayout.java deleted file mode 100644 index fef31605..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/FlipLoadingLayout.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.internal; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Matrix; -import android.graphics.drawable.Drawable; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.Animation; -import android.view.animation.RotateAnimation; -import android.widget.ImageView.ScaleType; - -import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; -import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation; -import com.handmark.pulltorefresh.library.R; - -@SuppressLint("ViewConstructor") -public class FlipLoadingLayout extends LoadingLayout { - - static final int FLIP_ANIMATION_DURATION = 150; - - private final Animation mRotateAnimation, mResetRotateAnimation; - - public FlipLoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) { - super(context, mode, scrollDirection, attrs); - - final int rotateAngle = mode == Mode.PULL_FROM_START ? -180 : 180; - - mRotateAnimation = new RotateAnimation(0, rotateAngle, Animation.RELATIVE_TO_SELF, 0.5f, - Animation.RELATIVE_TO_SELF, 0.5f); - mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR); - mRotateAnimation.setDuration(FLIP_ANIMATION_DURATION); - mRotateAnimation.setFillAfter(true); - - mResetRotateAnimation = new RotateAnimation(rotateAngle, 0, Animation.RELATIVE_TO_SELF, 0.5f, - Animation.RELATIVE_TO_SELF, 0.5f); - mResetRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR); - mResetRotateAnimation.setDuration(FLIP_ANIMATION_DURATION); - mResetRotateAnimation.setFillAfter(true); - } - - @Override - protected void onLoadingDrawableSet(Drawable imageDrawable) { - if (null != imageDrawable) { - final int dHeight = imageDrawable.getIntrinsicHeight(); - final int dWidth = imageDrawable.getIntrinsicWidth(); - - /** - * We need to set the width/height of the ImageView so that it is - * square with each side the size of the largest drawable dimension. - * This is so that it doesn't clip when rotated. - */ - ViewGroup.LayoutParams lp = mHeaderImage.getLayoutParams(); - lp.width = lp.height = Math.max(dHeight, dWidth); - mHeaderImage.requestLayout(); - - /** - * We now rotate the Drawable so that is at the correct rotation, - * and is centered. - */ - mHeaderImage.setScaleType(ScaleType.MATRIX); - Matrix matrix = new Matrix(); - matrix.postTranslate((lp.width - dWidth) / 2f, (lp.height - dHeight) / 2f); - matrix.postRotate(getDrawableRotationAngle(), lp.width / 2f, lp.height / 2f); - mHeaderImage.setImageMatrix(matrix); - } - } - - @Override - protected void onPullImpl(float scaleOfLayout) { - // NO-OP - } - - @Override - protected void pullToRefreshImpl() { - // Only start reset Animation, we've previously show the rotate anim - if (mRotateAnimation == mHeaderImage.getAnimation()) { - mHeaderImage.startAnimation(mResetRotateAnimation); - } - } - - @Override - protected void refreshingImpl() { - mHeaderImage.clearAnimation(); - mHeaderImage.setVisibility(View.INVISIBLE); - mHeaderProgress.setVisibility(View.VISIBLE); - } - - @Override - protected void releaseToRefreshImpl() { - mHeaderImage.startAnimation(mRotateAnimation); - } - - @Override - protected void resetImpl() { - mHeaderImage.clearAnimation(); - mHeaderProgress.setVisibility(View.GONE); - mHeaderImage.setVisibility(View.VISIBLE); - } - - @Override - protected int getDefaultDrawableResId() { - return R.drawable.default_ptr_flip; - } - - private float getDrawableRotationAngle() { - float angle = 0f; - switch (mMode) { - case PULL_FROM_END: - if (mScrollDirection == Orientation.HORIZONTAL) { - angle = 90f; - } else { - angle = 180f; - } - break; - - case PULL_FROM_START: - if (mScrollDirection == Orientation.HORIZONTAL) { - angle = 270f; - } - break; - - default: - break; - } - - return angle; - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/IndicatorLayout.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/IndicatorLayout.java deleted file mode 100644 index a9069f2a..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/IndicatorLayout.java +++ /dev/null @@ -1,147 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.internal; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Matrix; -import android.graphics.drawable.Drawable; -import android.view.View; -import android.view.animation.Animation; -import android.view.animation.Animation.AnimationListener; -import android.view.animation.AnimationUtils; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; -import android.view.animation.RotateAnimation; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ImageView.ScaleType; - -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.R; - -@SuppressLint("ViewConstructor") -public class IndicatorLayout extends FrameLayout implements AnimationListener { - - static final int DEFAULT_ROTATION_ANIMATION_DURATION = 150; - - private Animation mInAnim, mOutAnim; - private ImageView mArrowImageView; - - private final Animation mRotateAnimation, mResetRotateAnimation; - - public IndicatorLayout(Context context, PullToRefreshBase.Mode mode) { - super(context); - mArrowImageView = new ImageView(context); - - Drawable arrowD = getResources().getDrawable(R.drawable.indicator_arrow); - mArrowImageView.setImageDrawable(arrowD); - - final int padding = getResources().getDimensionPixelSize(R.dimen.indicator_internal_padding); - mArrowImageView.setPadding(padding, padding, padding, padding); - addView(mArrowImageView); - - int inAnimResId, outAnimResId; - switch (mode) { - case PULL_FROM_END: - inAnimResId = R.anim.slide_in_from_bottom; - outAnimResId = R.anim.slide_out_to_bottom; - setBackgroundResource(R.drawable.indicator_bg_bottom); - - // Rotate Arrow so it's pointing the correct way - mArrowImageView.setScaleType(ScaleType.MATRIX); - Matrix matrix = new Matrix(); - matrix.setRotate(180f, arrowD.getIntrinsicWidth() / 2f, arrowD.getIntrinsicHeight() / 2f); - mArrowImageView.setImageMatrix(matrix); - break; - default: - case PULL_FROM_START: - inAnimResId = R.anim.slide_in_from_top; - outAnimResId = R.anim.slide_out_to_top; - setBackgroundResource(R.drawable.indicator_bg_top); - break; - } - - mInAnim = AnimationUtils.loadAnimation(context, inAnimResId); - mInAnim.setAnimationListener(this); - - mOutAnim = AnimationUtils.loadAnimation(context, outAnimResId); - mOutAnim.setAnimationListener(this); - - final Interpolator interpolator = new LinearInterpolator(); - mRotateAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, - 0.5f); - mRotateAnimation.setInterpolator(interpolator); - mRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION); - mRotateAnimation.setFillAfter(true); - - mResetRotateAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, - Animation.RELATIVE_TO_SELF, 0.5f); - mResetRotateAnimation.setInterpolator(interpolator); - mResetRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION); - mResetRotateAnimation.setFillAfter(true); - - } - - public final boolean isVisible() { - Animation currentAnim = getAnimation(); - if (null != currentAnim) { - return mInAnim == currentAnim; - } - - return getVisibility() == View.VISIBLE; - } - - public void hide() { - startAnimation(mOutAnim); - } - - public void show() { - mArrowImageView.clearAnimation(); - startAnimation(mInAnim); - } - - @Override - public void onAnimationEnd(Animation animation) { - if (animation == mOutAnim) { - mArrowImageView.clearAnimation(); - setVisibility(View.GONE); - } else if (animation == mInAnim) { - setVisibility(View.VISIBLE); - } - - clearAnimation(); - } - - @Override - public void onAnimationRepeat(Animation animation) { - // NO-OP - } - - @Override - public void onAnimationStart(Animation animation) { - setVisibility(View.VISIBLE); - } - - public void releaseToRefresh() { - mArrowImageView.startAnimation(mRotateAnimation); - } - - public void pullToRefresh() { - mArrowImageView.startAnimation(mResetRotateAnimation); - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/LoadingLayout.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/LoadingLayout.java deleted file mode 100644 index 9c12586d..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/LoadingLayout.java +++ /dev/null @@ -1,393 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.internal; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.res.ColorStateList; -import android.content.res.TypedArray; -import android.graphics.Typeface; -import android.graphics.drawable.AnimationDrawable; -import android.graphics.drawable.Drawable; -import android.text.TextUtils; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.Interpolator; -import android.view.animation.LinearInterpolator; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.TextView; - -import com.handmark.pulltorefresh.library.ILoadingLayout; -import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; -import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation; -import com.handmark.pulltorefresh.library.R; - -@SuppressLint("ViewConstructor") -public abstract class LoadingLayout extends FrameLayout implements ILoadingLayout { - - static final String LOG_TAG = "PullToRefresh-LoadingLayout"; - - static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator(); - - private FrameLayout mInnerLayout; - - protected final ImageView mHeaderImage; - protected final ProgressBar mHeaderProgress; - - private boolean mUseIntrinsicAnimation; - - private final TextView mHeaderText; - private final TextView mSubHeaderText; - - protected final Mode mMode; - protected final Orientation mScrollDirection; - - private CharSequence mPullLabel; - private CharSequence mRefreshingLabel; - private CharSequence mReleaseLabel; - - public LoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) { - super(context); - mMode = mode; - mScrollDirection = scrollDirection; - - switch (scrollDirection) { - case HORIZONTAL: - LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_horizontal, this); - break; - case VERTICAL: - default: - LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_vertical, this); - break; - } - - mInnerLayout = (FrameLayout) findViewById(R.id.fl_inner); - mHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_text); - mHeaderProgress = (ProgressBar) mInnerLayout.findViewById(R.id.pull_to_refresh_progress); - mSubHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_sub_text); - mHeaderImage = (ImageView) mInnerLayout.findViewById(R.id.pull_to_refresh_image); - - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInnerLayout.getLayoutParams(); - - switch (mode) { - case PULL_FROM_END: - lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.TOP : Gravity.LEFT; - - // Load in labels - mPullLabel = context.getString(R.string.pull_to_refresh_from_bottom_pull_label); - mRefreshingLabel = context.getString(R.string.pull_to_refresh_from_bottom_refreshing_label); - mReleaseLabel = context.getString(R.string.pull_to_refresh_from_bottom_release_label); - break; - - case PULL_FROM_START: - default: - lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.BOTTOM : Gravity.RIGHT; - - // Load in labels - mPullLabel = context.getString(R.string.pull_to_refresh_pull_label); - mRefreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label); - mReleaseLabel = context.getString(R.string.pull_to_refresh_release_label); - break; - } - - if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderBackground)) { - Drawable background = attrs.getDrawable(R.styleable.PullToRefresh_ptrHeaderBackground); - if (null != background) { - ViewCompat.setBackground(this, background); - } - } - - if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance)) { - TypedValue styleID = new TypedValue(); - attrs.getValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance, styleID); - setTextAppearance(styleID.data); - } - if (attrs.hasValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance)) { - TypedValue styleID = new TypedValue(); - attrs.getValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance, styleID); - setSubTextAppearance(styleID.data); - } - - // Text Color attrs need to be set after TextAppearance attrs - if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextColor)) { - ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderTextColor); - if (null != colors) { - setTextColor(colors); - } - } - if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderSubTextColor)) { - ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderSubTextColor); - if (null != colors) { - setSubTextColor(colors); - } - } - - // Try and get defined drawable from Attrs - Drawable imageDrawable = null; - if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawable)) { - imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawable); - } - - // Check Specific Drawable from Attrs, these overrite the generic - // drawable attr above - switch (mode) { - case PULL_FROM_START: - default: - if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableStart)) { - imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableStart); - } else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableTop)) { - Utils.warnDeprecation("ptrDrawableTop", "ptrDrawableStart"); - imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableTop); - } - break; - - case PULL_FROM_END: - if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableEnd)) { - imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableEnd); - } else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableBottom)) { - Utils.warnDeprecation("ptrDrawableBottom", "ptrDrawableEnd"); - imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableBottom); - } - break; - } - - // If we don't have a user defined drawable, load the default - if (null == imageDrawable) { - imageDrawable = context.getResources().getDrawable(getDefaultDrawableResId()); - } - - // Set Drawable, and save width/height - setLoadingDrawable(imageDrawable); - - reset(); - } - - public final void setHeight(int height) { - ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getLayoutParams(); - lp.height = height; - requestLayout(); - } - - public final void setWidth(int width) { - ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getLayoutParams(); - lp.width = width; - requestLayout(); - } - - public final int getContentSize() { - switch (mScrollDirection) { - case HORIZONTAL: - return mInnerLayout.getWidth(); - case VERTICAL: - default: - return mInnerLayout.getHeight(); - } - } - - public final void hideAllViews() { - if (View.VISIBLE == mHeaderText.getVisibility()) { - mHeaderText.setVisibility(View.INVISIBLE); - } - if (View.VISIBLE == mHeaderProgress.getVisibility()) { - mHeaderProgress.setVisibility(View.INVISIBLE); - } - if (View.VISIBLE == mHeaderImage.getVisibility()) { - mHeaderImage.setVisibility(View.INVISIBLE); - } - if (View.VISIBLE == mSubHeaderText.getVisibility()) { - mSubHeaderText.setVisibility(View.INVISIBLE); - } - } - - public final void onPull(float scaleOfLayout) { - if (!mUseIntrinsicAnimation) { - onPullImpl(scaleOfLayout); - } - } - - public final void pullToRefresh() { - if (null != mHeaderText) { - mHeaderText.setText(mPullLabel); - } - - // Now call the callback - pullToRefreshImpl(); - } - - public final void refreshing() { - if (null != mHeaderText) { - mHeaderText.setText(mRefreshingLabel); - } - - if (mUseIntrinsicAnimation) { - ((AnimationDrawable) mHeaderImage.getDrawable()).start(); - } else { - // Now call the callback - refreshingImpl(); - } - - if (null != mSubHeaderText) { - mSubHeaderText.setVisibility(View.GONE); - } - } - - public final void releaseToRefresh() { - if (null != mHeaderText) { - mHeaderText.setText(mReleaseLabel); - } - - // Now call the callback - releaseToRefreshImpl(); - } - - public final void reset() { - if (null != mHeaderText) { - mHeaderText.setText(mPullLabel); - } - mHeaderImage.setVisibility(View.VISIBLE); - - if (mUseIntrinsicAnimation) { - ((AnimationDrawable) mHeaderImage.getDrawable()).stop(); - } else { - // Now call the callback - resetImpl(); - } - - if (null != mSubHeaderText) { - if (TextUtils.isEmpty(mSubHeaderText.getText())) { - mSubHeaderText.setVisibility(View.GONE); - } else { - mSubHeaderText.setVisibility(View.VISIBLE); - } - } - } - - @Override - public void setLastUpdatedLabel(CharSequence label) { - setSubHeaderText(label); - } - - public final void setLoadingDrawable(Drawable imageDrawable) { - // Set Drawable - mHeaderImage.setImageDrawable(imageDrawable); - mUseIntrinsicAnimation = (imageDrawable instanceof AnimationDrawable); - - // Now call the callback - onLoadingDrawableSet(imageDrawable); - } - - public void setPullLabel(CharSequence pullLabel) { - mPullLabel = pullLabel; - } - - public void setRefreshingLabel(CharSequence refreshingLabel) { - mRefreshingLabel = refreshingLabel; - } - - public void setReleaseLabel(CharSequence releaseLabel) { - mReleaseLabel = releaseLabel; - } - - @Override - public void setTextTypeface(Typeface tf) { - mHeaderText.setTypeface(tf); - } - - public final void showInvisibleViews() { - if (View.INVISIBLE == mHeaderText.getVisibility()) { - mHeaderText.setVisibility(View.VISIBLE); - } - if (View.INVISIBLE == mHeaderProgress.getVisibility()) { - mHeaderProgress.setVisibility(View.VISIBLE); - } - if (View.INVISIBLE == mHeaderImage.getVisibility()) { - mHeaderImage.setVisibility(View.VISIBLE); - } - if (View.INVISIBLE == mSubHeaderText.getVisibility()) { - mSubHeaderText.setVisibility(View.VISIBLE); - } - } - - /** - * Callbacks for derivative Layouts - */ - - protected abstract int getDefaultDrawableResId(); - - protected abstract void onLoadingDrawableSet(Drawable imageDrawable); - - protected abstract void onPullImpl(float scaleOfLayout); - - protected abstract void pullToRefreshImpl(); - - protected abstract void refreshingImpl(); - - protected abstract void releaseToRefreshImpl(); - - protected abstract void resetImpl(); - - private void setSubHeaderText(CharSequence label) { - if (null != mSubHeaderText) { - if (TextUtils.isEmpty(label)) { - mSubHeaderText.setVisibility(View.GONE); - } else { - mSubHeaderText.setText(label); - - // Only set it to Visible if we're GONE, otherwise VISIBLE will - // be set soon - if (View.GONE == mSubHeaderText.getVisibility()) { - mSubHeaderText.setVisibility(View.VISIBLE); - } - } - } - } - - private void setSubTextAppearance(int value) { - if (null != mSubHeaderText) { - mSubHeaderText.setTextAppearance(getContext(), value); - } - } - - private void setSubTextColor(ColorStateList color) { - if (null != mSubHeaderText) { - mSubHeaderText.setTextColor(color); - } - } - - private void setTextAppearance(int value) { - if (null != mHeaderText) { - mHeaderText.setTextAppearance(getContext(), value); - } - if (null != mSubHeaderText) { - mSubHeaderText.setTextAppearance(getContext(), value); - } - } - - private void setTextColor(ColorStateList color) { - if (null != mHeaderText) { - mHeaderText.setTextColor(color); - } - if (null != mSubHeaderText) { - mSubHeaderText.setTextColor(color); - } - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java deleted file mode 100644 index bda7b2fc..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java +++ /dev/null @@ -1,110 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.internal; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Matrix; -import android.graphics.drawable.Drawable; -import android.view.animation.Animation; -import android.view.animation.RotateAnimation; -import android.widget.ImageView.ScaleType; - -import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; -import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation; -import com.handmark.pulltorefresh.library.R; - -public class RotateLoadingLayout extends LoadingLayout { - - static final int ROTATION_ANIMATION_DURATION = 1200; - - private final Animation mRotateAnimation; - private final Matrix mHeaderImageMatrix; - - private float mRotationPivotX, mRotationPivotY; - - private final boolean mRotateDrawableWhilePulling; - - public RotateLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) { - super(context, mode, scrollDirection, attrs); - - mRotateDrawableWhilePulling = attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true); - - mHeaderImage.setScaleType(ScaleType.MATRIX); - mHeaderImageMatrix = new Matrix(); - mHeaderImage.setImageMatrix(mHeaderImageMatrix); - - mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, - 0.5f); - mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR); - mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION); - mRotateAnimation.setRepeatCount(Animation.INFINITE); - mRotateAnimation.setRepeatMode(Animation.RESTART); - } - - public void onLoadingDrawableSet(Drawable imageDrawable) { - if (null != imageDrawable) { - mRotationPivotX = Math.round(imageDrawable.getIntrinsicWidth() / 2f); - mRotationPivotY = Math.round(imageDrawable.getIntrinsicHeight() / 2f); - } - } - - protected void onPullImpl(float scaleOfLayout) { - float angle; - if (mRotateDrawableWhilePulling) { - angle = scaleOfLayout * 90f; - } else { - angle = Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f)); - } - - mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY); - mHeaderImage.setImageMatrix(mHeaderImageMatrix); - } - - @Override - protected void refreshingImpl() { - mHeaderImage.startAnimation(mRotateAnimation); - } - - @Override - protected void resetImpl() { - mHeaderImage.clearAnimation(); - resetImageRotation(); - } - - private void resetImageRotation() { - if (null != mHeaderImageMatrix) { - mHeaderImageMatrix.reset(); - mHeaderImage.setImageMatrix(mHeaderImageMatrix); - } - } - - @Override - protected void pullToRefreshImpl() { - // NO-OP - } - - @Override - protected void releaseToRefreshImpl() { - // NO-OP - } - - @Override - protected int getDefaultDrawableResId() { - return R.drawable.default_ptr_rotate; - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/Utils.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/Utils.java deleted file mode 100644 index 73432189..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/Utils.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.handmark.pulltorefresh.library.internal; - -import android.util.Log; - -public class Utils { - - static final String LOG_TAG = "PullToRefresh"; - - public static void warnDeprecation(String depreacted, String replacement) { - Log.w(LOG_TAG, "You're using the deprecated " + depreacted + " attr, please switch over to " + replacement); - } - -} diff --git a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java b/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java deleted file mode 100644 index 618bace0..00000000 --- a/core/pulltorefresh/src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright 2011, 2012 Chris Banes. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *******************************************************************************/ -package com.handmark.pulltorefresh.library.internal; - -import android.annotation.TargetApi; -import android.graphics.drawable.Drawable; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.view.View; - -@SuppressWarnings("deprecation") -public class ViewCompat { - - public static void postOnAnimation(View view, Runnable runnable) { - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { - SDK16.postOnAnimation(view, runnable); - } else { - view.postDelayed(runnable, 16); - } - } - - public static void setBackground(View view, Drawable background) { - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { - SDK16.setBackground(view, background); - } else { - view.setBackgroundDrawable(background); - } - } - - public static void setLayerType(View view, int layerType) { - if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) { - SDK11.setLayerType(view, layerType); - } - } - - @TargetApi(11) - static class SDK11 { - - public static void setLayerType(View view, int layerType) { - view.setLayerType(layerType, null); - } - } - - @TargetApi(16) - static class SDK16 { - - public static void postOnAnimation(View view, Runnable runnable) { - view.postOnAnimation(runnable); - } - - public static void setBackground(View view, Drawable background) { - view.setBackground(background); - } - - } - -} diff --git a/core/pulltorefresh/src/main/res/anim/slide_in_from_bottom.xml b/core/pulltorefresh/src/main/res/anim/slide_in_from_bottom.xml deleted file mode 100644 index bb430ce9..00000000 --- a/core/pulltorefresh/src/main/res/anim/slide_in_from_bottom.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<translate xmlns:android="http://schemas.android.com/apk/res/android" - android:duration="@android:integer/config_longAnimTime" - android:fromYDelta="100%p" - android:toYDelta="0" /> diff --git a/core/pulltorefresh/src/main/res/anim/slide_in_from_top.xml b/core/pulltorefresh/src/main/res/anim/slide_in_from_top.xml deleted file mode 100644 index 52d91afc..00000000 --- a/core/pulltorefresh/src/main/res/anim/slide_in_from_top.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<translate xmlns:android="http://schemas.android.com/apk/res/android" - android:duration="@android:integer/config_longAnimTime" - android:fromYDelta="-100%p" - android:toYDelta="0" /> diff --git a/core/pulltorefresh/src/main/res/anim/slide_out_to_bottom.xml b/core/pulltorefresh/src/main/res/anim/slide_out_to_bottom.xml deleted file mode 100644 index 83eca5ad..00000000 --- a/core/pulltorefresh/src/main/res/anim/slide_out_to_bottom.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<translate xmlns:android="http://schemas.android.com/apk/res/android" - android:duration="@android:integer/config_longAnimTime" - android:fromYDelta="0" - android:toYDelta="100%p" /> diff --git a/core/pulltorefresh/src/main/res/anim/slide_out_to_top.xml b/core/pulltorefresh/src/main/res/anim/slide_out_to_top.xml deleted file mode 100644 index 5105ae1f..00000000 --- a/core/pulltorefresh/src/main/res/anim/slide_out_to_top.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- - Copyright (C) 2009 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> - -<translate xmlns:android="http://schemas.android.com/apk/res/android" - android:duration="@android:integer/config_longAnimTime" - android:fromYDelta="0" - android:toYDelta="-100%p" /> diff --git a/core/pulltorefresh/src/main/res/drawable-hdpi/default_ptr_flip.png b/core/pulltorefresh/src/main/res/drawable-hdpi/default_ptr_flip.png deleted file mode 100644 index 0a2c0bd9bb4907fc43e8ba68e3b9b6fefd6d84ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1835 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 a+Ju$p-kaba>tx`1KsXlyru;kqAO8vU6*3Y4 diff --git a/core/pulltorefresh/src/main/res/drawable-hdpi/default_ptr_rotate.png b/core/pulltorefresh/src/main/res/drawable-hdpi/default_ptr_rotate.png deleted file mode 100644 index dc641b72459953994dd5800438f559dc4659f228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48963 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 diff --git a/core/pulltorefresh/src/main/res/drawable-hdpi/indicator_arrow.png b/core/pulltorefresh/src/main/res/drawable-hdpi/indicator_arrow.png deleted file mode 100644 index 8ae79770973e4fd85f994c0f6edff5eb5ebae6c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 390 zcmeAS@N?(olHy`uVBq!ia0vp^LO`s}!VDxogtJxwDdu7)&kzm{j@u9Y9{{<!0X`wF z|Ns9_BN|MS+WZ};k-sF!FPK44$=D?{t-NFAs@-SqzH`(1Iuj_xS>O>_%)r16w3}Oq z@zUM8KR`j564!{5;QX|b^2DN42FH~Aq*MjB%%art{G#k)1?OPX!mW?Zfa=zIx;TbN zOifNmNDu*n1O`SmRaI416EP+Z#-kz!brO@4lbsE`j~qRERPc<`jHZOnwzf95MH>aG z1RZpNfU|dL91yfD<4c_F=I-t;EXDoMuI065`nfrljJ-#<W?fyyY7rqSdv|yF`+FBJ zo=ey(&17c0!7-APho|^l!vW6)PMHST$|pAMR$$nsCw^iF+eY3KO*fA1cz-wBBg5dv nzTG@uIbQE(m@z-CiG$&1ouAKL4X5QmhckG(`njxgN@xNA7&wZD diff --git a/core/pulltorefresh/src/main/res/drawable-mdpi/default_ptr_flip.png b/core/pulltorefresh/src/main/res/drawable-mdpi/default_ptr_flip.png deleted file mode 100644 index be696c1c634c04fbcef5c3ea03c1ef89ca4ab284..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1612 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 Rga~W{!nqP$O7{j_`WN%b-~Ipq diff --git a/core/pulltorefresh/src/main/res/drawable-mdpi/default_ptr_rotate.png b/core/pulltorefresh/src/main/res/drawable-mdpi/default_ptr_rotate.png deleted file mode 100644 index 95b22bd71c4f2ed6c91652ac255b62bb8461e38a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49665 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%0A>T0#(t2XSN{pdHLemJ|=iV;Q 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%0A-uWX&~N5)pN#W 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 diff --git a/core/pulltorefresh/src/main/res/drawable-mdpi/indicator_arrow.png b/core/pulltorefresh/src/main/res/drawable-mdpi/indicator_arrow.png deleted file mode 100644 index 20fe2c126ae700d57be9c7f19a0cf7296ece8055..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP)<h;3K|Lk000e1NJLTq000aC000^Y1^@s6gZjN;00004b3#c}2nYxW zd<bNS00009a7bBm000XT000XT0n*)m`~Uy|9CSrkbW?9;ba!ELWdK2BZ(?O2Mrm?o zcW-iQb09-gHF34$HUIztH%UZ6R5*=|ld(zzK@dP+yqHA9DxHPch=rtD>=Zx2#&4L) zK8=5n)@r~%(8dq25D}Ygf)-ju1T8`$8bu5W7I)FRVfVa&E$+=eW_IVcMlM984Kygm zR8>c_kGe@VfEFcTg=Zi!?7K`@0hSD#0CzFr3z!C2w8AiJtFq7m+J=pQ%b4&1yaiaa z!aeY0Sm8`o*aDUfdjw8n!Yj}WuxN!bW>COOnXn108a4p>F`*AU7*?2z6%t@Rz@owq zux{8ba1|3mzjxt%SfL3l1lVuXMC1fmq*}b!fi7@VQP@ws_haYWC$LR=L$P(Js^<xS z_x{>B*8$cdn=e$g2QZf_cR)JTmRW-=mmWIbponY$$NatP39zTCH?uv3DSGdR&bcwL no3+wa)w6%ELPS(VG?e=R;L=SFhh?BF00000NkvXXu0mjf7aXr< diff --git a/core/pulltorefresh/src/main/res/drawable-xhdpi/default_ptr_flip.png b/core/pulltorefresh/src/main/res/drawable-xhdpi/default_ptr_flip.png deleted file mode 100644 index 3e6ddba5c554ba6983077079125c30387e70fed8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1983 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 diff --git a/core/pulltorefresh/src/main/res/drawable-xhdpi/default_ptr_rotate.png b/core/pulltorefresh/src/main/res/drawable-xhdpi/default_ptr_rotate.png deleted file mode 100644 index 00225c9a2c5800ee8cc3ad4a123811f33b7f975e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50019 zcmcG#Wl$wS_vQ(WJ2VZA)3`P6PUG(G?(XjH?ygPa?(XjH?u~P?%U$~Y&+J6ZhuxT& z-Hghrr|M)zor<iJkrBT<5%RKPNborDU|?WK65_&&pI4gC$_NYnc@{#I=l#4uItfZB z!+sWTSmW@|dpLV>4JR-#_<?^FoP~<C;`1S%vxvI0lAWoun}MSV*e_!{Lz5q(7LF!v zc8*p~KZKOnPCM(P!N9((+dHbNxo2NxO{okpAo^EH_rqKF!{fPYYm`kefYo%=f|poi zF1nI(zdB$<rr^>)Qj9edPwZcu+;e*e$1R*W^AMnf37yWDNTrRS-l+DfKx1j++YbxT zK<Rt@{tgyePyobuH-E?GPdB3IV8Z6jId$|I+Xj*lDE-K?NPlD!HqzFP85MDLpS*_k z%Z7%XAiTW!`Zo366M%1lMsqm9UQ4)TpLJAouMs=)JPwu5q-(=(!rR-pK#xL@DD%A7 zib@40EZ*I1Va*%A!?OvO`7#1s%nYAh11G?dXV!z)bLYGE%@Aq)N)Ji>C4JXQK3vbP zd|a^5EfTGV2^pVC*!!3=1ZdZv=Bbw+Kzb}d8;;2zPyD84bzSW(-lgZ{^8!J2>&I1? zSksh;+?urb^&2?9hR@Q@&ewp6mGl^`vEKbM_o&FQX|Gc6w|gg*^ajwZciLJDZ`bWh z^)~3lTl|^sNNZ&mrqAuM<G$$h0QIdwc{<Im;mv)o6CBiBz$Q(Z?&p(eoH)cD>01fa z1ObX`D!%3FvjNK3S5%Ok`0wY+UXA+Nb-Qt0Bu=xoMxpKVZlY|T9mXO%ZFkJPF`V?f z#qfDilWpeZr728>*-hms)m=1vmDN#J56y966b{g|OMvn-xWAh5CD!m6>UT8h?WCSA zJGn3$GE*6XdVeIFHN9YN|CvI+rg!ga+BrwI%EooQ-pmjijnekzu6Lr$NX<a8{ZMox zIZlsu?h3{o6eK9m!%94@=Huc3KzIKG5*na)-Wi-?f50dXoj(02c==N-w(?di=dRMF z2Mt9U0wiB6?f1s*mItp;)*5B!wis$EvN_MzW8^v7@mEs2hVDLN472O8831Mn3>qmq z@Y#W}?+qL-7|YHzfU)e!f%~79tH1JUenf%u79n&V)!}4ErbfBn`<#8e)9JK3pZ)v& z#8T33aJC1u+~H@o|2R9u>wR}6M~p>RKKqOYaT_Z^(bw(qkALCwS^tj;RWWk`7#J6o zjg_*}XXN;-IpK;W`o@jaOK;Uvm=ZpPpmpH(gva2w(QEsXfCUy$K|uI_J^C(E6p-3l z8cRgAt_l4C&@)waadUBbj8IZUU_<ax^T~KoF;!JLI9+*~y1MVXd0)=pCB)0w!D-me zC;1lSN07JUX(VRnS+%xiFw(JPMz3+ZpMSBnzHANBhcvNbTgCTmK>})2m^5oXuIamb zBAYb<cKHZ^S&t|vcD5Tn&kJkVI$M@n>*`KTYMOdkme;!*ZLW;m9DIQ!fZb7U4nuR0 zf6>W$p8fEU^(-&;0j*o?*)+Gjjn#T~QwNOt(i7U^PEerc0>R&Ti2(w9+`me5e8o9e zdgZ5h_qdl&=3WeiNuD<A=SaUfOu55=_gdyEUW3T7t6O41Pw^zK{Hl1D`m}L%s;`w^ zhS@u81q`=rTj)`d1eYuY3>pRoj1wV~J>~Ip%}w~LUPv1tf4lGUT<aKk8I@m|jbtaI zO$=P~jGD`IzR(divfE#3W|bNmF<X~Xt)5C+YqJN&<OarU7_X|E8aN|n^&K#{<3Y<M z^(`3Ru$T>e*xe-GT5}wlfFR{7IBSFa#$a}pkoCp9P{tn#^dXnNl%UUi>kGz3&ore) zlA(afOe`%apt8tpP`@CBy>NjF9`Mb=$F5fle(*xJ$hy4McH+#B<IEQVTY%8nT!y~6 zBDu^m)~xy}HPG<gswGux-ZrPuH7j@yB6g1NvWL`#JGkgN)uaXLHQ>wY>BJEEV&44f zXr>Zm4$@Ng2;)@7LObTASf#9=x8(I#LA&3Nh(#25Bzv&dF<>=Lr$qEjEMuGU$n}`9 z3nXN++6|FLjjrTOil~1WgDnvYG-ZPcD1NYnT;X0Vn60H@E6`UA>;GX)$AeB9&{uqu zcSvvklD-XLpjT6yCFhc<-9f5#fryjytBBd$89HV<f9_;HKYoc{j9jvzL4?UQ&9nK| zY+}_^BAdWI+f_h_t{}{AU?(mdLF~dSR+W#o-xJ|x(IylHe`c`EqAVSE$n}e066c$5 z5|J@euytts6l%RjZ<u0?u=gq=yqdlk8X~aO1G4>zLVj5c^SOkiT)ENtM+|1zJYE^p z3{!GQ|H-_5W|g---@d-9z#bhX)IFCtyZ3lWatz!+{TUNw8G_@F2NszApAsNbW|UwN z@b#}?o(MZTR@V#6>YZsUm75>!1sg*hW0}+X#QnngosAEI*u~;&mE>|P>chnht~(Bw zy8bb`G#C{`1>`Q!77jmjalof0p{tyKq<^ntle2A-!Y-<@g5cmH*YQfTj1{%2dum0V z9RIq^AMiGFTL~-Z8bf3pO*VALJkB*RDnsJeSZtmAI|;-7k5fy^r9IU+S(cH&2XQC> z0&z!P_%slc^Vj;~N-gqZ)~NZ}T)c5w=ovMw(tbmzmiCl&E{#iTt_C`{+l~f7Z*v~! zk#r{E7*lR|<`E@X4q~YlCJgh9kR`cL5@Z^>j8SIRMfyp=4^OE44qO=w%z)@iHfHJk z<*%lvVMl|Nd`I}yznUf*00=6*;HNp9IsIv_8Ut5Jd9FFU&y?8JW+yj7JROkMd{+(~ zWJ_9|YlTh7J}2Kj;yn63(!!bM(*pVnTfT(Xsl5mTtuj`B;$$j>%QI1A!Duv$d3}SI zbTqWeptin1+~68$o~|{44A&dZ4W@l%3Ie8km>qBwqRFVeb%iG$e__%)sT56gMt@7a z?U%_)PX0Cv<M_jpW?_dZd>hGIQ0$GDq-fsQz8Nd~Fdx?b{QkUTYStLCTv-~=L_}cf zn}8LM49qmmL}g>Et)uh>-eP-Bac-Y_8A|C1Wk#bII+{JDWv~!z<iiV@KzkMbt)0>p z6H2E@<I-=L`(oq8>e)b^zn<2x-B)JD`v#JHmrrA?egirW?2Cjt)FT^XK15n8B;#Y* zx#^D7MHuI4ccDYmiggnxOIxt$-CCEhdeaZd-RU0mP>Ye)&a1IAhvG03axH|=ugTUa zj_189rhv)h9~{moQiBvyLUN?d3>>$&ESU?ixjPO#a^I8|*IA4sbq!VFx2d=rqw&o# z?Nb+Zp1W$Ui4vm?b3zhGF#EcaLr-opWR|xS{c44P;Cm5D`n7(wb)@th?4d#eC>@4) z`90$cG|w-5{0ep)3m)i?cq5s?M#>O#f5KQ~nA#?)?tcm4@HDDNaA?vEBuGX{_9xim zqUv@x2tH@5J#V4h3=nyR#nF@kDq@)iCyGLoEHnd$U6Ow}pzfBKN~33|X2T}ZVCAK; za_sTi`Jom@uXAAyLkMDY^8aZ-_AVyPn`4*6@u}_(eGAVeF)3?nUOxz*+Mvz?G^K<u z?5j?j2qb|&tJ5XV-J%}bprm&r!(^j8vz^!N9UTXheMvLKi$$#wE@R}67b=sHg|DWf zdJLxUR3FSMSQa3V{H?=hvv34?!DgbD-M9uSRCRtDiW^a&BmMCWHfk1w3ltx<57ozW zWPzHwtI=O`$HD5QVEL2{^=N<pnti@Kr96~6iG~V}A}Hx$OpZHXsL;NqY)VV@J|>8E z9|slWJRzrHc*>#{Z(HtPY*8nHZZ^@EZfBUlf`|_(@M6mI4Qw884<VUv>sWnQ<A~`N zpM-EP`c3&&51Jy7qJSAXm7L_wA`TqTxNT);<h$CFpXBsAOA0VxX)@9eFEG*0+?Pfh zPZC-!mjUPn@^<%(JSCxD#QnuZinRzz_`Oq}uu(fB&PrJ7#_G_m#+8{0FJrMNjZ~Jq zBlQC}ocUyRdYTxDt}2+Enm1_SkPh3|!1qhA{G?nj{UYI#%P}QtDukY$#-KdnLRxXr z*_J}Gm{ZB2kNo}5z1{rSl!X)05vetNvJg0ljJ8vCoPN=E&S<if#J&3gDDB}}*?aq3 zuxf0@KJ!IuXd~YB3T`N_$M*R}my&WN*@nqR${yxOx?n~RJK+)$GNm@IGSN0%Iq0c8 z)j1)69@NrmEJp#Kq6l$?atKL>ib?QN0o4kp6jbVlvR6KB?hlLGx=2-C<Dr1OSDP^F z)3QMH<D{G~`q#fnK;i~nm&XUS>zq|;G{?skNpj^%6NV62sq=GotVOZiWh_=M$RarK zj!ULhf$F+B812t^MvRrj1R}Gztfo(j*SSz1JDkrmRQ4_w>!%pBc!Qlx)d%ayP)gc} z*7bth;G8Aj9>mEfVxCkFe-E4Je;+5bH{01~mMkE}z6l`BT`|PRTzL)m6Oj!>y=5x` zxBF$~{%sKIx{05PX_XuRpmwq;M02sV0Bh_0IUxY=%Ep+cdlxyGWfVZ{(P%5g_*L?N zym0`uZ?tvdL&%me)GTO5Int`3*g8<6Z?W~YK?29)80KWmOKYz7Cp<exQHjg8HFbT< z+s|mqz=bYUirEET_^A(ZG3m3V<1EE1AyZ>7{p$G&*3v)Qv+7jFC{Pe1Si4BhE@YEl zds6(Z)vPH>evF_WU}l(O_7vbFJj(`~7vmMq6t$qt*YZlT*eLmS&5!7cV&^LBmYqCm z;+F~p#Wt9LFi_|*?*7dV3tNK<bd|2F{`e@rGTxy?rRVJnt8Xr;RnuE{p22#YS^6DU z8LvMgMF-~8uQYpEr#gI@sc+s&VpX0C?+{A$fEs1K9W)%s3}b@dGoE2vSsS^n@GB(x zVac`J-!VHqAWs>)7<OrY`DD5W3vC$5TrgIhGg_TrB@#SB>u{Mc=#M;UID`&WQVcs* z3VKVh9K#n=M~KOy$0b)Jj{Sig(v>eNlP6?%2OkQ4+gRy;`&J#uH*iEk^xLiaiMuuU z<AU1LYX<!J0J-A@+<WKZAWGfy5`%^dm<1Px2txG(!4r5zj6A$t8zpy!_`x>AwQC4F z1KLix8i~iCggWKJ?RtMjTP3>}XFvZW=d1Xt2Y1W6zmE$hK*xgPL{&pZ#0M{2!gazj z!udJNF!XVy=u5#q>FTGYa}KJjIM4GCRh$xX%W$g7`m>?u>%iF~PZ$TbmR`=3pkx_m zoIA-nWix+2!Vx7~`<jTfMIWXMhAE2-cuvpl0kIhPah5NoFIuL|9;0gJZOW*rH~qau zZ2K=u0c-j!&VMX%{uz+9&;4+KJn~C=ibisD&4#a<a0R@Ff*VIx+We?z5g!vmbmU9e zWf^A4=oV2CjVck1!Q$7B3C$Lmy($dsy$F~oI?!yC*R&LLX%Q1ugDQgBTEFDOQwO$b z$w%(@&^U8Z;*!y~f+K7dBWz;{uA!z{vxYr8?Lij(AC7`qOa(GD1yg7hfPq05)Nh*z z@8Y+s7UOk}UmnuIy2OVFAlF%zhBebj??Ug+KXyZEc<*i(q7RO!Ep9FuQ+0&Enpap! zv{a2JVy$D+!Ja6obS<ptY;q9Fz;aOQerCUm7OT<WmU#m-m}LPRvi%(hyXxWcI$QOg z_$TOaVYwMHAaf<V^EuaxnafPSM%^@pxxA$TDc%|)eCtJFfucB!Z#CecA*lNo6~C$1 zoAe8a={HZgfxeY>I6WHxSC-La>fc382^(jp4cYED>+mZ?^9;2t(LiQ2Lpe3IijoT> zX7-N5wwX+{^?g{RGZ%UG#Wz!XsR_$pz@+E}w%a7*?1S}H99+0zjhc}vK9=dRZ~T%! z<54r=hk);YdWbgrFHPc>V|LpdChG1iIzK8gRnb6lm0ja)8p}e<(Rb*5LXgUw>-6Pj zW(zk=_D^R*aKGTMdilxv=r4$@hF^SpZ3v%RnY)o6Z7_SvzfFEa8TO8=-7ZZ!^&C`D z@>~8UAT_Vm!__uw<8;w&s^d<*maT82aryMKaso@hF;UuZzi;ofFV)-R&k^nOFWh~N z-2@clfI>3^nvUa89rj{VtzQizNu^pz&I}xyZd2t2u3Kf>#+S1Dt2JftR;lA8zo?Dy zZt_LA9T4Q}qpG!JGDrkh;IN91SQ51<PNmPO-oN%VCODQ8tx$gFv~_-DAEa0-kr-x) zOEsN@=F?BLO>aLM_RIy-HrlkrIv}-=DZg54g0#PwUR;VHwLf5IJH$DfkBO=N_;Nqq z(e-!g%2p0bHYYI@Z}z8UvN!I>_AD+F(4p0WA#Q!H+N=Y(H)Ye(5as7vl5U`OZ+=VV zsSdM_p_kw~?Khae;el-CGtosK?jLM*EmqB2=oW%!uH!r9XVIb=6uZm{!PjnT3G%<D zyX>=TwG-seUJ3R=;wW4w6E$PotpOLax5D%|S6vmgDfa2_j^Mwg&m`cy&$T~B$Q1Ie z>e@T;4PuSV2Fi16<jJ{=)w}kwB2|&=G$6S7Ag%0PkecW4CA0MWD3C=tD+AY4IvxSF z{dRNSQn3%gXxj(xLb{ZE<GuBMf!oU(Y=3X!K$cOub$F$b5E`cLr2buC-%Zx!jbQ2Y ztGkay2tF=^InI3flog~<<a9^<UV(T<-8@cOxIlD&Tk+Qt1pe%$?Nm79BWwi(?cUOB z_K~^*F|}(D2&L{xe*&mFa(rRro=4qU<=k3#IUQAiAr&PwVU5<tf>rW5REygEwrM@p zgpH6tcZjkkEWNZzLW?K-{7Hw`K}<9!E879<hJ;QSM!{?nSDBY);+bwazp>?jAy)5` z6T&emHJk9&$yb_u_aN}EJwiY)(h#Z`b!|tB>|SO%0k<`plI=j*Zi=X$U?1X!oc@;) zYj705ai0K(7N}{mNV?u>00%cnv>AZQbI@d}il^i7FwePO&C$Mp8d-$kJ`0g~`POcD z5}A`WJ>3+UL*rV#$_c}52X*<LkQ>IP#^^jWJ7Ie2IW&tQq=u;DUl4*P_D|F26jVhP z(1ccFwSx(v>}|hqng46h<s6#Y)@*qC&!o!ufZ`B(e6o=3_vfg1|1z>6ZF<dgXbr<m zEgRpySum+*Ji|?NXd1V7dTFvFGN;Gc6}icY!1V*iY+D7d3l2|bs<YyspTq<YD~$Km zh9@%mCzi)LL(>@CCk7`qcAs)Kt9SNa=g-&C_0Q_f{FCef1r-@?|8Y0CpeOgAwEH5Y z#(Yiv=`9z^f7J9g;&ip?wo0~+gX`#;4hO=cUVIsg?I^9+(B&mqUK0y0A9|~v6VYXM zbyNNHQVHH!*XWYQ{huMHwJZ@KHVaAZAGsCFjF)JW$<2crbAdFLG;?fvLCqvw%E}uA zPBsXBjK?a6l{GSNcoN%D3w#~5Pe2hX@8Nbp_(ksO_2|bLK>KZ$B*gb1D$mSX;x+Ly zYMfx<<RW7HO1*_bbBgH$k5@sc{%Rau=J*7LDDR69g859}EQEVMC()}3bK~aQ=V1IB z8<lGPIz%ADp^{DF_*@)`;%2F9-HvE$xUhpz;xs2ddX0N%9+sKe{a>to2K?COaQ?Ev z4z{((nGUQR&YN3*E8r^JjBS52j5K?|y%|j}Q^l1b(g*(fdZ?MZGQ==)&8|k;AnGWE zU+<HPJpbj;2fh0|zU3R+N6hA9?6G(>0I898+-=7yDH}VK+nyzdWOQEAd@N{mefCl0 zg>_rWYf;QdZreW&>Ex~5q_2h1Vue&cjobsAz=G)M^8T|4l$wfy?`D*;g%tKy$M?1@ zKkFt>vqV|eUn{-G;v?}D@m=E=Is`Q}bYnCdBuQ!-M~^0nulq+2$xrZ&@>T2#NZw$o zOyDR7Bu!>o0-<NyZu{Y85#9D*xD+8?ik2HGw*|H{{k4y<im`7H?r@maAwR@=YMT<f z8P?~?9=$_qLEJo#OyP*FxmNsR&5G-CbzmmKZqljap7EIacEZ*;adNwKTrW&qX(Z#d zqD)#L){#VLP1|+*<7&<Tfd6}kztw(S63rIxjLOA)3T-%%k81~Y724=L8y-NMFx|}n zERZ#%DbuP+RmH1ldjLb?JaNB9EjvuF@5#z0oAUOQ)vk40xaO6HF>{kfM!ccgiSMky z-uI)-y3b*7m-ap7+V0RA$im2-xcqwa=e<hKS5fg|A&<C4x6`ljQSPfINb}wgot}zZ zR#2c@QKd%={#$+SvwDPZZrN5`KAK-__M8F<)AH)I*dHs31FU5R&zwKLC>Z9&{8tHI zqb@17qJ9wZ53ItvcB72&E1H^W9agnruft-kZ*zpoS~?BQV@Rp})Tw(ou6t0j$@4XO zrwD&wbo)q1N6rg!=rt^?lt4Af!2ND=WZ|b=YIpk1<AA1V^PcNb?Jf9nwtu?;(YhZv zjpW#$nEQJ~VflNX3v3Rq<$+<N4UTzMlf!zcrJZue?`zV_9jlXX5qeWkuVAOTe$Gx_ zuB&}|O1@)}8m%*xORKu?Oi^3tVlkK=GcZIo^bg$tpH%Hrot2U;KtHd2vc>#Rq|++; zyj>R4BArP!e&)q&qT{MLy{s`GWDM;>=lGeVwNOmz^Cox1!P+0ZC!OCDFgQ`enLhBZ zXV2Qfv<98{*sfn6A&HrKAl!yj7?pmF^Uf==(M_0|B}X{&WF{2`k)paqoAclhB8jy* zM>@(AT*Npo(&~l`4bA!W-xqwm7TXZ`T=nMg?{X-?Nu-lPB>fyA${PxqFGaIv+^(Dx zm+R&fo=6aOy-*`cu?td==}|k`uzx~pBI85&8OMudKS_eJgM3%-3+k3o==sxi(aXD; z``yMUXbxGc4LLf`+)F+y?l2*5LH*SA2XH7_;PjX8#5%`igBJbrp4~T4q}iLo4cU<d zUgp6aBi6_VxaLE&XYZk$53Qn~u;V>R>kFAKL<DPj&2I=|m-7o=K0)iGEsw);Y?iV= zqD~d|sx+RPGF$^132Ld^cVuJ4Uxj)wa_P_IypdI;?k+x3-EHnRsn>R*tor>gXou&b zYJCoMqD;?fb*GEp*d@^IwcABA{W1S0&`FPS*F_-l)cd-LWX3Pw9a;6GfE(@J7iIo9 z5$OgGE^NOs+Ft?%&d<>iEA+FEHehGo2)xM*u-@5y&xfMz4n)GvCorawKKF5O*+_o| z!!DAo+e~lmEjpbp#zOX)Q8EAJSdmr(F1L&KbXhp>_otJo=J5Is+bWHv>|Lk!FI#&{ z>!Qy26yxwfhUw3Jql>TmXnICf!0ydum4`mdMM7b~G={<MPu`@Dnp+P|+WLOc$?Lll zKotV$P_;(xYg|F@wK))uyB>d1@#jR~9M<6WE*5FU)x=3ZVZ?1ePG_M)DUD`a7winz z)d%%(l|=L#Ao-$ZVVO?iCD&;D%Yl1{9f*7J!X`{i@?s;IMXao?-Dtd_tyl^3v7Iii z_r@+pmGq^-udXIXF)oI0&GM4Jd};1uuAo7;&*{D4PU1rBD2332s)k<uk#b%qriwdy z8WphPRVU}-0Sc*Mj-JlZeb<UOud}LG!@-%y(4aw@YoX?9&>`rkS;ncyhFj7cpf{^B zP@3<4tj>RCGgu1F3<0`%5-b4g;`AP2PtryPhgQ7l^CAu|kZI_uTc0Nm_TMYkRO?Ea zBBFXAlIce)^87<yE0za+ObYGdhB4Jk2aYmEQW+*Pt9F+I*jG9Nx!329M%DoZ1RwYN zbEul(ghE>L9W2e^3j8J7Ay>gnVcvO((@ffQ5oELL%_qsP!S$0!=eSy=k6bZyjl_zC z3(rb4#4hhUMNVqWUsK9}dWCfF0u9!Dx6SoS^Le`+QzZd3NUjiem*KUfJ(jVI<>Zf> zO7+&MX}0s?CFyC^3-8~fL`iPxH-;Sr-&C3JiMO{^j7cL$g&$t*CxahTFA`;}OrA2A z|H>rI8CfKI3EK=(RL_K3(s&U{dTyu@RS;SXueS{kvxUx%JAEJl-5#!lEqn;4xwPxO zaekyg$4s)D2NQsn%WEnV+#2Cu2DLiiBQ_~6%UHZHdF}o9s(U1R<oMoLH6C$ex;D^B zI&kaR>qH!CNcH%BtN~^cX=AZus0wc>n@1eFsC4!wmWkw=f2Ee*w=kq{UfcAc;f3f; z;ed!aA|GE;JBidrac|ma8j6Tu9iDK3SJ%<Dwi`JE_gZluQ=XS^>Uqmm%atoAhd|z# zjxP9}m~Zaibbt0ZWx5-GGMk<AhV9=zu|u|Tk$ZD5Rd8BG_gY5FxXx$Eeg60xW<%JR z4RacA$Em!}$iaNk;oHBGe7o9w=E9sZU#;`fiuUa6`SH8)1ZYHIw(d7V+3R=(4V;&? zCSy!H%z#-N+jFp4vz*0}0F-hvAU;PIMUWL1?dwRhw9;n%Plt)-p(;(8%|9zcRiZ+h zmTW^+s#2Sdcn(%Pm@V3Bo0-ysRcFeZcRbxtGQ6VJ`FN<RKs0NuS~y2GQ*NM;DxyL$ zH}~f<<4lneGQQN_^gGdp(CGQoW!eXSK{;2l&?Zm{6pZ21*{6FA7Nr;J9t&|qw}H0@ z^u=zLutR<;W*GUs?KL2@>Bhk`R5%eiKt!c(<{q4O<r+#^agZkD8r}RPCgz?5L^Eoq zt0P-KB2=EYK3~(Y3uofzIPaGL4Zykn0agNq^GIT7Y2CkLUGr_8QZU@n5F2=_gh|11 z7dJC<{!m)qD7kZM|2uGbW8DVe=OzY^hK7V`#B<=d_>0QX#mp2B3bj2766NRGvP!yO zA?kN_$3fywwu+Hi_a-FOijBL>(t3sn%u(2@>(>vV!;pWv@!kzykA^>WiVfr9kqesN zEg6%F8s9oV&ShWcEEavx({~8nXEx1wqRLsYNK$cK=WcB25YpNz%Gwy%9_?7lTQV(5 z;(KG_*!5bcc%P_r5{+c#<_bN>$9Fr+ZTQ$`9NP0SzqHyngisDxZ1l4qh39$XFA!rG z<2Q%0nqL3$B`J=WeeC1|=9yiG1O4Rg>`);erViqLJE*}SRu9G*-I9l!!<ZWQ_2JF_ zgsc`&<JEfLEKuq?S`L6xwvg5d5u*Ehba@m1g9~TgLkz!N2B06Vl_PZcqSI+|qPE%N z6+V+Wl}jj)mDiAD+OT@>{J|sb*pSxMLypwjcPMcf;aN>VfOiGOJuU0m7$1c(XQDGW zdz{YLXu=R`D+=eyQ#U+I66^Y#s4dHpJviF<k9n{HYV+E5zL!&nn`5ZT4!4KI5NdPf zI&+Z)i_B_Zj;c@d$f(Lnc}Mz{OCSCE#e5Q=y$3$*sr^mdZtLW^HHql4ltM`HQln=h zAPmJnJA3WE5A8yUTafXY!oHE+^`UenF@X2fv!$7JLyWmrtD*1jY=_P1j3(`A*?B|X z%{Rii?F&dBO+rTVFyDU6sbqI3*FGkOlK?q)l-PWJ|88f(Cs0H}-Zfg||IAP4(B?(o z!v71P3hjrowL{A{N(fv%)hIj1z96OB%@N3}ZT>|Qz9L}!^_G5xC#VKqWyx$;%xmaI zh_ogYy9!iys10i38P*Iy&cn*Ll}~ri`Wqo4GSmAve}nmdAk+dCuIo`|5KNpeUg6Ui zH6!!!;G{aHDS*>-((O&);&0u8#K5rWs<cw=T*_*zEhH{46mH8{ZQW%5DHdDMh`|j9 zVlH`5+1Redbg0iRmm3c*vPT46BHZ6u`_Z05h#M*x25sdrU3{8csz5k)a+WDgoJ?6{ z7BU$rA*Fd1v$|yo)a46!*f1a)H<NJ*>=^)Wo^6d}Q2keIIQV&7oUIi^56xtwCRu8z z8U3;?ZA<YMm&g?xToDXjkx!&A1y8C^%g+wlS(I<RqIz^}1s}=7qRZLDr`ErZd15W5 zvzMFn`3+rO50pI9P(6jJ04oGc(ZM9iPVI;Hc=N3Puc&meo-mJZqI)vjQ-c*+DW>m` z;U6nq4~raV#OQs<CC{p?{@($mt9H7&^Eg55eXRsSG<lc?T~O}lYy)AjX8Q|`N|P~$ z+~5Uc**-mEs7%;`Y(k@^uxmeeg~~;V`K+NsXljdKLwz@+Nfi7nFSm>|8cnD$Xz|61 zh6-3lEczM{O$u(>Skg^t2-D*@((!T3jcc^;7m)HCsZ5OeYpvT6$Ik-sV0otk7^LQV z)+Qkg6#SbZ{a3AL0cY4hx214YZT+@pulBc$Wy~1R42b1*H9ZRu6^pG^lPGY08YyCR zTywalPxq)&s|pFqoFmTf3v{x4$;?2~JQHA`H?+y!v`k|X)mwpPQ3G?i()q)QQ#G`H zz{Nl#r4EApYv#lz9DIo*G>Rn^d1RLC5}J@D`e81yMyWtSv#We!OS878m@LIM;{Ps! zcnyP9-&9UF^`kAGr4l_Fu1riQQ3t2AqER|x2FKQcwZWr$anI9K=5o`=%mZx0_c)o^ z!k2Wyo!Bz9DA}1Qy;=irvKOU115xIywk%7Gg>AJ_E==GlhW}q%78P|!ruvOZh5${e z^a8?E^oG}Dx8IOUbTixZ%HS~hZpY5>dg~@gEi<V~CMbN8p%-hM@2E3$;8}8Bo3;{< zn0C$PRYE&2BHKo~wIH&>=m(Sh+S4kqeJLC=Kf=zd0(EOlq$x^a%8aC`pvtvFUU(=n z&blUPjAoZmn;ZizvsI=qgY-sn{g^%(eZG^O4Gws7;iVNoU113)@QfNKRT7Ez2%ib} zy;2!TN%&I;PSmE9GdpbIYiPcLB4BQUf&~+Y7NV@9JS4}X$K$-IIa8oAHF<1({aO5& z|FU}~a<*EkhK0k{Vfr%XZx?O}-k>^JLg^U=CW|<7V(o?EYp1IqVjo|)c-wms%$^0F zBD@>SIn^SzsiZ`O4nc&w){8o#=jObGh%l;`+KrPa?SYlniPe{btHbX2stdFuV_7+A z&XhU$M=6g1L$mVLqp)+^V7MJx*I;@xPf5MW&a^L<B5YjNBW8}pK}Tg9149dAs#Imj z+9s|u(r|%7fLdYidX@)aLxdo7Lb)Q&nB5ork$YiAk*X=PDP6PD-JE)%iPZp8a5IUm zke#<z0^%{sWeqG&L$pmP3wPwaHRCPXM;Pu!LeyLiDCjpBT&cT2CnJu-8aj6|1bU|j zc;D_BxkcP*=WSu$kvj4{tR;cQb0V1}>A#K_-m~%0D731?v8faG#q))U_N1H8!D-i( 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%0DB)*GP*zwyj4yv)M9;>dco3RUK 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	cDK`-4>wXx{u<nE!ql z;S%>uxyam;_hR!=F9%Ua9H=;b89CvJdrsv(es|pKZKla^#?>vfKe!pW%ep8Oc%kW@ zgh}@BE_&G$0T!=5>0c*kuCx1nPdM4zkIPA=bXc!oraFW`-W{-J#U_}WvD}qWkOS!` zzATkKBf*hWZ$A3tWywTbLKG&i8N*EFLN<jL8y;ir*s8mNH+J~;8f3@=KM)Jtk{kxz zY=(B?4)$O^)Po9XTVKU4TM%n266W8g9kVKPs0_7}7m|NeUeVV8SXz0hlAi>u3Q4MP zhbxCre6Xzha~ramV>D|_(nuwlJ0k*o?-KsOKGRmCv)7w>9CXDswWYcs#Ks_hKCbn1 z<!GN`NO9G871W@^K#F;`6Ol%`g*n{a?s_(9adYW35SVsW>ksyV>Y9C}RNy8XrjCkE zT31%fxs_Yam-V6JNzj5)nC}ii8M8-edf>+U%lL)oM&xM2X~YR-TWGgv4*xE0-9oe# zdH-;YFU@sDs&(GimGuUDzoMCta(6^2f|V@G{v;+bIm+-A^gMDn%1y!U^NUD0-W7j- z%A-sDF4k`FtA<$n<K);b?kYaOZWs8`4PqZIcIYiqYjJtT#zRwfkg_4Spvyxq4Sm5W zdj|YNm_toJ#jlOW^WO!*8DgB0dsEvJBT}<E(z$md!5{B_6kw~~-L`(}F01*WA3dzb ztUTNh%Q0{3+8cg3dDH--9xpJDN)h&XSLE3Cf{8_qLUczUm~=*DiN!aPP3Dt}_V6Fr zWdF^Q--qlYxfHZJrHLARf7xe47$nC$j>m`G?J6(Jc3Y1(vO*NSFZ4ev&<(r%3P^H+ zboZ1{a<|dCn6Nkmr8CT{flzrPO5cAg|C0XYr$bl2y!KpQzTKMakL#zjVMpWC+J(4P z-K;xv+}YOdxp5kZGEY)ZN&&MNP6mRJU%tdh25R8VxBNf#Z9C7@w9+M?hPL8ZE$c!G zu#)2H7Vz1YPIR!r0#kADgN+X$@>_mPnh^>|gtKpco_UQ+$cxvDrJWvP`h4-1Kh4*z z<|MY}m(I4{-WSZXd&02sRKDf$VBeU7=_k2ft4~o2t#7R*3M!!^p-voa6Z<#B7D^N% zqDAlD)$gD~dl4X#<V@g{CQ95K4OT$cr{{gAdak^3^GEDk%F4sYrYx0;QzV&liqR)N zVncXZs-pG~^yW-$bRr>vgQOKy;btQz%BZfHVdz!g$Ue}n-p#qQb%`=z?{H4uPHDW* zbF0=+!mZM^p3j8Iv^>4nGtTHoHRy0-L54$dtjbU`SBUg<5%IBJ;@3%6!+=D}`?MY6 z3fsRLdY*cM)O6??2@Xw`860|L45(Ew`tt9xQQzbNvrNZJP*hLBN8G5toMUjxR?;rn z$^8=og^2o7FSlGl*$nCzr^$DSB&h+UYn+>U2fU`<)QfiZpxfY4^_ycX)H}JiX3*2+ zglzAj1<h<auJQhN2O!XL$!@s<>o6UWKuK0xofsjJP4&QxBC%cVWNf&Wc*e`?_+UZO zlPwa^7B!Nzrd5424K?(bW~Aa#q%7@b7l0FIQ0>i{EYaktPb&Gg>s@Ya8{A4hnmige zY6xqwW{JJXZQ^q)jRq<7sfuxP{wk&FvgV<Ny}<wC7_IT6{hg@NKPG6H>`rIDRTtgV z2tMQT@yY5t(gsh+jnoJ;Hm|c8@`Y;qT8nhTPy6NkF2dAqtBwS_{yKSdNAnLo4L?Gc zg2S3g^q|*=+?IH`PVm%QGyRQF@!h8K`15;&$=Uf-o``frQf>@y80EUht;Rzc%iZdV zWr+%PC)a?6*e=DSnc(3Ni4J}1TmThu3$@xl+srEKlvC4JB(%LWYQX>NU#%)CVT>~T zq0S7x(Mh%sa&m%Zfssu$lz8;+^En!lxZNLkR4v{sa6eNmDiF&H_#wmC;@D@j-yFlD z-u1jNcdzgMt=)BIinC^D`+(Z>q{y2OvYWgBbgtW<$<r>BYA<Nwi<nKXe=7ROxEXT( z;ME`})SE$rmNdMg`2(KO^XUd-kgyHEc++#ip(j}tsk?m-znaqBlIM95i<{(#k~(hP zWew@fb&F@y77mYYPrV!U>j6F$gdqrRDI;pv7p5na<SPp=VO<TTx#Lu!!DQ#hG7brB z+`p=U9!~9|ChsFJL0vCGMdlZr#Tb=%L$50Q=^R9cNEyrLsdcp?;`6loeplUF5-QsN zvk#c@UbGzWQhrrz#qGg-iWhQ?cuW>dvbh<VNL@FGGM(89caGoAjMA?qiua=9-1mDT z$s2ux{mMvInWW^C>-}K${Xj^{&8En&i8}eH@l#5HP<;ogHy888NS6=kJo&mE=Qb0W z!X=N?bhFxj+}0#jf;g{X3@GJ4_z7|ezy52Wq$-_JS~=r5cVK*Yy#CnK3{h(lQMB}K zw!CahJWa3Wy>}(;`1Hy5OTUNGTl2~b!JbhQ)${(Y<u$JIlu>l4oJ^x_rU$#ApdzM~ z9&uk%T+Fu_dP<0!T2y3kAwTv92SSIfp(jzHQoGj$B%kQ*P4zsP^y*-*0((c;5l5S+ z*5}QD?+e$DW&P%^3^gyVwQw|N3Mr|I`{a19bjx&^)Zehkn1?Mk?skZ}eZ89qVvRT{ zgpy=6pog4Pn=mJv#vxhx<WV{dABeVHx*V8#Rzw+@Qs};lOgKAyLXTeZ8&VYaQQ5tt zGS}et<%CO0lQn9~-r)q%KI}{NX;M!Ar5WKorCu>A6_Iu|vO?J9DCuN=UZ53Po67x` zh9!*UU6BjDq3$N3m?tOvh0%jwE~m!C5s}(S`DTy{)z4(QT3P+&H&7ELMq4+jO22>y zQMgsvpLvcG3<&M;cf6K6b!!il-}~?KPCJ}}F1Sj2+s`dp&y;s=gnd%-(?l7Tloiw8 zoFpNdbKFOLKDwvFbwpVyCmBbjm)I&ZayVv=a+B~o^hc(wf@H-~{x-{xV2=Vg;1vN$ z?wq@rI>IG7HHWOMOw3aYKdJMztff4vvMS_Eh{%_+_F)O>nY(Y^JpkkSezKkONxjX4 zibT_yeEpc(t)^?L(;Ch>nizqIa<=JOy^-6EUoM`tJK_D~#;*~^Cs|JU4#b7do5$sh zNL2pVk9cov1ySGjujd7ttkfJ*-rI|_H?<CuBSr%|4wcx?WyVCQm+0;LguYi3LspBP z>B>14>~BY1=JLdU8$0?fQ3{WH+&`c(Au>PT>K1lXV)ee({cxuH&nw(BDwSa3M9`tO zNvs&|%ZO1FGFnI0>c%GCiYeU0w!S+hg7_Wry<LA&4b2;V4>w@cA|KCObRk-}*B<}^ z@ry9;DEXt6lvtB62^D2JV~OQXqBM0VOQpq;Shicp^9PpFgpJM`$jZy-?(jPcjN&i< z_(TVMSh1q|p<0A;s-*ppe9cvh{LtA_3dKngvew!4_cJYXf(uxV&pJd}*aFKp!&!)~ znRcYOZF?R^f_oTiTW!@t?9Ou7R-vRE9o-%rsCdPIp=SvOKKgZA?F@O=OcRll_W=}Q zLCT_oX(6FKgd5^b6>V{0;|hTxUcB#m8<(d)yek3Rh)9{j8)Q5_t(b7_uSPyU|4;`0 z5a?$70umdcaai|FW%u69`GE+-9>XV!Wd;|B!8|TW%=x7g+ll~)5P{x8C*0HO$TN&b z4GkWDWg7f7f*jE!ev2M~#f&v}#-_?WI7>FCD{RvZSUhieH@I@y^3^ONr7tkS!qC@0 zk9fw)?B(I=I}2XoG0qXQTz$3d)P2IyeUXoOYo#|zoKn_N1qVSlpP^n6rD;DH38MLJ zK&nqWQAl^lZK(LC;mPy5cSX{4Bs`*{#D#;2>n$&ss?|VJCZm@xyypgQKd)rWei~GW zv*7{*6UV#$+!N+bpbo5GonDb07B#%q=Z{3<i_N?98+wx9!>>+=jJeN7DQ8v`6)t4w z)SY?dTNS+9J;eg$@kOGnaaaf+ScM!V!@HO!o5OA(rqGRlzQKon9Dg-yBXPu{EJcj7 zD89qhMC93gkvDo!WiPkaarg?}PM7v!;b4jX&wHQaLC>V<HVWutxhHphL&N|{r4-en zx;ObeCFyN)XGwrZTX4YayE5l(RmNsxR|?=KX5y0W<9L&tB9cC{B?Vc(%L2YK7Y|ZC zZsU!S->>qnncxh&1J5%<%=>&y{6)&DrNtBIt*h@<KhuJ<Ui7nmq;Hwam0VINBzo;x zA|996ws?Jt*FCZFSJ;OO1$){@-SH-Adoi$rD)S9-H)P2r4OK_40g?Pezc6I_uqXKQ z)4*gK<Xl3>(N@kDx3dm^)0JYU*@LuO_*QUj`1|!4)6CUsCf4+lpEHj*0pcICirsGd z?)k-A-j92nqL_kOjgg^w?j*Gw)%Llh)7S5SMXXO2eS0!puS`Tq*gLV8tS9%zZMI>0 zu;EkjzH65@e&D?F<UKc;DW|AR$0IWe-gh;2e-)t$Ji)gM@7#=rXwy~KHB~Q@u<XaR zeD9VpOPlVK3Vq8qEV25KWGBglSOjVvK^uI7hmQJ4UGO`qb2=3Rs7ISvk(^R0$pAzs zzLLu>OgIT^u@=5j=D8rJ!uspEGjQDnlc~Qt{m?Z^b#ZgJY_A?Mv1Sk=@8Tqx+sC4_ zQ`Z+@VsPb&weUy$&Y08_CbS3*A(u|tZ=WaYinadM)G|CCb^WN7{V?B)gZ4C&Gr`Ju zg{;XbvP&eu_lk3?n9@m+oTQ?9TI|@KflC6f8=C!zrKSIS;tScJqtr717pau5`OPSE z_=9vxbb0e50j|kf?V48m?1!m0g1_xNez6v-wCA!i!9s7i?fO8>4=uI66dA+_-3KsQ z7a9-2yZNG&Y*c10;1_yV54?kWqu+fk6Mxn4+kHN#v?-pR`_~;g+;g#@)D?+`KbVSV z3~_tY=g=sX$PWf&JH1a7+RRhCxNj>HY5oRvLqq&a?ALEVT=WJYuSZ?IcvFouNsoUw zJEhW6b*^Sg(RBzY`qnoiM+W9TXfKC&QvAG|h2=^RUU)jL{V@5Coplfu7Xn!1BJli( zQez?;H*KS;AkYsM@^E2zh*On~4VBC`7h+;>R-IQlWKsH3M8D0Q;0*c;cO_u!62L_z zFXpSKm`^D-&(^q9d%e0X`PW$O)ox{-W?NSY3Kr)^eWP5exBbqZ-?R&hu)6Fm*FI<X z?A0I=PQOp5k_J`DAY@(^s$@u)q)<5OCev@9;Ru*}85f!(WKzn^E>3%}s+avK+-7Bh zZ_#feJt}f_#^2qS_GYDLc|^o`G}m#5)J(9;>CDCHl<PJZKqcc*>n)5`_KELcDymo7 zjyGM3S${Rga;YV+6cS+0@Rc~gl@$(_ZBDYwnsv{C#GZRhYE|tf+g(v<-ut!|&8v#8 zi>bTrlRNgs#C;va7S@`V=qj>{=I-&mFP~VCj>Y*T7&L{E7ZawxMdI4-Hy9ZHO>*H9 za37z?m}qv_+#E|drb&+)8wcD`Ah71yIb@I#!=6Yq0kPO_D>Wd~%j@)ChC4stzH1{P z<tjPN`P~yL)g-oWyN?#1jm7wLigOJ73Y6Q9I<t^AC23tH*lu7TQ`=!8OV1=8LViA& zPdzKzm)^5;mEp;z!iZ=-?3dHjZ6SGLNjWGEMy5)%NP`|Qzc>_;eV8`Nd3j_Ss04;+ z3FZV{0Np~JfLwW0cI?z&A6g!RA%x}qb_%0*p?5A-jy5&{qR*?7zu`Vd^}QEtzi&YE zW8xQ)o?W)!JlTA|jPA!fx9l`3a>mPb7V+gLJC~@E7q{MAYRESkUjiQxdrQFc1Ew{_ z&Kg)dnK3h-4^KEC%ZV&h#O);?O1T{+o(7gna~;=4BV0l>(`x06(<+e^hbzj=2GC?Z zSTC*48#4N<m=G<eiy|wz33VV-f-yCR+;+2eUn~eG6Ywas-orHFi=cs}9OGEk@1+MD z4|WRMF~{m)PA^5eFfoS`!^_7Uou89Em<F#aODUbY>0PIKae9KM<sa7#Juv-kip@=t zz`bY7@g^0S7GZLEeu;MGF&Vv!b%?T%S+TEO>q6aM32)bz&fA$0IfN#sHr+;Y#XgZt zkuoTG=V^ZdIzhzlBICvHOMCcy(^(42xpkpMCOEz9_p!{6S^Dn^xw2iLq-NZk+@AS` zC*Q1TE9(j#sGOF%60<sL)7&RKd!En$Yz=yaA}J3G#d|F_t+`Ac9}q91Cv0kcWQZL) zc!a00ANpuGwz`@WAK)z?w@0l6b3^0@UzYiR-iqY_jqlqB%O&f-&^V=4$@p-cQ(dXJ z`}`1u>7^u{TjRutw~>fDHfIGAY*P+j_iCK4V2tjbbJrQpvZ<&H1AOfQLG0(Tm)dWW zh9jjaF81Mejy|t90kk?2VFFYn)&+SP_qnnyKDaDaldWAAy82E=yVm&>C(5`z6oqVw zx7rZfTUb(9oKlVFuWW||zJqFev?m(;0lMl3Xh|j?z^^MhDo-G?dM7Z)WsP^W;hpUh zi36PU?nm7`Jfi`NWpG5VCRs^-T}H|r)5VOhMGXvCb@=&IgY&$U+ohiNC+|8%Xapv4 z)tln4d*>!j5~UM<81jnCu}|84H{H-An?ohc{HiLErO1g~Z_-yKKSzYySZtU4X&y#K zw)=@SYn;ZN<>e1QpM22_O<0{;@81>wpq-vTkb6EFg*dgax$zBit*Kc0994j&gHFgB ziKic4ZOg^wFD~2XCO;D>eo(bQt@Lwzp{EOmjM*+hCTX=%6uFgsaVzK_h9(bqCl+*H zr^Kmb)Rg66yF?RiQ*fbx^Bdez1D-sOeyXR9_bNV^33*n?@+O-8o2l{lg<l@_H3Hv1 z^885D<mu=|y@h$>L?$<{4~>iB&ij2mKMh}H-&>_)H0?-*0za84b4)o6hGqvgwrZX! zQcEnG20I&bxkd*VF!oc?vu}ib2=bz3@ma4qXnOFrs);K+i2JLc9_uRQT>1}WYsrhR zCRwO7xA}4UJHReH`AOwO5cni=`l2WlfqnYSL-A`Qo8@vwf)(#ueOmf4ufwWeQT{D8 z_71JYaIpUoPoAEVymADFGbw8IgXcCvCF3Rc?XF5Xs`<jg)Cz)E)?e`kYQyP)BbJVc z{m6hfPYz@FsAj)MExIdudLWWvjh3quA!613Ei#m78deaxId<*(_=Vly4o}}1BWA4Q zp77j$>GI6IJmG7dYFprLDh5cIX(6ncu`)5LO10rfI_X7gmTj?=q`|+F)oeluJTNPN ztq{yZFL`AU7wJWxAKjkP(>|JXNW!hPX()6mtdh}5{$_r~5o7=vsjl3CZ=G>jP;Sy4 zylra**sUzHhy*od?)d2}OAI$lnVDEh4P07z#{38{*k@Mjfl)u9KqST0h%h^NGaBZR z_G>v~PGD1y=rqchCmH`7&#rzcNL>aIPi3)kCe<A~iSb1C)&9E7Y|Xd{3h83ML)?(Z z$tf#4AFf`E)H)KAoN~##lRe=lN8yQVwi`>?*^TE{sRZ85E2GGzN;ce}O-Jbjw-2Yn zdL`NT+=*r)D8BzCL(blJRU@U*;9v{-?b;nD!!VIfc#*tz_{oE-LHR&V$s#2w&q5;A z?sylc{%zfhYaLuN8e@=PzS%4y=TdpJsym>tM#y>fICTHR<Wv^IhxoPMu&aIl#V4CQ zr7)$o{lACIg};B|MYeEk&-#=?xJI?EGR8i$-TBke<@<h`{1h~0$E^KA-n;M?J?&S0 zL&q}==*(K%rp>Ua6iz)<xKHN_sM<`+EaZDoKW|=@p#JMGg~vRMGQjx>iHlXH${Su^ zMNh1;=pR%g%~^=kOkkvDj)tLoBiZkSBzt-?6&rNmjoF0y$RBVCjsB+ZD30{%WP_M_ zJ5foCiG?b=FR#+sM&&I!)k!KGo_0Nhr*n`lmlCbe=;@QDp+Vxj-qB{zT*g3ybUHI; z1&Z=;jbbHxPF=x^tt-NN)AJR{oS7bXS+qOgPy0jt*1Eu%Fy^?{tb5FK9K!3m+elWT zHDj68k57K)Kzd>qWda{k?bVb|N72c~4jRJl9HwNpvrt9W+HU8^Oy^!SoUAb6us9Yq zS2vAc74PIzDOsE-PMLpIDr;E(^^0kOn7W%CRMn`P`rJP^f;T^83f5tJGA=W|s^Q*7 z4E8$|x==MqxED1lZsLB2J+Hq6Ns=$S7S=Lb_1HuY&>b%N<Z5++{iuyx-TVFfuk@^6 zIbx*Z^C^Rr#)h|9o;DcM-J&mPVoZqmK125+ZHE3ciY!A~xV^&fgALzBq*;?ItIR%? z&qfzb`+ccK3h}<amlt^o;RNTOkzXRyrp`XUkV|tZIHdX2LLI+Ywq^D86(lgvJaL!2 zao&d}qDDiNrEP<`Z;LmUh(96cp;~EslcxK8tde#9hJ|`PrP)>Y;@!tH6Ksi}24?_k zgy(OY$*QXZ3Lu=;A&ZhF?CcEfbPvy0pH-P2-aM&Q%y0<%T;4KDfDP%Zy{~f{S@M@b z7>sao#P^aRX4brQd+N*sCe90j*PkLAK8mwbB-#SLzUL|;?6785XF3!}HaF)0w5+G^ z=@(4%2;BEE<Mnt=9h$y3kYOSCcyBlJ6UHg}(?L*F|K-rxn8htyEn${h;}xbFvz<$6 z_}FBI>EI`}52>Dlcm<%-z!gGk(4kt97jIq=`DgQsu10pRw>$5OB~1pqR@cMn2>tl7 z9>d!5DdE4PAx@v1VooL=esjDWxJNG^K=Jt+(G+9ma^gQm1JHlqgo&1PKL%Y6r;rs# z7TPm3z}M?XVZ7U+z|L2{ujVMzUuR1mzJ!}4{O1vO9#lCwEWw0CEe}@P0dY^Vz62<3 z7{>qXQ6CuW*>CBgH?pt!P(}V2S6~MocO_wKa=wgAT*7<db98*3z$9`_@&lL!pG<Nx zn;!PWi1C)!<Z4K#SBKa_A}8jnLD&A^@2YI+*BUsx|JpG+!aed~&Ljo#p-nSKJ0DrM zTok0|_sU6}z4ft33lj(Si|6hx3KoW{5)nCHRp(BJnwmsKdNP%H-MMF(v*MF-9p4F< z|9brN346)S2E`~2)h>s#fthxtxW!xtpG>Omae>OHHHBWhm?@ZjHj9Nq7AC{(q^4aB zDKIBC)U!(*qqow4=P4zRe|La}n?AsePi?F1?6ICuxU;m<oMWHWg%7O@S1Hk~o<`oz z*4lAHeIRb2Q?Mee8k>IgihbBj%)nT_DaT4N9jpGaadQ8uEqQyl%)P+nfauV&--Q7+ zIgfGnPKJ*4I}2#yzbk+3dZl4Mu@hN8#s~Zh#rpiIRULDaonQ(I0K%ylJi)2RRMjQT zQDuvlbgZ53SJaQ$tmJdZt5M?C*y`CYp}W-dq6Ym~>F3{hPr3nm8h5e`#Gc1cJM7!q zHnr$`c#^)3Fnt%5ZOmJ$zy%^G*7$CjJdb~StgZ2FvCuP%B5^c&>m6b%Z>Zjt)1u5= z`hzV-RN`#Yhz3ZdBjF&>@$s~4oQNl%rHnr2W}(W|{K@l6XE{}rJ6R*5g!?iOn={o! ztr;v1>!CIOal6s_JGj4fm+hy4@0WhJ1b^Le73+zUx5aURyVKasaB3YJ3ThuBX2>0V zwZP6;&_bN-W*^GdxSu8Isk;Tq=XpRbAr;c=A0?wlanT^A=+MIz^=rlu{AAdE`Sjw9 zg9!n0yOC|~w)jPbJUVVq+<}D`OQkcvJ-?{yOxl}bYBCi#RmoWXcTT?I`R$-VO;){h zx$VMdp?Rq=AUmVjdHDn##e_KlseDTYXeW~X&}>of5x-U-%6a0GJi_Pm&dWA@#H{1D z_z|ib;ZSFD!(g6R)~-DAVGX82?mGYUoUkQ@a)5ETCs&;hxEN4KaA{goLP4|!yoZ_x zhbCPVvtJyCDp&;``?LXY7IVjM1ytE~w=X6>5r0przuvd6BZn6lld_~PV@It@8Fw#X z0hAG{f9^KxkjHN@Uz#{rOUXSB<s@R1vOdU7@MO?G6N!!4I*K;N_qn=3qdsSRbO1ar z#C3Jbbe~Q{(q>qf&Sv`G$E0##bk=2E3S~Th&jTB|Xg1lCt>>>ceBLjlcm-HKQjaSQ zV<&uN>I|x)hCna^Hmp2zyY;$plX&@Ak9Oqz`Rp@++ZUA}LPzIjc=oVPB4^Yf=C)~; z;m?Hf=bIAz4^lJ36vO@E-q+ju7O2dk*Dv&ihD>>JfdoiOYH>FtxEUbH@NC%FM17^S z$AgVDiLJY}E>SF)CNc73#4`$DJ##HxzpYfIVd<Vm!&gVH{AcS(Mk<nTuXBv{?_Hio zcXyH{76jBh6n@^cHlKP8ReO$9dJNv0-w4rb${_2o9dWO-%pz^!&k9)%seyH^%}rA3 z(m#k4%Zik%T?4&2{BRHy2p4#ua{F(tO`}lp9)+vJJY=W;l7}XGrr+W|q-YX+xV7)- zCqOsZ)!LR9ASldy4i#H2zv?(S)U7|<G~vy+rH)GZv*~f6L$7+A?lX4x>$_HNEcdez zTk8IizT?NueyYYQ%EXN2W)Vv8-)0h>0t=}yOdyVu*X(gzL-PVGAY!_2<D;g{O{dp3 zqE~piN2uYawtZcHDcoI9O_|mxNLto$)fB3iJ4BUVnNBYE!6pd%O1R6BKsu26_EI{t zM#zfXvM6<+D0f)paDrbU_dpC0#h-NpCqBGyS$5N_ATD~)^V@r#+un83&0XrMBh`H2 z|F6AskA`yH<2cnuL?KDS7&{%?WsE_L8Nx&*_xmN9#u(Qb%rN5;A)$~^qGBhsi?9*7 zADYuhm|Szel}j!MNkeXDx}4f)ud~is?;mHa^T+$H`Qv$?_5J;x=lML}S?{bh@9%w) zd)`b7S7oJX8u|>*rO;H8bJrAg$Xqx5v4+r~K<m;7U#ynJ-n~2Wr`Z4d(WCB&LRxgQ zoMc5mRi^N6>m<m~x#x(x2j-Rg@%V(=vJ}@aQnKGf`QsvK4rxY-ne$0G?K;wv*{17C zh4dPp>s{sOlR?#D$I2|r6peS(@{X}DnIANQ?&Hea1k*<z_z7PM9hBi2R)emoyt>X8 z<Nd@(CT-I?uDw~HdTtZH(U#L@bGfbQyr^-~{-~VRTR*Wpbz5-9xau6Fc;BAY=2NXD zod3v67uj4|A@5ePwIGWa5q8e25A#e;@gF5?_(_QeFIibRrdr%~q|!NB<xX8q(_B@f z<t7f=dT#df%cM#ZP2_{klIi`a!sELejP?=6OB#l)PQ)v4H*z+tF=lm2b3@)aTZI3H z8OlYM?Xt)Xa1MS}h$~8dP};(sD~l1R*%f!x<CyBIrO3<EwTDMiug%Mz%$>A;C~i1f zeb`ZOJ#q}^&-1J`FX9U7Q}We&lCSH-B)8&JFZ4$r%$#@6E^gB*+Ia8ntLv~>b|l%Z z%i(|)rO;gGlJM^=_T$AemxIz5yx{WBO9Rv!B^>h~w)9M2-ZO?-Nyn+yKflwz{A%bI z*Go6_WTY<)Z{xKYWUP<-y~^zwLj=xwN^&wyBS3Sx=E)85@u#sPkxc7%K`}9UT5fz$ z`y>x^59R?Mx_SI?WP|GU`75&b5|f8tht}zDrgR{x>8uRG+1{{?t=qN)PcC=MQ+Cz@ zDc7NJT{Q#AaDP><*Fqs1V}rB0Z`0m+duCCeS}nGX-5jE*qa+q!CJnzr5}ej^R+jTE zaw&{;fm_(nJ<mOUYiZSvvr@{iC9$h2Y4JChMK$&{lT9I06%`yl3f!klLI{KlF9O5l zX3p*vZJ#7d>rhvxS$4PMA||JANgAdZ6z6(NA4|M!eWxc>pU8dy_CjeiQt7yl-;u(G z>6p~t*}rZ&Ex1GjbhwpnUPBg5WA$chda7Dl_MVV2JRC(h8f2G`nb;19v9zsvo6fj` zk&C~j0)O59L@dtcNi3FNTQF*tSX$zjP&<{+Y)WSG?QA_jPL<LLZ!EuYe1ZU#do=%O z>LJ;w$Ljs~hmc{;nS3_{ffYyE(Z0o$aNb8nI?vWXIc^MvR33cfDpM+QP?~v}GJ4^m z0`Yl}t$|S>&$Y%&cBw+DH={yP>j`@DyMCQ6Y}APLKwneTD&r}&+pTuk8x5m*&nzcW zZ`_<<Nf1lV&Ovy^M&&IBI%^a{x-&V7V6RfgZ8+|&SIeVN{JkwaIfZ{EK_s)rho`2y zV(=!uYtE+ITL)_T))Gwv`TQ)(A@_x;Cpire>q8MEXwv32t&MYGUda~BomBl1=6p$N zKx5t;F|T``CvFLcuE+T?A0~F~-xX<Oqrl`FW&XncqHfW=#s)8#C(#<LE8huo-GLbo zYz*(DH;zT1@ABnz7yEA3HBX|at|akDwmH*2=^c1^jU_tVZ$!&~(0P2(G3kBVsr0%o zd%d#<tRCf!XC`r{Uz^(g)NbVW(+i~?W3?B}dIqTC+cnQRbq$?9WY{(`uSWEaYp%T! zV5(S3mZnYUI!&k8JKY%xLNk6_H1uTEwY+1jbZ0jj|NZ!(@pwvCWcj7QotW^tjVOWO zHu;ji7Cixal~YAl!A8xq?t*Am->mw}0k3rRGh0ua^ZG4DT>LkQcfCWcb(ux`P=dVK zl`li{N~9y7YE=m}Xr#Nq2MO=U!wGB8^|NBO>)%57v}bJe;=(2s$}0=Setmh%Wn0!Q z{cX3W?-I<muPdRM{bJ8GQ%Frl@yR_xh!+FvTXmeL&fRKyAJDrdQoZsNKGT}>V!eW= ziOJdypOAN1YqqU>f1@b$|Gz16ahrQ6LoA&tm&fAZP&wpbWk<0yK7+)Oe3Y=Rr1N+s znvd_7dqGh;G+!*v3r~TZ#}hn=Xy`(9Jrv^MiiX;%87mw6>f_x#P6qqqErU(0aKT<U zO;@OnHZO{XWGC>!Q?L-4k2jHwq@kf-@*>&o&)qO6<coyjg@)>W9uQ(@YzEOM`QssK zN(e=qG8_(3S670os;R5P6(B0ga21#``=hQ1S4FC+BUO$;z8z3)UUm!R@9KuMz!-cR zj(vuPx>G2=NEnPtr7BSoN+f>*46doE`8kb>iXvN~NDd-Wurx&?S>|h!f9Ap9$vA%x zUy28b2>F~Bd!7_PK|`UR2l{?|TbGaT_koDyZ|v9<VKl5S46dXM`<|H{h+;EA>igrd z6q3IciR7*Qb>#*g{&*_M--`^<w^WDx#Tbk8AW}$VcR3X7&jCMX@FN!<gQeiL*@O^^ z%5X)vvK3qnsjP-ng**Hq{;TLu;l?Ca54WIy6Asrvs%m@-|AXjTI12U|${!$o*@4gN z`&0jagXfC-&dxW$-}}oJx#D1WZ@dqlNFlTN!T*(?D-P*K^7p|~v^{*V1U$@_NI=1U zbpFTreVsMiB5ZfUzT5MkQ~$oL|C7cK?*EhYUz37^0D=qR0&xK%07wkF3&aJ803b2w zE)W+W0)WJzyFgrk2mlg;?gDWEA^=DXx(mbwhyWll=q?Z!AOe8Ipu0d^fCvB*gYE)x z0U`iM47v-%1&9D3G3YK37a#(F#Gt!CT!07w5`*pnaRDL#NDR6Q#07`|ATj7J5Emc< zfW)A?KwN+b01|`l0&xK%07wkF3&aJ803b2wE)W+W0)WK-(OtYh3O?{ec9jQ}UCyzj zcTSo8PJ-A|7+ov(h}J%rg4{PEj3uVFK-9jnRJX_u)x6!=8QIy2q9V{;_XLF}8t1wV zihdRnSvjg_DL9thYLBpj_J4R@4<RBk$cJU;vmIPBdVZD2lU0+MNz!B-7G;LGwaqQp zt<O=j-lcC=_w~)LEr*r9ubH*?s+Ew*X+iP0G-?UL`4I?&7K8Co$TlVH>VTiw(CBJr z@M$;6SmC9g=KiX>bx6>W%V}F#iN2t0d5qxR+k)avdqcT%Rp!v-g-f=JDw&M_*wv?m zwp}(h;a<A;5WC*KSpBKZtGc{noyN;DpwFgP@>1Wt^4tixBP_U3x}Gj^P#sa97$VBq zmoHcF?36}mVy$3c11>53Wic=7T%Y8Q=nH-(37hiWy{MJw))v@#ekFSadp?QS%^9vk zSj4jLk<`%ei`+E{gknz8U#_2XSnBv)!(LOHyW(QzgMP&A^q8?@8uiS6AKL!<E3qq4 zC<R3LWpR;(mCjt63N-Koy0lx--$m-x{1pc2N-T>jqTu7%h?iU(xtPoFBhIg%xlPtR z<<jx)bwz|77Bt<%Yd^n^-*C_r(9dU8p>38t?`}mJUFMLmgubY7RL~M%XC0yjt0Pzp ziQWfpOI%L-1aJ3WG&ysIvbe9%yR`5W8C|`@wyUM@l2;7pJO#PeUEAWZnm~G`RAG@= z7Cj@@?secBlLzD+A@dobl%0!=*i}+KTE2H;mD;*`RnX7P@fG^v(EGj_r|uy$sb5Ho zP3{Gq@8TcU-><;XcN+0`nc|wwr=#!Eql~U~y5KY<V^(@~tc518cN|R2|J`&v`iPso zS!w2cw-qL|q)VC4V=$CyBKM@j+0xB9+GTvSJKvU>@jB5#PCLIMHI!DED9+GXTGxE; zQB#gFGe-Vx!xK9|!~E<I<9O2DV~*wu$dsu3*j``)uWvl7<6oQ}#Fbbmb_i|fR8Yq& z`S_J}_eCA$`kWw1srda0#0GP<kBs8`0l2~}m1XyML;7>+o-lonUd08mPf{k+fz=B= zEBqhLtCTBjgb8Xm+i}Y@Q?o}2`R%;ro{!FSU9{kBQ|waJgpQZC48|k+QN<m11(yc* z&Gw9z9a<0fHLV!9n_c<($>WJ<ZoW9onKFB;fbh%)s(9XDB$co|7boh?b<B`H<Z}Q& zS&@3Da`y*aRL6WERaVuwIOVh@b>FK2=y>6Qq?d^0FjS1CcwTK(mI3{()0^`;7YjNE ziT%duL3tg9)q{mML+`4O)l}_0YFw<9Y7r`ZfqT2Dg|H;FRrvEl=joBTd<`zq(I(E1 z1M$l;;|Wy_vc2=Ccc4xp=6P~Yl=Z5&J2;67if72iH}eNdDa~`AE+stJ&;01ArQINX zRc|0ybm@L9Eg<QIapvQwq1e(zwcJ|++CPsnXop9h*+)gH&{S7NZ4Br}-P>8Nll;wB z$%1up!d<MuG2<h7Tb!mCdXFyW)Fb%y7cHHOM<<%A)uEYxuP|p;40!xaP->J^yHt|E zwdu|>Us+#{K7Mb<r{!X^sNY;vd#^akjBjlpJuZGhfOpVtqCl;k=W~JDsS_rcLcMd5 F{{VoNlXn0B diff --git a/core/pulltorefresh/src/main/res/drawable-xhdpi/indicator_arrow.png b/core/pulltorefresh/src/main/res/drawable-xhdpi/indicator_arrow.png deleted file mode 100644 index 810ff595b79a2d7840ccf80cf4e559d6e15a2473..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 429 zcmeAS@N?(olHy`uVBq!ia0vp^5<qOi!VDyn%%8RaDdu7)&kzm{j@u9Y9{{<!0X`wF z|Ns9_BN|MS+WZ};k-sF!FPK44$=D?{t-NFAs@-SqzH`(1Iuj_xS>O>_%)r1c1j3A$ z?$-SQ3d)qYMwA5Sr<If^7Ns&crsOB3D!649rIzOxWfv<r2b&gdeQX9)cg54iF+^ix zaza9a01Go4hd>Y$lWUWV$N`Q^`V3Dsq?sE9&HB2y1uO(jcwOC0ML3!^6#6*MNzh<F z%B|rb@r21)<G2nl$E1ygXHGXRn6cn?z?X^=21jm3zB~a-VUA@&Ph8eAH7#YaytunD zLAxXL;>C?pM{Zudc=6nWz0!Q!3^piQaPsgJpL00qxj-#bB3*gHVV=hl4M4*-^f#`3 zxQClf_<+o@%?jUSGw!@@vY5W$Tq1L!P(s|?@9*w<@7TZe{@&Xh&kgQZXE$(6+Ogc@ e;bG2=EDWJDx@K@C2HykvkHOQ`&t;ucLK6VlUz}F} diff --git a/core/pulltorefresh/src/main/res/drawable/indicator_bg_bottom.xml b/core/pulltorefresh/src/main/res/drawable/indicator_bg_bottom.xml deleted file mode 100644 index 81a91aa6..00000000 --- a/core/pulltorefresh/src/main/res/drawable/indicator_bg_bottom.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" > - - <solid android:color="#40000000" /> - - <!-- - I know the android:radius is useless here but it's needed to fix an old bug: - http://code.google.com/p/android/issues/detail?id=939 - --> - <corners - android:bottomLeftRadius="0dp" - android:bottomRightRadius="0dp" - android:radius="1dp" - android:topLeftRadius="@dimen/indicator_corner_radius" - android:topRightRadius="@dimen/indicator_corner_radius" /> - -</shape> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/drawable/indicator_bg_top.xml b/core/pulltorefresh/src/main/res/drawable/indicator_bg_top.xml deleted file mode 100644 index 59fa9cfe..00000000 --- a/core/pulltorefresh/src/main/res/drawable/indicator_bg_top.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:shape="rectangle" > - - <solid android:color="#40000000" /> - - <!-- - I know the android:radius is useless here but it's needed to fix an old bug: - http://code.google.com/p/android/issues/detail?id=939 - --> - <corners - android:bottomLeftRadius="@dimen/indicator_corner_radius" - android:bottomRightRadius="@dimen/indicator_corner_radius" - android:radius="1dp" - android:topLeftRadius="0dp" - android:topRightRadius="0dp" /> - -</shape> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_horizontal.xml b/core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_horizontal.xml deleted file mode 100644 index f05bb033..00000000 --- a/core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_horizontal.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" > - - <FrameLayout - android:id="@+id/fl_inner" - android:layout_width="wrap_content" - android:layout_height="fill_parent" - android:paddingBottom="@dimen/header_footer_top_bottom_padding" - android:paddingLeft="@dimen/header_footer_left_right_padding" - android:paddingRight="@dimen/header_footer_left_right_padding" - android:paddingTop="@dimen/header_footer_top_bottom_padding" > - - <ImageView - android:id="@+id/pull_to_refresh_image" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" /> - - <ProgressBar - android:id="@+id/pull_to_refresh_progress" - style="?android:attr/progressBarStyleSmall" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:indeterminate="true" - android:visibility="gone" /> - </FrameLayout> - -</merge> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_vertical.xml b/core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_vertical.xml deleted file mode 100644 index 2185e2d6..00000000 --- a/core/pulltorefresh/src/main/res/layout/pull_to_refresh_header_vertical.xml +++ /dev/null @@ -1,59 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<merge xmlns:android="http://schemas.android.com/apk/res/android" > - - <FrameLayout - android:id="@+id/fl_inner" - android:layout_width="fill_parent" - android:layout_height="wrap_content" - android:paddingBottom="@dimen/header_footer_top_bottom_padding" - android:paddingLeft="@dimen/header_footer_left_right_padding" - android:paddingRight="@dimen/header_footer_left_right_padding" - android:paddingTop="@dimen/header_footer_top_bottom_padding" > - - <FrameLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="left|center_vertical" > - - <ImageView - android:id="@+id/pull_to_refresh_image" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" /> - - <ProgressBar - android:id="@+id/pull_to_refresh_progress" - style="?android:attr/progressBarStyleSmall" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:indeterminate="true" - android:visibility="gone" /> - </FrameLayout> - - <LinearLayout - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="center" - android:gravity="center_horizontal" - android:orientation="vertical" > - - <TextView - android:id="@+id/pull_to_refresh_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:textAppearance="?android:attr/textAppearance" - android:textStyle="bold" /> - - <TextView - android:id="@+id/pull_to_refresh_sub_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:singleLine="true" - android:textAppearance="?android:attr/textAppearanceSmall" - android:visibility="gone" /> - </LinearLayout> - </FrameLayout> - -</merge> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/values-ar/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-ar/pull_refresh_strings.xml deleted file mode 100644 index 25d5392d..00000000 --- a/core/pulltorefresh/src/main/res/values-ar/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">اسحب للتحديث…</string> - <string name="pull_to_refresh_release_label">اترك للتحديث…</string> - <string name="pull_to_refresh_refreshing_label">تحميل…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-cs/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-cs/pull_refresh_strings.xml deleted file mode 100755 index c878da0c..00000000 --- a/core/pulltorefresh/src/main/res/values-cs/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Tažením aktualizujete…</string> - <string name="pull_to_refresh_release_label">Uvolněním aktualizujete…</string> - <string name="pull_to_refresh_refreshing_label">Načítání…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-de/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-de/pull_refresh_strings.xml deleted file mode 100755 index 901291bf..00000000 --- a/core/pulltorefresh/src/main/res/values-de/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Ziehen zum Aktualisieren…</string> - <string name="pull_to_refresh_release_label">Loslassen zum Aktualisieren…</string> - <string name="pull_to_refresh_refreshing_label">Laden…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-es/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-es/pull_refresh_strings.xml deleted file mode 100755 index 5e9d2803..00000000 --- a/core/pulltorefresh/src/main/res/values-es/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Tirar para actualizar…</string> - <string name="pull_to_refresh_release_label">Soltar para actualizar…</string> - <string name="pull_to_refresh_refreshing_label">Cargando…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-fi/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-fi/pull_refresh_strings.xml deleted file mode 100755 index 0381287b..00000000 --- a/core/pulltorefresh/src/main/res/values-fi/pull_refresh_strings.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - - <string name="pull_to_refresh_pull_label">Päivitä vetämällä alas…</string> - <string name="pull_to_refresh_release_label">Päivitä vapauttamalla…</string> - <string name="pull_to_refresh_refreshing_label">Päivitetään…</string> - - <!-- Just use standard Pull Down String when pulling up. These can be set for languages which require it --> - <string name="pull_to_refresh_from_bottom_pull_label">Päivitä vetämällä ylös…</string> - <string name="pull_to_refresh_from_bottom_release_label">@string/pull_to_refresh_release_label</string> - <string name="pull_to_refresh_from_bottom_refreshing_label">@string/pull_to_refresh_refreshing_label</string> - -</resources> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/values-fr/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-fr/pull_refresh_strings.xml deleted file mode 100755 index fb53ef8c..00000000 --- a/core/pulltorefresh/src/main/res/values-fr/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Tirez pour rafraîchir…</string> - <string name="pull_to_refresh_release_label">Relâcher pour rafraîchir…</string> - <string name="pull_to_refresh_refreshing_label">Chargement…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-he/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-he/pull_refresh_strings.xml deleted file mode 100644 index beedc1f6..00000000 --- a/core/pulltorefresh/src/main/res/values-he/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">משוך לרענון…</string> - <string name="pull_to_refresh_release_label">שחרר לרענון…</string> - <string name="pull_to_refresh_refreshing_label">טוען…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-it/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-it/pull_refresh_strings.xml deleted file mode 100755 index 415fb9ed..00000000 --- a/core/pulltorefresh/src/main/res/values-it/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Tira per aggiornare…</string> - <string name="pull_to_refresh_release_label">Rilascia per aggionare…</string> - <string name="pull_to_refresh_refreshing_label">Caricamento…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-iw/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-iw/pull_refresh_strings.xml deleted file mode 100644 index beedc1f6..00000000 --- a/core/pulltorefresh/src/main/res/values-iw/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">משוך לרענון…</string> - <string name="pull_to_refresh_release_label">שחרר לרענון…</string> - <string name="pull_to_refresh_refreshing_label">טוען…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-ja/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-ja/pull_refresh_strings.xml deleted file mode 100644 index d24842c9..00000000 --- a/core/pulltorefresh/src/main/res/values-ja/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">画面を引っ張って…</string> - <string name="pull_to_refresh_release_label">指を離して更新…</string> - <string name="pull_to_refresh_refreshing_label">読み込み中…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-ko/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-ko/pull_refresh_strings.xml deleted file mode 100755 index 53edd592..00000000 --- a/core/pulltorefresh/src/main/res/values-ko/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">당겨서 새로 고침…</string> - <string name="pull_to_refresh_release_label">놓아서 새로 고침…</string> - <string name="pull_to_refresh_refreshing_label">로드 중…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-nl/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-nl/pull_refresh_strings.xml deleted file mode 100755 index 4c063ed9..00000000 --- a/core/pulltorefresh/src/main/res/values-nl/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Sleep om te vernieuwen…</string> - <string name="pull_to_refresh_release_label">Loslaten om te vernieuwen…</string> - <string name="pull_to_refresh_refreshing_label">Laden…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-pl/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-pl/pull_refresh_strings.xml deleted file mode 100755 index 007255a2..00000000 --- a/core/pulltorefresh/src/main/res/values-pl/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Pociągnij, aby odświeżyć…</string> - <string name="pull_to_refresh_release_label">Puść, aby odświeżyć…</string> - <string name="pull_to_refresh_refreshing_label">Wczytywanie…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-pt-rBR/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-pt-rBR/pull_refresh_strings.xml deleted file mode 100755 index 0ec1ef7f..00000000 --- a/core/pulltorefresh/src/main/res/values-pt-rBR/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Puxe para atualizar…</string> - <string name="pull_to_refresh_release_label">Libere para atualizar…</string> - <string name="pull_to_refresh_refreshing_label">Carregando…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-pt/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-pt/pull_refresh_strings.xml deleted file mode 100755 index d08bc63b..00000000 --- a/core/pulltorefresh/src/main/res/values-pt/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Puxe para atualizar…</string> - <string name="pull_to_refresh_release_label">Liberação para atualizar…</string> - <string name="pull_to_refresh_refreshing_label">A carregar…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-ro/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-ro/pull_refresh_strings.xml deleted file mode 100644 index 87ddc941..00000000 --- a/core/pulltorefresh/src/main/res/values-ro/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Trage pentru a reîmprospăta…</string> - <string name="pull_to_refresh_release_label">Eliberează pentru a reîmprospăta…</string> - <string name="pull_to_refresh_refreshing_label">Încărcare…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-ru/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-ru/pull_refresh_strings.xml deleted file mode 100755 index 71ddcda7..00000000 --- a/core/pulltorefresh/src/main/res/values-ru/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">Потяните для обновления…</string> - <string name="pull_to_refresh_release_label">Отпустите для обновления…</string> - <string name="pull_to_refresh_refreshing_label">Загрузка…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values-zh/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values-zh/pull_refresh_strings.xml deleted file mode 100755 index 08766e0b..00000000 --- a/core/pulltorefresh/src/main/res/values-zh/pull_refresh_strings.xml +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="pull_to_refresh_pull_label">下拉刷新…</string> - <string name="pull_to_refresh_release_label">放开以刷新…</string> - <string name="pull_to_refresh_refreshing_label">正在载入…</string> -</resources> diff --git a/core/pulltorefresh/src/main/res/values/attrs.xml b/core/pulltorefresh/src/main/res/values/attrs.xml deleted file mode 100644 index a3408ae7..00000000 --- a/core/pulltorefresh/src/main/res/values/attrs.xml +++ /dev/null @@ -1,80 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - - <declare-styleable name="PullToRefresh"> - - <!-- A drawable to use as the background of the Refreshable View --> - <attr name="ptrRefreshableViewBackground" format="reference|color" /> - - <!-- A drawable to use as the background of the Header and Footer Loading Views --> - <attr name="ptrHeaderBackground" format="reference|color" /> - - <!-- Text Color of the Header and Footer Loading Views --> - <attr name="ptrHeaderTextColor" format="reference|color" /> - - <!-- Text Color of the Header and Footer Loading Views Sub Header --> - <attr name="ptrHeaderSubTextColor" format="reference|color" /> - - <!-- Mode of Pull-to-Refresh that should be used --> - <attr name="ptrMode"> - <flag name="disabled" value="0x0" /> - <flag name="pullFromStart" value="0x1" /> - <flag name="pullFromEnd" value="0x2" /> - <flag name="both" value="0x3" /> - <flag name="manualOnly" value="0x4" /> - - <!-- These last two are depreacted --> - <flag name="pullDownFromTop" value="0x1" /> - <flag name="pullUpFromBottom" value="0x2" /> - </attr> - - <!-- Whether the Indicator overlay(s) should be used --> - <attr name="ptrShowIndicator" format="reference|boolean" /> - - <!-- Drawable to use as Loading Indicator. Changes both Header and Footer. --> - <attr name="ptrDrawable" format="reference" /> - - <!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. --> - <attr name="ptrDrawableStart" format="reference" /> - - <!-- Drawable to use as Loading Indicator in the Footer View. Overrides value set in ptrDrawable. --> - <attr name="ptrDrawableEnd" format="reference" /> - - <!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. --> - <attr name="ptrOverScroll" format="reference|boolean" /> - - <!-- Base text color, typeface, size, and style for Header and Footer Loading Views --> - <attr name="ptrHeaderTextAppearance" format="reference" /> - - <!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header --> - <attr name="ptrSubHeaderTextAppearance" format="reference" /> - - <!-- Style of Animation should be used displayed when pulling. --> - <attr name="ptrAnimationStyle"> - <flag name="rotate" value="0x0" /> - <flag name="flip" value="0x1" /> - </attr> - - <!-- Whether the user can scroll while the View is Refreshing --> - <attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" /> - - <!-- - Whether PullToRefreshListView has it's extras enabled. This allows the user to be - able to scroll while refreshing, and behaves better. It acheives this by adding - Header and/or Footer Views to the ListView. - --> - <attr name="ptrListViewExtrasEnabled" format="reference|boolean" /> - - <!-- - Whether the Drawable should be continually rotated as you pull. This only - takes effect when using the 'Rotate' Animation Style. - --> - <attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" /> - - <!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. --> - <attr name="ptrAdapterViewBackground" format="reference|color" /> - <attr name="ptrDrawableTop" format="reference" /> - <attr name="ptrDrawableBottom" format="reference" /> - </declare-styleable> - -</resources> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/values/dimens.xml b/core/pulltorefresh/src/main/res/values/dimens.xml deleted file mode 100644 index 24339b5b..00000000 --- a/core/pulltorefresh/src/main/res/values/dimens.xml +++ /dev/null @@ -1,10 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - - <dimen name="indicator_right_padding">10dp</dimen> - <dimen name="indicator_corner_radius">12dp</dimen> - <dimen name="indicator_internal_padding">4dp</dimen> - <dimen name="header_footer_left_right_padding">24dp</dimen> - <dimen name="header_footer_top_bottom_padding">12dp</dimen> - -</resources> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/values/ids.xml b/core/pulltorefresh/src/main/res/values/ids.xml deleted file mode 100644 index 26c9ae76..00000000 --- a/core/pulltorefresh/src/main/res/values/ids.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - - <item type="id" name="gridview" /> - <item type="id" name="webview" /> - <item type="id" name="scrollview" /> - -</resources> \ No newline at end of file diff --git a/core/pulltorefresh/src/main/res/values/pull_refresh_strings.xml b/core/pulltorefresh/src/main/res/values/pull_refresh_strings.xml deleted file mode 100755 index 20cd2fa4..00000000 --- a/core/pulltorefresh/src/main/res/values/pull_refresh_strings.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources xmlns:tools="http://schemas.android.com/tools"> - - <string name="pull_to_refresh_pull_label" tools:ignore="MissingTranslation">Pull to refresh…</string> - <string name="pull_to_refresh_release_label" tools:ignore="MissingTranslation">Release to refresh…</string> - <string name="pull_to_refresh_refreshing_label" tools:ignore="MissingTranslation">Loading…</string> - - <!-- Just use standard Pull Down String when pulling up. These can be set for languages which require it --> - <string name="pull_to_refresh_from_bottom_pull_label" tools:ignore="MissingTranslation">@string/pull_to_refresh_pull_label</string> - <string name="pull_to_refresh_from_bottom_release_label" tools:ignore="MissingTranslation">@string/pull_to_refresh_release_label</string> - <string name="pull_to_refresh_from_bottom_refreshing_label" tools:ignore="MissingTranslation">@string/pull_to_refresh_refreshing_label</string> - -</resources> \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index b5554310..df54c39f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -4,5 +4,4 @@ include ':core:subsonic-api' include ':core:subsonic-api-image-loader' include ':core:cache' include ':core:menudrawer' -include ':core:pulltorefresh' include ':ultrasonic' diff --git a/ultrasonic/build.gradle b/ultrasonic/build.gradle index f70422f9..b0e8b248 100644 --- a/ultrasonic/build.gradle +++ b/ultrasonic/build.gradle @@ -56,7 +56,6 @@ tasks.withType(Test) { dependencies { implementation project(':core:menudrawer') - implementation project(':core:pulltorefresh') implementation project(':core:library') implementation project(':core:domain') implementation project(':core:subsonic-api') diff --git a/ultrasonic/src/main/assets/html/fr/index.html b/ultrasonic/src/main/assets/html/fr/index.html index 0fc3ee9c..81334bf9 100644 --- a/ultrasonic/src/main/assets/html/fr/index.html +++ b/ultrasonic/src/main/assets/html/fr/index.html @@ -33,7 +33,7 @@ <li>Écoute et téléchargement illimités vers autant de iPhones et d'appareils Android que souhaité.</li> <li>Lecture de vidéos.</li> <li>Une adresse web personnalisée pour votre serveur Subsonic (<em>votrenom</em>.subsonic.org).</li> - <li>Aucunes publicitées; dans l'interface web de Subsonic.</li> + <li>Aucunes publicités dans l'interface web de Subsonic.</li> <li>Accès gratuit aux nouvelles fonctionnalités avancées.</li> </ul> diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/BookmarkActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/BookmarkActivity.java index cae4632d..d9a69532 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/BookmarkActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/BookmarkActivity.java @@ -27,9 +27,8 @@ import android.widget.AdapterView; import android.widget.ImageView; import android.widget.ListView; -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; -import com.handmark.pulltorefresh.library.PullToRefreshListView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import org.moire.ultrasonic.R; import org.moire.ultrasonic.domain.MusicDirectory; import org.moire.ultrasonic.domain.MusicDirectory.Entry; @@ -49,7 +48,7 @@ import java.util.List; public class BookmarkActivity extends SubsonicTabActivity { - private PullToRefreshListView refreshAlbumListView; + private SwipeRefreshLayout refreshAlbumListView; private ListView albumListView; private View albumButtons; private View emptyView; @@ -70,13 +69,13 @@ public class BookmarkActivity extends SubsonicTabActivity albumButtons = findViewById(R.id.menu_album); - refreshAlbumListView = (PullToRefreshListView) findViewById(R.id.select_album_entries); - albumListView = refreshAlbumListView.getRefreshableView(); + refreshAlbumListView = findViewById(R.id.select_album_entries_refresh); + albumListView = findViewById(R.id.select_album_entries_list); - refreshAlbumListView.setOnRefreshListener(new OnRefreshListener<ListView>() + refreshAlbumListView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override - public void onRefresh(PullToRefreshBase<ListView> refreshView) + public void onRefresh() { new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -472,7 +471,6 @@ public class BookmarkActivity extends SubsonicTabActivity @Override protected void onPostExecute(String[] result) { - refreshAlbumListView.onRefreshComplete(); super.onPostExecute(result); } diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ChatActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ChatActivity.java index 2e4bf1c8..e91fc007 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ChatActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ChatActivity.java @@ -5,6 +5,9 @@ import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.inputmethod.EditorInfo; import android.widget.EditText; @@ -13,10 +16,8 @@ import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; -import com.handmark.pulltorefresh.library.PullToRefreshListView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import org.moire.ultrasonic.R; import org.moire.ultrasonic.domain.ChatMessage; import org.moire.ultrasonic.service.MusicService; @@ -37,7 +38,6 @@ import java.util.TimerTask; */ public final class ChatActivity extends SubsonicTabActivity { - private PullToRefreshListView refreshChatListView; private ListView chatListView; private EditText messageEditText; private ImageButton sendButton; @@ -51,9 +51,6 @@ public final class ChatActivity extends SubsonicTabActivity super.onCreate(bundle); setContentView(R.layout.chat); - refreshChatListView = (PullToRefreshListView) findViewById(R.id.chat_entries); - refreshChatListView.setMode(Mode.PULL_FROM_END); - messageEditText = (EditText) findViewById(R.id.chat_edittext); sendButton = (ImageButton) findViewById(R.id.chat_send); @@ -67,7 +64,7 @@ public final class ChatActivity extends SubsonicTabActivity } }); - chatListView = refreshChatListView.getRefreshableView(); + chatListView = findViewById(R.id.chat_entries_list); chatListView.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL); chatListView.setStackFromBottom(true); @@ -114,15 +111,6 @@ public final class ChatActivity extends SubsonicTabActivity } }); - refreshChatListView.setOnRefreshListener(new OnRefreshListener<ListView>() - { - @Override - public void onRefresh(PullToRefreshBase<ListView> refreshView) - { - new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - }); - View chatMenuItem = findViewById(R.id.menu_chat); menuDrawer.setActiveView(chatMenuItem); @@ -137,6 +125,33 @@ public final class ChatActivity extends SubsonicTabActivity timerMethod(); } + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.chat, menu); + super.onCreateOptionsMenu(menu); + + return true; + } + + /* + * Listen for option item selections so that we receive a notification + * when the user requests a refresh by selecting the refresh action bar item. + */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + // Check if user triggered a refresh: + case R.id.menu_refresh: + // Start the refresh background task. + new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + return true; + } + // User didn't trigger a refresh, let the superclass handle this action + return super.onOptionsItemSelected(item); + } + @Override protected void onResume() { @@ -276,7 +291,6 @@ public final class ChatActivity extends SubsonicTabActivity protected void onPostExecute(String[] result) { load(); - refreshChatListView.onRefreshComplete(); super.onPostExecute(result); } @@ -286,4 +300,4 @@ public final class ChatActivity extends SubsonicTabActivity return null; } } -} \ No newline at end of file +} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectAlbumActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectAlbumActivity.java index a96159a2..769e7e0c 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectAlbumActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectAlbumActivity.java @@ -27,14 +27,12 @@ import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; -import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshListView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.moire.ultrasonic.R; import org.moire.ultrasonic.domain.MusicDirectory; @@ -60,13 +58,11 @@ import java.util.LinkedList; import java.util.List; import java.util.Random; -import static com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; - public class SelectAlbumActivity extends SubsonicTabActivity { public static final String allSongsId = "-1"; - private PullToRefreshListView refreshAlbumListView; + private SwipeRefreshLayout refreshAlbumListView; private ListView albumListView; private View header; private View albumButtons; @@ -91,50 +87,23 @@ public class SelectAlbumActivity extends SubsonicTabActivity * Called when the activity is first created. */ @Override - public void onCreate(Bundle savedInstanceState) - { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.select_album); albumButtons = findViewById(R.id.menu_album); - refreshAlbumListView = (PullToRefreshListView) findViewById(R.id.select_album_entries); - albumListView = refreshAlbumListView.getRefreshableView(); + refreshAlbumListView = findViewById(R.id.select_album_entries_refresh); + albumListView = findViewById(R.id.select_album_entries_list); - refreshAlbumListView.setOnRefreshListener(new OnRefreshListener<ListView>() + refreshAlbumListView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override - public void onRefresh(PullToRefreshBase<ListView> refreshView) - { + public void onRefresh() { new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } }); - refreshAlbumListView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - for (int i=0;i<albumListView.getChildCount();i++) { - Object child = albumListView.getChildAt(i); - if (child instanceof AlbumView) { - AlbumView albumView = (AlbumView) child; - if (albumView.isMaximized()) { - albumView.maximizeOrMinimize(); - } - } - if (child instanceof SongView) { - SongView songView = (SongView) child; - if (songView.isMaximized()) { - songView.maximizeOrMinimize(); - } - } - } - } - - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - } - }); - header = LayoutInflater.from(this).inflate(R.layout.select_album_header, albumListView, false); albumListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); @@ -1319,7 +1288,6 @@ public class SelectAlbumActivity extends SubsonicTabActivity @Override protected void onPostExecute(String[] result) { - refreshAlbumListView.onRefreshComplete(); super.onPostExecute(result); } diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectArtistActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectArtistActivity.java index 48aaef8b..7b838b22 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectArtistActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectArtistActivity.java @@ -32,9 +32,8 @@ import android.widget.AdapterView; import android.widget.ListView; import android.widget.TextView; -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; -import com.handmark.pulltorefresh.library.PullToRefreshListView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import org.moire.ultrasonic.R; import org.moire.ultrasonic.domain.Artist; import org.moire.ultrasonic.domain.Indexes; @@ -55,7 +54,7 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter private static final int MENU_GROUP_MUSIC_FOLDER = 10; - private PullToRefreshListView refreshArtistListView; + private SwipeRefreshLayout refreshArtistListView; private ListView artistListView; private View folderButton; private TextView folderName; @@ -70,13 +69,13 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter super.onCreate(savedInstanceState); setContentView(R.layout.select_artist); - refreshArtistListView = (PullToRefreshListView) findViewById(R.id.select_artist_list); - artistListView = refreshArtistListView.getRefreshableView(); + refreshArtistListView = findViewById(R.id.select_artist_refresh); + artistListView = findViewById(R.id.select_artist_list); - refreshArtistListView.setOnRefreshListener(new OnRefreshListener<ListView>() + refreshArtistListView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override - public void onRefresh(PullToRefreshBase<ListView> refreshView) + public void onRefresh() { new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -347,7 +346,6 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter @Override protected void onPostExecute(String[] result) { - refreshArtistListView.onRefreshComplete(); super.onPostExecute(result); } @@ -358,4 +356,4 @@ public class SelectArtistActivity extends SubsonicTabActivity implements Adapter return null; } } -} \ No newline at end of file +} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectGenreActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectGenreActivity.java index aa038463..996edd6d 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectGenreActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectGenreActivity.java @@ -29,9 +29,8 @@ import android.view.View; import android.widget.AdapterView; import android.widget.ListView; -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; -import com.handmark.pulltorefresh.library.PullToRefreshListView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + import org.moire.ultrasonic.R; import org.moire.ultrasonic.domain.Genre; import org.moire.ultrasonic.service.MusicService; @@ -50,7 +49,7 @@ public class SelectGenreActivity extends SubsonicTabActivity implements AdapterV private static final String TAG = SelectGenreActivity.class.getSimpleName(); - private PullToRefreshListView refreshGenreListView; + private SwipeRefreshLayout refreshGenreListView; private ListView genreListView; private View emptyView; @@ -63,13 +62,13 @@ public class SelectGenreActivity extends SubsonicTabActivity implements AdapterV super.onCreate(savedInstanceState); setContentView(R.layout.select_genre); - refreshGenreListView = (PullToRefreshListView) findViewById(R.id.select_genre_list); - genreListView = refreshGenreListView.getRefreshableView(); + refreshGenreListView = findViewById(R.id.select_genre_refresh); + genreListView = findViewById(R.id.select_genre_list); - refreshGenreListView.setOnRefreshListener(new OnRefreshListener<ListView>() + refreshGenreListView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override - public void onRefresh(PullToRefreshBase<ListView> refreshView) + public void onRefresh() { new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -181,7 +180,6 @@ public class SelectGenreActivity extends SubsonicTabActivity implements AdapterV @Override protected void onPostExecute(String[] result) { - refreshGenreListView.onRefreshComplete(); super.onPostExecute(result); } @@ -192,4 +190,4 @@ public class SelectGenreActivity extends SubsonicTabActivity implements AdapterV return null; } } -} \ No newline at end of file +} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectPlaylistActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectPlaylistActivity.java index 0ba31f04..eeeccd2d 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectPlaylistActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/SelectPlaylistActivity.java @@ -40,9 +40,7 @@ import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; -import com.handmark.pulltorefresh.library.PullToRefreshListView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.moire.ultrasonic.R; import org.moire.ultrasonic.api.subsonic.ApiNotSupportedException; @@ -63,7 +61,7 @@ import java.util.List; public class SelectPlaylistActivity extends SubsonicTabActivity implements AdapterView.OnItemClickListener { - private PullToRefreshListView refreshPlaylistsListView; + private SwipeRefreshLayout refreshPlaylistsListView; private ListView playlistsListView; private View emptyTextView; private PlaylistAdapter playlistAdapter; @@ -74,13 +72,13 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt super.onCreate(savedInstanceState); setContentView(R.layout.select_playlist); - refreshPlaylistsListView = (PullToRefreshListView) findViewById(R.id.select_playlist_list); - playlistsListView = refreshPlaylistsListView.getRefreshableView(); + refreshPlaylistsListView = findViewById(R.id.select_playlist_refresh); + playlistsListView = findViewById(R.id.select_playlist_list); - refreshPlaylistsListView.setOnRefreshListener(new OnRefreshListener<ListView>() + refreshPlaylistsListView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override - public void onRefresh(PullToRefreshBase<ListView> refreshView) + public void onRefresh() { new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -379,7 +377,6 @@ public class SelectPlaylistActivity extends SubsonicTabActivity implements Adapt @Override protected void onPostExecute(String[] result) { - refreshPlaylistsListView.onRefreshComplete(); super.onPostExecute(result); } diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ShareActivity.java b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ShareActivity.java index d7a2d237..9e012dd6 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ShareActivity.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/activity/ShareActivity.java @@ -41,9 +41,7 @@ import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; -import com.handmark.pulltorefresh.library.PullToRefreshBase; -import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener; -import com.handmark.pulltorefresh.library.PullToRefreshListView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import org.moire.ultrasonic.R; import org.moire.ultrasonic.api.subsonic.ApiNotSupportedException; @@ -65,7 +63,7 @@ import java.util.List; public class ShareActivity extends SubsonicTabActivity implements AdapterView.OnItemClickListener { - private PullToRefreshListView refreshSharesListView; + private SwipeRefreshLayout refreshSharesListView; private ListView sharesListView; private View emptyTextView; private ShareAdapter shareAdapter; @@ -76,13 +74,13 @@ public class ShareActivity extends SubsonicTabActivity implements AdapterView.On super.onCreate(savedInstanceState); setContentView(R.layout.select_share); - refreshSharesListView = (PullToRefreshListView) findViewById(R.id.select_share_list); - sharesListView = refreshSharesListView.getRefreshableView(); + refreshSharesListView = findViewById(R.id.select_share_refresh); + sharesListView = findViewById(R.id.select_share_list); - refreshSharesListView.setOnRefreshListener(new OnRefreshListener<ListView>() + refreshSharesListView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override - public void onRefresh(PullToRefreshBase<ListView> refreshView) + public void onRefresh() { new GetDataTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -374,7 +372,6 @@ public class ShareActivity extends SubsonicTabActivity implements AdapterView.On @Override protected void onPostExecute(String[] result) { - refreshSharesListView.onRefreshComplete(); super.onPostExecute(result); } @@ -385,4 +382,4 @@ public class ShareActivity extends SubsonicTabActivity implements AdapterView.On return null; } } -} \ No newline at end of file +} diff --git a/ultrasonic/src/main/res/drawable-hdpi/ic_menu_refresh_dark.png b/ultrasonic/src/main/res/drawable-hdpi/ic_menu_refresh_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6cae3ecac303d7aef2320669041a7e40ab9df576 GIT binary patch literal 498 zcmV<O0S*3%P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0005GNkl<ZcmeI$ z0c2Z20LS6OLs2{w!B7+d48>540fwO{iUEeAfMIwTilTrb2!>$@iUNkA7=j`wf+7fl zA_%?#IEhH&E^D|C0P+7xF5bIP6h%=Kso(_H=-~lF4Dp0JT;T(%umW6$+;D&!jIC~j z2KBP>kaKv2Z<yHJ1Q(0PlPv%({E^N*4x;h70?@{@#m4C36z_0|L%hWqx_GhJ01add zKx^@MBV4R<I8mcn5|SqXdw4MK9(7m~4l&qfz<2X*P=yU)AEWF6XkjXLm*8`6Ab$W| zu_5+zkB3yh{TH#%8OCP|_$2m}VSLtrj@VU(@mT{N#7;7d&l)fkdlPnvn6P~%;90D- zYXN`7j(08Khgh>~0q0`<kOB5EPVtu=!9J#9A2S4e5ql1)peOc-D)Gg@SnN7wz!7F* zorISIJ+TSukP>dqyUg@X@HM1{8Uyn>s5U%XKh67%D&&ARCgwe^bFgu`<Z_^u|N4*@ zi}lgq7_Io*^BxU`78{`*wgGJnq|@K}BMNGCFtfQC8dTwbK^wg_L#DXJQFtv-;~c-x o#|Qvp4A8|H4nk2BMNuU153dCaU2~@$ivR!s07*qoM6N<$f(6{u#sB~S literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-hdpi/ic_menu_refresh_light.png b/ultrasonic/src/main/res/drawable-hdpi/ic_menu_refresh_light.png new file mode 100644 index 0000000000000000000000000000000000000000..3a8c89e88126ec576ce5d3e735f88dde0c822a32 GIT binary patch literal 492 zcmV<I0Tcd-P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0005ANkl<ZcmeI$ z0b~ME7{Kx2A%sIX48w4MAq-&*FbpAt0frD@7!E@S0YV7FFoZC`FoYq5LkQsz!VtpS zAAygm>btka`||^MeP6kA-I-!OpU>y>mC!^F158%N=%ayK80=CVnO8syGuR!ah!JcV z-XgOMo-v0#&>Xe(!y}_Ye8DRDKtT=<=oeuMD`AE%%DBeG$`vZ;;s;hjf*4j%EnG8v ziW&^I6(E+2tfyBFgEc>YfPK3_;&Oo(SfK@jL(3y|u|SB0IJl2vYq|Oby5i6Y^4Sj$ zg>v$O!-JdQq0qfJaO`e)DAW-LHrx#lh2*WX<ZgH<G!X}$<D{~J>-+-p*(bzF^(_`C z;-q>N3&c37s$zj5vM7g{#w}Zxmk)BdgLaSNGp10hCk`LMK&yiM_R)k|mspAq=s+VQ zzaY#JK(#ikP|xT;!4uRAkiZHZm;<k^H(22l2ALFL4l9iIys*m~UJiuFw9<w*3PZ#w zia`S0AjSk1Qi=#pijcr686t$!0(7v1J<t*{4F0SLy*(FMpp8rXn*vnvjv-R<$}vF~ i6%=rEKA+F$^Zf!-GlG!>>)3Mu0000<MNUMnLSTX={mnH1 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-mdpi/ic_menu_refresh_dark.png b/ultrasonic/src/main/res/drawable-mdpi/ic_menu_refresh_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..50c5f22f608fd24a33aaa5c30e70c2edd58f6753 GIT binary patch literal 412 zcmV;N0b~A&P)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0004FNkl<ZSPAXH z5qDd0901TC76O4lU=Sz-3WY&n&~pZZK`<}~79S1@`3Qx5fIy*87~}&C0)gV7FbEU^ zg+O5N;I7bf{&{E1lJ}CH2Hw3<tJRJXS{ULEGt4o^6gL>45gQ<jLqHqfklSvB5gM@u znP;&te8y6Fk9Z%?ka-dNK!#k=3>kXppo0&%!cRpjjID{P&{y;eA7cv)v9v){feu!Z zDO#~3bg}RcQ3b}52Q;GuWHyMhaH^;mB_Q)3Q5L>RCQ$-1TSQryO1{L7kl8_$g-6M| zcx%?gF|a0%0Tz;WyfxfQ`mrZul5v!Uk>ob^gqdU*W#L?sqZ<|BLh>8Ur~(to3@1?% znwU$jqbi&sm)zkbc7z6|k|(rcAGlOBLpQcS4-bky#UbEYQI1>m(T*2rV}S4emc=3A z61no07{qJ9876j<;|860Z8*mW_gF}t@B>#kjasdCg#G|@Di7Faoa%T00000<MNUMn GLSTY$1f=W$ literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-mdpi/ic_menu_refresh_light.png b/ultrasonic/src/main/res/drawable-mdpi/ic_menu_refresh_light.png new file mode 100644 index 0000000000000000000000000000000000000000..060433d34738468d29d80216489073480899a883 GIT binary patch literal 391 zcmV;20eJq2P)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0003_Nkl<ZcmZM< zq+k?`f>9s>#PLA98i<br@qIu$bpV+_6vuHKU<e_EA%qaZ5QZ@fLx3;@2=D+y2mlZU zfDpnk1b`tN0t{goLKs3A4!?cz$9c@{-Mtj<%Ljnp{heplSYU`6{>mXrO}rq5avU** zKg>ZW-6IZApdD_!F({XVf0YCdeYDIiCisAVtvQrYxB-;$iF@QV%DHHvS~x;xjRyW( z2m5G)yfbf6M@TN_h1yU?KjIjK_Y9d;<S__u4VkCNV-VgBGS@hJd0$fv+C!#^v$uiF z0A+KKnIpI<WR@sf0+|tl>p><(2SvMs%n#}))Cw{Qt`J%sUyzxha9yO3c?}#@^B&l5 zG*GHBl#!r=y!zNe84rlk49ZBc#K3zJni%2@@;F3oj1&rVzz`>?ixq@CDHdqq<n=Jc l27B+Pea8fCR8>`7T)(nc*4Pk_w;})l002ovPDHLkV1kb&m^}ah literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xhdpi/ic_menu_refresh_dark.png b/ultrasonic/src/main/res/drawable-xhdpi/ic_menu_refresh_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..415da26a96bce8e9652d1a2e128735e2b8f069cc GIT binary patch literal 712 zcmV;(0yq7MP)<h;3K|Lk000e1NJLTq002k;002k`1^@s6RqeA!0007yNkl<ZcmeI& z0c2Z29Khj25e!993`H>%#ZU}o2#O*oieVUvpeTj_0EQtLhG8gzp%{vyC<+*YA_$7& zA$a%(P~2<Nwt08m?&AT#FE4-h?k*HXQ4~c{6h%=K{|7ALJq8$JgmYZodM@x2pRtWj zcp~&euJ8(b_<<V_H^T@$bRH82LT=E(A#OaMDf;L<Bo5^EH~N5y#hIWtZyX3Yz$(tQ zXN2YEI2i@PTTHd@3Y+mbnFPW<X6932giqMT7S?V(T^wM9%6uxkLm#pVgb(I(f*o`o zIOz9q;eIp7DiF3%yW0h}!xN#4u}4Y~=QXC9)i_+h(qWi=AS~fhvkKh>&%8S4Kz+?_ z@Fpx6zGoQ-%eWR-<9*^ED0!fPW(PUOfi_plGjXTs<D?ICpxI{nIOzlZ7WXsfIMCL< zPAzULeVp`x_Qg%IjFTYHH*w#xjFTYHFL67e2mu%3-i9IsOvJqoMF_-&q6C@?rs7sZ z5dtnXe_|9k5!VgHof}kNLMHG-Tt6%tK8hP>bktoX8v|I;Y$GIwU2)UU7MzJ2h6ECB z#l+!AT#faR2(~rb4Q;_1YH`OQ5uAw|V=1%=Up4C`h;yXbr&L#5Dsfet3rD;|EpCcV zNC5-QCRj~>-Nt_Edxux|MA}^Nn^S3a98$vuD$OeN7IgG9(`<s3kOS<v-|=%S0kDo! zcdM}-a)Qt9S7V5cN6wlNYImz6Z*1m~;>P%bE;erubgW<<Jq$4x7mt%O?4Z)VYjnd) zfDK$}&+iv^Xn<E3pt3j>4#P`^ReVM5`P^WD<?ye-8jf)0acZ35C_$KZVFe%Y9VfWN u6ad%wgHsH#mnce66h%=KMNt$*k-%TWobJK`zfX$*0000<MNUMnLSTXso-Wk@ literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xhdpi/ic_menu_refresh_light.png b/ultrasonic/src/main/res/drawable-xhdpi/ic_menu_refresh_light.png new file mode 100644 index 0000000000000000000000000000000000000000..1e93351481cf5b1302d4467a163d0fd7c7838f76 GIT binary patch literal 698 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U~2SqaSW+oe0z&Ar6^FM{UiTF zr51rU#Tt%8i8cu*i9-fFhk;xkMg|~p*r4TuA`cKAXcquVxmr|wXGlBuc178F+uZku z`4xV~@1625W7e`v2-?3)#_yt|c<r9VZzm=6cR2G3mc3;=IPJLQyp1h68Lf7+I=0EU z3&aTKnadtcY?OAH-P_!7>Y-4vhu5==JOjQ%D_YDu)N4iVJXUDv+t5&9=6uzVZ_`^Q zZH}0vFNM9vGLJt@wu*Y8eD8s&|D@xNZLv-dj2xIRwzdD0N$zNV&6s-0kSC?rFzd!v zt7Q}3{&;_&u$U+B<6PGlN<SKlW?1Ao**=|}-XwdXkZ1aj?k&|^r3;wuDT=Wzm$XqZ z?=My0j7scd_Mf_;DT3#)Ec?7HN1+f9UDX<~r^S}fW=eZwgiJe-QNp-!M!P+q%@>Z1 z6+HDa6))tEEMn|ECeW>%VbUHU<8b@u=C#b3+#Rl*Qoh&fk6vIC=(aMcYKpj{JY}Au zn7PMZ?T(`&iXw{VKJkbsa%!E}W!!O;>7JCM&aMyhzt2y)vlZy3)Ra)(Ne_7LS+z7q ze3=ls*z~(0`+8dkA(Mx@%~TGW?g@9|+1L@-y52A0n#^;KnO7QBW-Jyta6eaXLS*F` z8RgK4Vd@=<oK+|GbUpSxrg?XXSXf_su#14H0-x=ajoGO@irErZ1VYLM*qimVqVLVJ z<4NIdR_kbzJ(=58eI@X3(S>e}#hrS~1Qfm$-Z2$$wyAcPtqx>0?oeNEaUgE0JG-HZ zs$t&7>r+24F#lBZE(ti$|56~gM<LokVqq^+U5RVVLr!L&4L^zs{wH_noeOM$rI1<Q bxPLLUdB^OEwzoeEOp^?ru6{1-oD!M<)?yqa literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xxhdpi/ic_menu_refresh_dark.png b/ultrasonic/src/main/res/drawable-xxhdpi/ic_menu_refresh_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c00e8404054a0c53fbe469b85851d06a17aa128e GIT binary patch literal 1017 zcmV<V0|xwwP)<h;3K|Lk000e1NJLTq003+N003+V1^@s6k7ifR000BPNkl<ZcmeI) z0Yqe57{Kv^K?sYm2q8R#!6JlMgfLiy#UKnG!Xi9`MOcJI2!jw7A%qaZVh|n%A%sB) zVKDeTz+3Nm?w#gM-Fxo$V*r@(pE>iL<KCM>2qA<JLI@#*5JCtcgb+dqA%teZDz?zY z0giEwpSb_!HNZ7a@C6;Lq*sK!rbgPpR}9VW9>>_h!aQR^Qv$WHg%ga-&olbioJTB3 zxx)_byuMp>(3(9K*$2ZW2HxHsI<v&eIvCoxP(2q|nI#tF_CIxqiRv1oS2k9*!LW!6 z^>K#9X=6by`>3J%8De#sSdhbD@o09BIKu&Y=wKZyzq~%+6ZY`~BeNS}tsqt&!LW;o zm%GCuHf9`f4sh?~p79;B4Tg_1#5zZNPVed3oYgVbZ+J4j8*IGNGJT5(hIbg6&OJJB zu*KNJb7O;{g-g@9#{2X}u!cXI8tlk)PSC2z9`U?U!LXsc3HB<uI`o?q>{@xfR6*El zL@;!ecbs!9sKcN!RL&Jz)sB^auwCWcVJY`ml@5jljFhvPf2`^U>ni6mgIHMvJ6CLi zc2i<Om6yY@V*Mt?g1V3LD;dPfBG`#yHyOmrCfK85Uz!#R>U?gv+O$|u*Uj><I<X?y zfnwiMsMWx+o2nt;Lb2^s4FLniKBQ_0cu;IPRYREPq!c1pz(}$8sTu-q6>Fzz2)I;i zD^){4U$JfqwK|$QOw|z3Q*6-C{pV&?@BPxG%`?^&8)KoW7mq$G*2^f^SH&(<RpC^z ztBiu(DYl=g3ZE65U@3!GAC$9R_2+I(6g$cw*tud)sp@d0*chvs4;yfj%Xkl`H4b*I zoVB{#fc^wIo-JZqIp?V^u&<l}7E?`N8IQ`@tW&TBJmj=AqJ<mf{7iL&uJZm!6^BFR zb?O+bh1(oHB=(ednd%DL%6mqq=CPh?e^!b!sN?d8Z>IApm#2;nOy~41r$;Q|hv}T9 zTwoa^(;1-sM$7ofbRO_7<pk>(o8Bo_U+GKLH@#=HQ;zW2%Zza}k5hiM(Z}S4u{Pq` zkN-Bo6?#~n@z>PFB|yX~{-ur0Zh%8{v4u9?|6_Pq#U^&}9YcVKH3h6=q<%(u$0}Z$ z2I}JiOR34Qh%?nT#_uWo4coX?J-1j(;os0g7Z2Xv9d;F8Qy8#-eLQ)6Lv+zf(+PNo z9<DGkUpMHa|5XeppK*$3vm2q0ojFf_0WEw)4+rSu61Nxu;1NSy;}l2u5<^7ugb+dq nA%qY@2qA<JLI@#*5JLD18vch`zg#4600000NkvXXu0mjf!ZF>J literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xxhdpi/ic_menu_refresh_light.png b/ultrasonic/src/main/res/drawable-xxhdpi/ic_menu_refresh_light.png new file mode 100644 index 0000000000000000000000000000000000000000..0c7fa34050afaa487f4f7713a9b1267c1087d2e7 GIT binary patch literal 1002 zcmV<G0~P#<P)<h;3K|Lk000e1NJLTq003+N003+V1^@s6k7ifR000BANkl<ZcmeFe zfdBvi0Dz$VsTZjN00000004m5wFAi1+BlBma1g=}hA@N|Ll}k-!!U%4VF*Kb5r*MK zxCj@+#SlUW7a@cYhKmqhgfI*TA%qZq_Y0Q+&pFPj=Q+>w<pV(Zk^edJt_p6^L<g@J z;WyqtnPY|?p3uMrj#(RCR>OBJp^V<~ihC3eJeJ@^5pK~#3?0Z8ebfCh)4E9l4; zXdwE!v5@2Hm_sMFLgQ=3LJq593|VH3i)>>dM@8sj4_Ru5R)(>VkBS&Wju@htek|mm z3YL&#mZ+p03vO4(8p>#mAv$QGfooiRa)obr#xKNBMlmjvj|GQIKo)<rGjfz!cz z#%H&mP@V_7$uQOk)dPK|8FXOI^$#{sN^hv)(ABX(7>v%agi?4%1IH{v8(W_Ti!gyw znBg3!>JtC^I@k-8LJtv6T@fSS2CG2{?a_u!Md<r9*bGXj1siMoGFSsj=r!MC!SW(3 zp#-Lg@;w$T?-5F1g^~wj!QKjpp#<uFj0KBpLJ3U#84DISf(-Vk`ZE?Rt$-b5(D!UC zxP8iB_%#+Rtp^#r`8O6UZ4DVbc{dhZes5UuZY;R^u)OqhELd0vGWdazLkGtrEGaaG z4DMh_p*du51xpHjKn7*lQ0TyyQYZ`-iXnq@SW;*K8B}3Op$TMg3rh<1A%iAD4!xS{ z!jeKQ$YAd2^Jg8_bpv_!@O%v!>`;JpMc6_HE##%|kii7jHh>JK$V)58;2GBT02%C2 zg6myD30%Y4ir7O2FL1pPWUzttO(BCFD!D#3fL=b%dtd-pn?VU&!urmzfpYq8@eWF0 z1ZR4N5}2b1S1Mx-B~XVm74VU>pT-DpPy)Z<TumsU|6qGvD4_<NE5aftU$PA)G=a0- zK?!ZqaD1!{%5b_N<mk`i4=9CiaK0kuPznPSajHuA1*I@VZYm>&QkbKPV|RxbO5p=% z$W_<aK`9MT!J#Xo52dt46}jvILRve#poFikiaz#8Jr-*I{`bRdk11Liudy<km_UH% zV;OqD4$5ebE}FPS73cU{2^G|FkDpjVKo~1c*N7p<#Hhi`%9ulr7^4KQD`E&)Y=?gl z`qUj3kYyIQgr6CT(8LFHVk<nNfRLdAp0R<BY>6f!q%3rX7N*!k2lR#pzNk<U4;Wwz zWfY^2dz5g%LJ@AzLI-_Jus{q!SYwG926(|!I3oP(PkV46000000ObGL2&$^8s;a80 Y0_f0?@q4r4=l}o!07*qoM6N<$g6(0d0RR91 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xxxhdpi/ic_menu_refresh_dark.png b/ultrasonic/src/main/res/drawable-xxxhdpi/ic_menu_refresh_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..3461b2a74f46d804363f2d0d435ece67f21cde79 GIT binary patch literal 1277 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=_6GQbxB}__Ll$&Z@5=#tz`i8N zFPK5Xz&*Zx`ugMdPw(G7IbT60{rCUx+siFjbgJJk_O|K2{oFxC;B&F_`Rv*Ac|`n8 zx;H<*epn+odG+Pj(d``JCoRPS7#Ns0c)B=-R4~51eRWq;ltk-8#xiZ@Z8uJ86_-~3 zpT3oUX2K!+yO#HpA74(N#>jKn0D^kzO;4XoDgNoSF+^*s_SGoc%LiOv?Py9{{i>k< z_1}x%&VLiwRk|xx?&@p)KbLJ=!VX`Yk?!L*H`unt?Jbvn&<wfvid$xiR%|@=C4zrp z=hX5UE(<Gnv|mV?$2}vU;PLS)6Slj4GY-Y7Ut6sE;$EVbW7+<8fzR?YZY4>+S6mV% z$~9$e1i#`H&5s*4Za=a0+FQ598)t6Y*6(lgW~bm=#S}J1{>qp8l%8$<`r=c=$?Unm zn(pm5|MA{zi;R0(Mez=`j%5dI<&EbUe63((S)+a|)Xd^=-Oi{9{}0VL&!{)y@2;Q= zO@V&bkGno=UCnaWKuh95QmK1=z_G+5JDOR{gzq}8mQ&W!R{0clNya3}<-WVqHJ9uQ zXO^ydrM%K=E8EwVRr5|)J#jP(J-B*<yIjb^Lnk?^pEzz0x$6O>%0on!+J0JK8XCOT zR>Xf}(-wERC*LKC;=X<huv#KMt6JlZX^i(BW&Wz9jD@?~4~16gzMIJYRHA75u4;{F zQSL`_l@nZ#?%v@pw`F0HDo~17qN;Ju4Qprq3Bsohr!>#G;rz+4HnyLKS3x~2Era>5 zi*=-MQBueQ24R!L6HRrC_Fiq9GvjywTTv2s+orVF77LCB$Q31Jx2>8WoNfF>XQAWd zuAOh*-M_HlT!7@sUddO^&Ejo!6YlUkAJjh*CbBNaSu5}Byw1C-K|d~8e_YKIdZhiv zJsBri_dS>RR@`t};ovHr`G<{Xr*FrN5T6=e{j7x_d3QNl-4C%aV_9~^P~oqksNAK` zr>l-V?wj?kUr==2(&sX#6O?T&Pq;sxvZ}K+M9OwmoZ^GP&_7f86~q)0t(O#B|8Bp6 zOX}0+eJ^foSYxn=b!OY?j(_=w=83!6IBA_;v8a_LY~wtA?xbipU$Y$%yN|3eKk-v; zaZ`TGv+~ylS&XvN&i8!Gi8=5u<;-W9s54bPg<`&Q68~EC%sjK;<l4g)<<`eJH?vPK zoE)A}e7<(?pSSva(qbn>Y(M=EVf*`DHEGTJqr&IEow)n0VnXoQ=bI#NGlgw_xz6<0 z60dsyjBh@Tm$bJ;SNXh6?$iFT-ABFR_|%lxWdZXZW=V0kd;a~gL+y65(oxNIxmD_W zJRJ7loguEd<)iq={oIV_3%JbwdF^j**O&Wx_5ZdH*QNjU>^#4+#9UxP=C<o=?;P4a sdqVvAssC2YKC6=`(FR3-y8m+O6sg5d-Z#q<SPU?Dy85}Sb4q9e07oLhHUIzs literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xxxhdpi/ic_menu_refresh_light.png b/ultrasonic/src/main/res/drawable-xxxhdpi/ic_menu_refresh_light.png new file mode 100644 index 0000000000000000000000000000000000000000..a5c09db5ee1bcf5c754fc99ac571144809bf7ddc GIT binary patch literal 1277 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=_6GQbxB}^+3tnF;J_B^UeMyjC zFoT4Fdwl)$^~dj@-oJZtzJg5p@BiPoms_ytRKH*BZPS1Ixr2(p=VIsc*|X>Ki1?dy zZ+?9Jutsq5>dUXA+d0BdT8afQFfecMba4!+V0?S~>aM0JiPndVW!lW!Zk*IAF0KAQ zeJlUWghTdsE$=5kzMMXdk>{`h1ohOLo<5gS{L^V;h}Kl?t5LR>54gVC(Ui9ORYCvj zzZbuq|0b}jbXTg})z|!gF59+*9lkgt-N$Wiux*RmTQ2>e8FKFxx6Bl+*m&wo1pmU$ zspT_V7FO<PzmPPKdqzOP<KtB(Y<K-;9Ew%HwpjPYy+kd?vi<D>pXF!VN|Jo9xFk%J zYs%UPe#I-AA2)2=eq!sjw{D9!&fK=G-{0oVPQkZ|DQt}Vl`r=xJ=^;A#ixdo*>it2 z-P>{g<GtAy8TYh`;vH%o%MRGe8_zNLTEWJ$M*Uc*nZ@C{olz71ADVHVQE$TET|pO` z0{yNZcYW5nn&qy6mc)akQuq3RV~Iz0G_#lq-*sFqr>v!|@+s<)j7gHqeRrp8F4-5( zEM4_Vd8O4>wy!Iz=AEv3;%F9naP<avxsZj2PI6Q~aoiqq*8@nEhlnh-{j|U|G<dD8 zi2uf>E$(tpzDpFvef<_-wM2YYwZ<LO81FmE{8dRA3wO643a!$8H<A6RMA7tJ)f&;F z+>hicC%7Kny~AB@%fcj8pcJn}RpXo+*3SGBgijkzX`XY#`IBL7Y(EdLf_hk52J>GR z>qz0Eq>u*;!X}9)n(7wqz1lWs#_<5Qq9pFNO=+(!790(bD@w|4TQxyA+xUsjLdVHn zJKwy!e__G70LhcRlCPYb#oOv8+~IdVsDC6(WL=K4R^Hcnop)7(eq6HtxSA*QNc)X@ zGETDYdoJ;<xZ$+I!Bsl*4;#-;-;Nt0J~h1hSqne%?sBxcA7Wv~vh0eX!e2vCxl5l< zR~>uYH|tx!py;}#&t*<0DBD_|aDO~yRcC96l<lfG#Rq|*f2Q&)h$$pmFDbbG-F^j^ z)Thn+UfkHQ#$XZa%(l}V|MCyb6L+(5(mK6jQ7cQ>#(DbONzrb;W;-HwA6a33;-}o= zru>*^<*yC07-grO@A;S$bKqafna?s&XR3M%#eC-^{<Y|td1k@MwTCUrt&ekVW}jX- zIXt8IeC^&pZ}s`4#ZHLWe)=E6_V>MN(wg^2h0lLGaraxrgy6H!H%Z=R3fug0o$0S7 zUiJPN-+US`X>W<H@_C!wr~P5Ok9x)NsVT9`0_Hu;lHzXn{QF~v+U;beqnhh-tJL>+ zIPAYWLtJyqNAZvQxf#zFaGCw{+TYx+FZcE8|7{<xOaJTHd46Syxxj?XZP(Y{IkbEB qg!uDQ|E-vPRwq%S4T}DB|K-#vQj49uZ<Zyf5c72Pb6Mw<&;$VV7zn)p literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/layout/chat.xml b/ultrasonic/src/main/res/layout/chat.xml index 8b8ea719..55304ad2 100644 --- a/ultrasonic/src/main/res/layout/chat.xml +++ b/ultrasonic/src/main/res/layout/chat.xml @@ -6,16 +6,16 @@ <include layout="@layout/tab_progress" /> - <com.handmark.pulltorefresh.library.PullToRefreshListView - a:id="@+id/chat_entries" + <ListView + a:id="@+id/chat_entries_list" a:layout_width="fill_parent" a:layout_height="0dip" - a:layout_weight="1.0" - a:textFilterEnabled="true" /> - - <LinearLayout - a:layout_height="4dip" - a:layout_width="fill_parent" + a:layout_weight="1.0" /> + + + <LinearLayout + a:layout_height="4dip" + a:layout_width="fill_parent" a:layout_marginTop="4dip" a:background="@drawable/drop_shadow" /> @@ -32,20 +32,20 @@ a:layout_weight="1" a:autoLink="all" a:hint="@string/chat.send_a_message" - a:inputType="textEmailAddress|textMultiLine" + a:inputType="textEmailAddress|textMultiLine" a:linksClickable="true" a:paddingBottom="10dip" a:paddingTop="10dip" /> - + <ImageButton a:id="@+id/chat_send" a:layout_width="55dip" a:layout_height="40dip" a:background="@color/transparent" a:src="?attr/chat_send" /> - + </LinearLayout> <include layout="@layout/now_playing" /> -</LinearLayout> \ No newline at end of file +</LinearLayout> diff --git a/ultrasonic/src/main/res/layout/select_album.xml b/ultrasonic/src/main/res/layout/select_album.xml index 1a527ee9..5a037202 100644 --- a/ultrasonic/src/main/res/layout/select_album.xml +++ b/ultrasonic/src/main/res/layout/select_album.xml @@ -19,16 +19,22 @@ a:text="@string/select_album.empty" a:visibility="gone" /> - <com.handmark.pulltorefresh.library.PullToRefreshListView - a:id="@+id/select_album_entries" - a:layout_width="fill_parent" - a:layout_height="0dip" - a:layout_weight="1.0" - a:fastScrollEnabled="true" - a:textFilterEnabled="true" /> + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/select_album_entries_refresh" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1.0"> + + <ListView + android:id="@+id/select_album_entries_list" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <include layout="@layout/album_buttons" /> <include layout="@layout/now_playing" /> -</LinearLayout> \ No newline at end of file +</LinearLayout> diff --git a/ultrasonic/src/main/res/layout/select_artist.xml b/ultrasonic/src/main/res/layout/select_artist.xml index 50fb304f..43a1a8ae 100644 --- a/ultrasonic/src/main/res/layout/select_artist.xml +++ b/ultrasonic/src/main/res/layout/select_artist.xml @@ -6,14 +6,20 @@ <include layout="@layout/tab_progress" /> - <com.handmark.pulltorefresh.library.PullToRefreshListView - a:id="@+id/select_artist_list" - a:layout_width="fill_parent" - a:layout_height="0dip" - a:layout_weight="1.0" - a:fastScrollEnabled="true" - a:textFilterEnabled="true" /> + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/select_artist_refresh" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1.0"> + + <ListView + android:id="@+id/select_artist_list" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <include layout="@layout/now_playing" /> -</LinearLayout> \ No newline at end of file +</LinearLayout> diff --git a/ultrasonic/src/main/res/layout/select_genre.xml b/ultrasonic/src/main/res/layout/select_genre.xml index 57ff820d..ccfb8797 100644 --- a/ultrasonic/src/main/res/layout/select_genre.xml +++ b/ultrasonic/src/main/res/layout/select_genre.xml @@ -14,14 +14,20 @@ a:text="@string/select_genre.empty" a:visibility="gone" /> - <com.handmark.pulltorefresh.library.PullToRefreshListView - a:id="@+id/select_genre_list" - a:layout_width="fill_parent" - a:layout_height="0dip" - a:layout_weight="1.0" - a:fastScrollEnabled="true" - a:textFilterEnabled="true" /> + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/select_genre_refresh" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1.0"> + + <ListView + android:id="@+id/select_genre_list" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <include layout="@layout/now_playing" /> -</LinearLayout> \ No newline at end of file +</LinearLayout> diff --git a/ultrasonic/src/main/res/layout/select_playlist.xml b/ultrasonic/src/main/res/layout/select_playlist.xml index aefcc934..e7176513 100644 --- a/ultrasonic/src/main/res/layout/select_playlist.xml +++ b/ultrasonic/src/main/res/layout/select_playlist.xml @@ -14,14 +14,20 @@ a:text="@string/select_playlist.empty" a:visibility="gone" /> - <com.handmark.pulltorefresh.library.PullToRefreshListView - a:id="@+id/select_playlist_list" - a:layout_width="fill_parent" - a:layout_height="0dip" - a:layout_weight="1.0" - a:fastScrollEnabled="true" - a:textFilterEnabled="true" /> + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/select_playlist_refresh" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1.0"> + + <ListView + android:id="@+id/select_playlist_list" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <include layout="@layout/now_playing" /> -</LinearLayout> \ No newline at end of file +</LinearLayout> diff --git a/ultrasonic/src/main/res/layout/select_share.xml b/ultrasonic/src/main/res/layout/select_share.xml index 7b0641c9..66a07823 100644 --- a/ultrasonic/src/main/res/layout/select_share.xml +++ b/ultrasonic/src/main/res/layout/select_share.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a="http://schemas.android.com/apk/res/android" - a:layout_width="fill_parent" - a:layout_height="fill_parent" - a:orientation="vertical" > + a:layout_width="fill_parent" + a:layout_height="fill_parent" + a:orientation="vertical"> <include layout="@layout/tab_progress" /> @@ -14,14 +14,21 @@ a:text="@string/select_share.empty" a:visibility="gone" /> - <com.handmark.pulltorefresh.library.PullToRefreshListView - a:id="@+id/select_share_list" - a:layout_width="fill_parent" - a:layout_height="0dip" - a:layout_weight="1.0" - a:fastScrollEnabled="true" - a:textFilterEnabled="true" /> + + <androidx.swiperefreshlayout.widget.SwipeRefreshLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/select_share_refresh" + android:layout_width="fill_parent" + android:layout_height="0dip" + android:layout_weight="1.0"> + + <ListView + android:id="@+id/select_share_list" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + </androidx.swiperefreshlayout.widget.SwipeRefreshLayout> <include layout="@layout/now_playing" /> -</LinearLayout> \ No newline at end of file +</LinearLayout> diff --git a/ultrasonic/src/main/res/menu/chat.xml b/ultrasonic/src/main/res/menu/chat.xml new file mode 100644 index 00000000..288df21f --- /dev/null +++ b/ultrasonic/src/main/res/menu/chat.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:android="http://schemas.android.com/apk/res/android" > + <item + android:id="@+id/menu_refresh" + android:title="@string/menu_refresh" + android:icon="?attr/refresh" + app:showAsAction="ifRoom|withText" /> +</menu> \ No newline at end of file diff --git a/ultrasonic/src/main/res/values-de/strings.xml b/ultrasonic/src/main/res/values-de/strings.xml index 246fbae3..75c7ad43 100644 --- a/ultrasonic/src/main/res/values-de/strings.xml +++ b/ultrasonic/src/main/res/values-de/strings.xml @@ -467,5 +467,6 @@ anstatt einfach Elemente zu markieren / zu entfernen. </string> <string name="feature_flags_category_title">Funktionseinstellungem</string> + <string name="menu_refresh">Aktualisierung</string> </resources> diff --git a/ultrasonic/src/main/res/values-es/strings.xml b/ultrasonic/src/main/res/values-es/strings.xml index 469b8ef2..7d6b8ba8 100644 --- a/ultrasonic/src/main/res/values-es/strings.xml +++ b/ultrasonic/src/main/res/values-es/strings.xml @@ -470,5 +470,6 @@ en lugar de simplemente destacar / desestimar elementos. </string> <string name="feature_flags_category_title">Banderas de características</string> + <string name="menu_refresh">Actualizar</string> </resources> diff --git a/ultrasonic/src/main/res/values-fr/strings.xml b/ultrasonic/src/main/res/values-fr/strings.xml index b96db050..6754c260 100644 --- a/ultrasonic/src/main/res/values-fr/strings.xml +++ b/ultrasonic/src/main/res/values-fr/strings.xml @@ -471,5 +471,6 @@ au lieu de simplement mettre en vedette / désactiver les éléments. </string> <string name="feature_flags_category_title">Drapeaux des fonctionnalités</string> + <string name="menu_refresh">Rafraichir</string> </resources> diff --git a/ultrasonic/src/main/res/values-hu/strings.xml b/ultrasonic/src/main/res/values-hu/strings.xml index 2059fdab..e5ab13a9 100644 --- a/ultrasonic/src/main/res/values-hu/strings.xml +++ b/ultrasonic/src/main/res/values-hu/strings.xml @@ -470,5 +470,6 @@ csillaggal jelölés helyett. </string> <string name="feature_flags_category_title">Jellemzők Zászlók</string> + <string name="menu_refresh">Refresh</string> </resources> diff --git a/ultrasonic/src/main/res/values-nl/strings.xml b/ultrasonic/src/main/res/values-nl/strings.xml index bc3f5a1d..70fbbe5f 100644 --- a/ultrasonic/src/main/res/values-nl/strings.xml +++ b/ultrasonic/src/main/res/values-nl/strings.xml @@ -470,5 +470,6 @@ in plaats van items simpelweg in de hoofdrol te zetten / niet te verwijderen. </string> <string name="feature_flags_category_title">Experimentele functies</string> + <string name="menu_refresh">Refresh</string> </resources> diff --git a/ultrasonic/src/main/res/values-pl/strings.xml b/ultrasonic/src/main/res/values-pl/strings.xml index 66f46d2d..06595852 100644 --- a/ultrasonic/src/main/res/values-pl/strings.xml +++ b/ultrasonic/src/main/res/values-pl/strings.xml @@ -483,5 +483,6 @@ Obecnie nie zapisuje obrazów w pamięci urządzenia, tylko wykorzystuje tylko p zamiast po prostu grać gwiazdkami / bez gwiazd. </string> <string name="feature_flags_category_title">Flagi funkcji</string> + <string name="menu_refresh">Refresh</string> </resources> diff --git a/ultrasonic/src/main/res/values-pt-rBR/strings.xml b/ultrasonic/src/main/res/values-pt-rBR/strings.xml index 2ab07c9f..1f331143 100644 --- a/ultrasonic/src/main/res/values-pt-rBR/strings.xml +++ b/ultrasonic/src/main/res/values-pt-rBR/strings.xml @@ -470,5 +470,6 @@ em vez de simplesmente estrelar / não estrelar itens. </string> <string name="feature_flags_category_title">Bandeiras de recursos</string> + <string name="menu_refresh">Refresh</string> </resources> diff --git a/ultrasonic/src/main/res/values-pt/strings.xml b/ultrasonic/src/main/res/values-pt/strings.xml index 8e53355d..68199729 100644 --- a/ultrasonic/src/main/res/values-pt/strings.xml +++ b/ultrasonic/src/main/res/values-pt/strings.xml @@ -470,5 +470,6 @@ em vez de simplesmente estrelar / não estrelar itens. </string> <string name="feature_flags_category_title">Bandeiras de recursos</string> + <string name="menu_refresh">Refresh</string> </resources> diff --git a/ultrasonic/src/main/res/values/strings.xml b/ultrasonic/src/main/res/values/strings.xml index 71c884b6..b5bfb427 100644 --- a/ultrasonic/src/main/res/values/strings.xml +++ b/ultrasonic/src/main/res/values/strings.xml @@ -474,5 +474,6 @@ instead of simply starring/unstarring items. </string> <string name="feature_flags_category_title">Feature Flags</string> + <string name="menu_refresh">Refresh</string> </resources> diff --git a/ultrasonic/src/main/res/values/styles.xml b/ultrasonic/src/main/res/values/styles.xml index aeae6325..ed9fae4c 100644 --- a/ultrasonic/src/main/res/values/styles.xml +++ b/ultrasonic/src/main/res/values/styles.xml @@ -81,6 +81,7 @@ <attr name="media_shuffle" format="reference"/> <attr name="media_play" format="reference"/> <attr name="podcasts" format="reference"/> + <attr name="refresh" format="reference"/> <attr name="media_play_next" format="reference"/> <attr name="media_play_small" format="reference"/> <attr name="media_stop" format="reference"/> diff --git a/ultrasonic/src/main/res/values/themes.xml b/ultrasonic/src/main/res/values/themes.xml index e78d0318..0280d683 100644 --- a/ultrasonic/src/main/res/values/themes.xml +++ b/ultrasonic/src/main/res/values/themes.xml @@ -35,6 +35,7 @@ <item name="media_shuffle">@drawable/media_shuffle_normal_dark</item> <item name="media_play">@drawable/media_start_normal_dark</item> <item name="podcasts">@drawable/ic_menu_podcasts_dark</item> + <item name="refresh">@drawable/ic_menu_refresh_dark</item> <item name="media_play_next">@drawable/media_play_next</item> <item name="media_play_small">@drawable/ic_stat_play_dark</item> <item name="media_stop">@drawable/media_stop_normal_dark</item> @@ -84,6 +85,7 @@ <item name="media_shuffle">@drawable/media_shuffle_normal_light</item> <item name="media_play">@drawable/media_start_normal_light</item> <item name="podcasts">@drawable/ic_menu_podcasts_light</item> + <item name="refresh">@drawable/ic_menu_refresh_light</item> <item name="media_play_next">@drawable/media_play_next</item> <item name="media_play_small">@drawable/ic_stat_play_light</item> <item name="media_stop">@drawable/media_stop_normal_light</item>