Resign all with gpg key

This commit is contained in:
Max Pop 2020-09-21 12:17:55 +02:00
parent 4d8e7f0631
commit 251e575421
No known key found for this signature in database
GPG Key ID: F2860A8BDF86D1F8
101 changed files with 185 additions and 5696 deletions

View File

@ -1,8 +0,0 @@
apply from: bootstrap.androidModule
android {
lintOptions {
baselineFile file("lint-baseline.xml")
abortOnError true
}
}

View File

@ -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 &quot;`he`&quot; should be called &quot;`iw`&quot; 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=" &lt;uses-sdk android:minSdkVersion=&quot;4&quot; android:targetSdkVersion=&quot;16&quot; />"
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=" &lt;uses-sdk android:minSdkVersion=&quot;4&quot; android:targetSdkVersion=&quot;16&quot; />"
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=" &lt;uses-sdk android:minSdkVersion=&quot;4&quot; android:targetSdkVersion=&quot;16&quot; />"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/AndroidManifest.xml"
line="7"
column="41"/>
</issue>
<issue
id="Deprecated"
message="`android:singleLine` is deprecated: Use `maxLines=&quot;1&quot;` instead"
errorLine1=" android:singleLine=&quot;true&quot;"
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=&quot;1&quot;` instead"
errorLine1=" android:singleLine=&quot;true&quot;"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/res/layout/pull_to_refresh_header_vertical.xml"
line="53"
column="17"/>
</issue>
<issue
id="MissingTranslation"
message="&quot;`pull_to_refresh_from_bottom_pull_label`&quot; is not translated in &quot;es&quot; (Spanish), &quot;fr&quot; (French), &quot;pt&quot; (Portuguese), &quot;pt-BR&quot; (Portuguese: Brazil)"
errorLine1=" &lt;string name=&quot;pull_to_refresh_from_bottom_pull_label&quot;>@string/pull_to_refresh_pull_label&lt;/string>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/res/values/pull_refresh_strings.xml"
line="9"
column="13"/>
</issue>
<issue
id="MissingTranslation"
message="&quot;`pull_to_refresh_from_bottom_release_label`&quot; is not translated in &quot;es&quot; (Spanish), &quot;fr&quot; (French), &quot;pt&quot; (Portuguese), &quot;pt-BR&quot; (Portuguese: Brazil)"
errorLine1=" &lt;string name=&quot;pull_to_refresh_from_bottom_release_label&quot;>@string/pull_to_refresh_release_label&lt;/string>"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/res/values/pull_refresh_strings.xml"
line="10"
column="13"/>
</issue>
<issue
id="MissingTranslation"
message="&quot;`pull_to_refresh_from_bottom_refreshing_label`&quot; is not translated in &quot;es&quot; (Spanish), &quot;fr&quot; (French), &quot;pt&quot; (Portuguese), &quot;pt-BR&quot; (Portuguese: Brazil)"
errorLine1=" &lt;string name=&quot;pull_to_refresh_from_bottom_refreshing_label&quot;>@string/pull_to_refresh_refreshing_label&lt;/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 &lt; 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 &amp;&amp; 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=" &lt;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=" &lt;ImageView"
errorLine2=" ^">
<location
file="src/main/res/layout/pull_to_refresh_header_vertical.xml"
line="18"
column="13"/>
</issue>
<issue
id="RtlHardcoded"
message="Use &quot;`Gravity.START`&quot; instead of &quot;`Gravity.LEFT`&quot; 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 &quot;`Gravity.END`&quot; instead of &quot;`Gravity.RIGHT`&quot; 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 &quot;`Gravity.END`&quot; instead of &quot;`Gravity.RIGHT`&quot; 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 &quot;`Gravity.END`&quot; instead of &quot;`Gravity.RIGHT`&quot; 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 &quot;`start`&quot; instead of &quot;`left`&quot; to ensure correct behavior in right-to-left locales"
errorLine1=" android:layout_gravity=&quot;left|center_vertical&quot; >"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
<location
file="src/main/res/layout/pull_to_refresh_header_vertical.xml"
line="16"
column="37"/>
</issue>
</issues>

View File

@ -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>

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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()));
}
}
}

View File

@ -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);
}
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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" />

View File

@ -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" />

View File

@ -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" />

View File

@ -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" />

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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'

View File

@ -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')

View File

@ -33,7 +33,7 @@
<li>&Eacute;coute et t&eacute;l&eacute;chargement illimit&eacute;s vers autant de iPhones et d'appareils Android que souhait&eacute;.</li>
<li>Lecture de vid&eacute;os.</li>
<li>Une adresse web personnalis&eacute;e pour votre serveur Subsonic (<em>votrenom</em>.subsonic.org).</li>
<li>Aucunes publicit&eacutees; dans l'interface web de Subsonic.</li>
<li>Aucunes publicit&eacute;s dans l'interface web de Subsonic.</li>
<li>Acc&egrave;s gratuit aux nouvelles fonctionnalit&eacute;s avanc&eacute;es.</li>
</ul>

View File

@ -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);
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}

View File

@ -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;
}
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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);
}

View File

@ -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;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1017 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -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>
</LinearLayout>

View File

@ -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>
</LinearLayout>

View File

@ -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>
</LinearLayout>

View File

@ -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>
</LinearLayout>

View File

@ -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>
</LinearLayout>

View File

@ -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>
</LinearLayout>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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"/>

Some files were not shown because too many files have changed in this diff Show More