refreshView) {
34 | refreshView.getRefreshableView().reload();
35 | }
36 |
37 | };
38 |
39 | private final WebChromeClient defaultWebChromeClient = new WebChromeClient() {
40 |
41 | @Override
42 | public void onProgressChanged(WebView view, int newProgress) {
43 | if (newProgress == 100) {
44 | onRefreshComplete();
45 | }
46 | }
47 |
48 | };
49 |
50 | public PullToRefreshWebView(Context context) {
51 | super(context);
52 |
53 | /**
54 | * Added so that by default, Pull-to-Refresh refreshes the page
55 | */
56 | setOnRefreshListener(defaultOnRefreshListener);
57 | mRefreshableView.setWebChromeClient(defaultWebChromeClient);
58 | }
59 |
60 | public PullToRefreshWebView(Context context, AttributeSet attrs) {
61 | super(context, attrs);
62 |
63 | /**
64 | * Added so that by default, Pull-to-Refresh refreshes the page
65 | */
66 | setOnRefreshListener(defaultOnRefreshListener);
67 | mRefreshableView.setWebChromeClient(defaultWebChromeClient);
68 | }
69 |
70 | public PullToRefreshWebView(Context context, Mode mode) {
71 | super(context, mode);
72 |
73 | /**
74 | * Added so that by default, Pull-to-Refresh refreshes the page
75 | */
76 | setOnRefreshListener(defaultOnRefreshListener);
77 | mRefreshableView.setWebChromeClient(defaultWebChromeClient);
78 | }
79 |
80 | public PullToRefreshWebView(Context context, Mode mode, AnimationStyle style) {
81 | super(context, mode, style);
82 |
83 | /**
84 | * Added so that by default, Pull-to-Refresh refreshes the page
85 | */
86 | setOnRefreshListener(defaultOnRefreshListener);
87 | mRefreshableView.setWebChromeClient(defaultWebChromeClient);
88 | }
89 |
90 | @Override
91 | public final Orientation getPullToRefreshScrollDirection() {
92 | return Orientation.VERTICAL;
93 | }
94 |
95 | @Override
96 | protected WebView createRefreshableView(Context context, AttributeSet attrs) {
97 | WebView webView;
98 | if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
99 | webView = new InternalWebViewSDK9(context, attrs);
100 | } else {
101 | webView = new WebView(context, attrs);
102 | }
103 |
104 | webView.setId(R.id.webview);
105 | return webView;
106 | }
107 |
108 | @Override
109 | protected boolean isReadyForPullStart() {
110 | return mRefreshableView.getScrollY() == 0;
111 | }
112 |
113 | @Override
114 | protected boolean isReadyForPullEnd() {
115 | float exactContentHeight = FloatMath.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale());
116 | return mRefreshableView.getScrollY() >= (exactContentHeight - mRefreshableView.getHeight());
117 | }
118 |
119 | @Override
120 | protected void onPtrRestoreInstanceState(Bundle savedInstanceState) {
121 | super.onPtrRestoreInstanceState(savedInstanceState);
122 | mRefreshableView.restoreState(savedInstanceState);
123 | }
124 |
125 | @Override
126 | protected void onPtrSaveInstanceState(Bundle saveState) {
127 | super.onPtrSaveInstanceState(saveState);
128 | mRefreshableView.saveState(saveState);
129 | }
130 |
131 | @TargetApi(9)
132 | final class InternalWebViewSDK9 extends WebView {
133 |
134 | // WebView doesn't always scroll back to it's edge so we add some
135 | // fuzziness
136 | static final int OVERSCROLL_FUZZY_THRESHOLD = 2;
137 |
138 | // WebView seems quite reluctant to overscroll so we use the scale
139 | // factor to scale it's value
140 | static final float OVERSCROLL_SCALE_FACTOR = 1.5f;
141 |
142 | public InternalWebViewSDK9(Context context, AttributeSet attrs) {
143 | super(context, attrs);
144 | }
145 |
146 | @Override
147 | protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
148 | int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
149 |
150 | final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
151 | scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
152 |
153 | // Does all of the hard work...
154 | OverscrollHelper.overScrollBy(PullToRefreshWebView.this, deltaX, scrollX, deltaY, scrollY,
155 | getScrollRange(), OVERSCROLL_FUZZY_THRESHOLD, OVERSCROLL_SCALE_FACTOR, isTouchEvent);
156 |
157 | return returnValue;
158 | }
159 |
160 | private int getScrollRange() {
161 | return (int) Math.max(0, FloatMath.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale())
162 | - (getHeight() - getPaddingBottom() - getPaddingTop()));
163 | }
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/extras/PullToRefreshWebView2.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.extras;
17 |
18 | import java.util.concurrent.atomic.AtomicBoolean;
19 |
20 | import android.content.Context;
21 | import android.util.AttributeSet;
22 | import android.webkit.WebView;
23 |
24 | import com.handmark.pulltorefresh.library.PullToRefreshWebView;
25 |
26 | /**
27 | * An advanced version of {@link PullToRefreshWebView} which delegates the
28 | * triggering of the PullToRefresh gesture to the Javascript running within the
29 | * WebView. This means that you should only use this class if:
30 | *
31 | *
32 | * - {@link PullToRefreshWebView} doesn't work correctly because you're using
33 | *
overflow:scroll
or something else which means
34 | * {@link WebView#getScrollY()} doesn't return correct values.
35 | * - You control the web content being displayed, as you need to write some
36 | * Javascript callbacks.
37 | *
38 | *
39 | *
40 | * The way this call works is that when a PullToRefresh gesture is in action,
41 | * the following Javascript methods will be called:
42 | * isReadyForPullDown()
and isReadyForPullUp()
, it is
43 | * your job to calculate whether the view is in a state where a PullToRefresh
44 | * can happen, and return the result via the callback mechanism. An example can
45 | * be seen below:
46 | *
47 | *
48 | *
49 | * function isReadyForPullDown() {
50 | * var result = ... // Probably using the .scrollTop DOM attribute
51 | * ptr.isReadyForPullDownResponse(result);
52 | * }
53 | *
54 | * function isReadyForPullUp() {
55 | * var result = ... // Probably using the .scrollBottom DOM attribute
56 | * ptr.isReadyForPullUpResponse(result);
57 | * }
58 | *
59 | *
60 | * @author Chris Banes
61 | */
62 | public class PullToRefreshWebView2 extends PullToRefreshWebView {
63 |
64 | static final String JS_INTERFACE_PKG = "ptr";
65 | static final String DEF_JS_READY_PULL_DOWN_CALL = "javascript:isReadyForPullDown();";
66 | static final String DEF_JS_READY_PULL_UP_CALL = "javascript:isReadyForPullUp();";
67 |
68 | public PullToRefreshWebView2(Context context) {
69 | super(context);
70 | }
71 |
72 | public PullToRefreshWebView2(Context context, AttributeSet attrs) {
73 | super(context, attrs);
74 | }
75 |
76 | public PullToRefreshWebView2(Context context, Mode mode) {
77 | super(context, mode);
78 | }
79 |
80 | private JsValueCallback mJsCallback;
81 | private final AtomicBoolean mIsReadyForPullDown = new AtomicBoolean(false);
82 | private final AtomicBoolean mIsReadyForPullUp = new AtomicBoolean(false);
83 |
84 | @Override
85 | protected WebView createRefreshableView(Context context, AttributeSet attrs) {
86 | WebView webView = super.createRefreshableView(context, attrs);
87 |
88 | // Need to add JS Interface so we can get the response back
89 | mJsCallback = new JsValueCallback();
90 | webView.addJavascriptInterface(mJsCallback, JS_INTERFACE_PKG);
91 |
92 | return webView;
93 | }
94 |
95 | @Override
96 | protected boolean isReadyForPullStart() {
97 | // Call Javascript...
98 | getRefreshableView().loadUrl(DEF_JS_READY_PULL_DOWN_CALL);
99 |
100 | // Response will be given to JsValueCallback, which will update
101 | // mIsReadyForPullDown
102 |
103 | return mIsReadyForPullDown.get();
104 | }
105 |
106 | @Override
107 | protected boolean isReadyForPullEnd() {
108 | // Call Javascript...
109 | getRefreshableView().loadUrl(DEF_JS_READY_PULL_UP_CALL);
110 |
111 | // Response will be given to JsValueCallback, which will update
112 | // mIsReadyForPullUp
113 |
114 | return mIsReadyForPullUp.get();
115 | }
116 |
117 | /**
118 | * Used for response from Javascript
119 | *
120 | * @author Chris Banes
121 | */
122 | final class JsValueCallback {
123 |
124 | public void isReadyForPullUpResponse(boolean response) {
125 | mIsReadyForPullUp.set(response);
126 | }
127 |
128 | public void isReadyForPullDownResponse(boolean response) {
129 | mIsReadyForPullDown.set(response);
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/extras/SoundPullEventListener.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.extras;
17 |
18 | import java.util.HashMap;
19 |
20 | import android.content.Context;
21 | import android.media.MediaPlayer;
22 | import android.view.View;
23 |
24 | import com.handmark.pulltorefresh.library.PullToRefreshBase;
25 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
26 | import com.handmark.pulltorefresh.library.PullToRefreshBase.State;
27 |
28 | public class SoundPullEventListener implements PullToRefreshBase.OnPullEventListener {
29 |
30 | private final Context mContext;
31 | private final HashMap mSoundMap;
32 |
33 | private MediaPlayer mCurrentMediaPlayer;
34 |
35 | /**
36 | * Constructor
37 | *
38 | * @param context - Context
39 | */
40 | public SoundPullEventListener(Context context) {
41 | mContext = context;
42 | mSoundMap = new HashMap();
43 | }
44 |
45 | @Override
46 | public final void onPullEvent(PullToRefreshBase refreshView, State event, Mode direction) {
47 | Integer soundResIdObj = mSoundMap.get(event);
48 | if (null != soundResIdObj) {
49 | playSound(soundResIdObj.intValue());
50 | }
51 | }
52 |
53 | /**
54 | * Set the Sounds to be played when a Pull Event happens. You specify which
55 | * sound plays for which events by calling this method multiple times for
56 | * each event.
57 | *
58 | * If you've already set a sound for a certain event, and add another sound
59 | * for that event, only the new sound will be played.
60 | *
61 | * @param event - The event for which the sound will be played.
62 | * @param resId - Resource Id of the sound file to be played (e.g.
63 | * R.raw.pull_sound)
64 | */
65 | public void addSoundEvent(State event, int resId) {
66 | mSoundMap.put(event, resId);
67 | }
68 |
69 | /**
70 | * Clears all of the previously set sounds and events.
71 | */
72 | public void clearSounds() {
73 | mSoundMap.clear();
74 | }
75 |
76 | /**
77 | * Gets the current (or last) MediaPlayer instance.
78 | */
79 | public MediaPlayer getCurrentMediaPlayer() {
80 | return mCurrentMediaPlayer;
81 | }
82 |
83 | private void playSound(int resId) {
84 | // Stop current player, if there's one playing
85 | if (null != mCurrentMediaPlayer) {
86 | mCurrentMediaPlayer.stop();
87 | mCurrentMediaPlayer.release();
88 | }
89 |
90 | mCurrentMediaPlayer = MediaPlayer.create(mContext, resId);
91 | if (null != mCurrentMediaPlayer) {
92 | mCurrentMediaPlayer.start();
93 | }
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/internal/EmptyViewMethodAccessor.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.internal;
17 |
18 | import android.view.View;
19 |
20 | /**
21 | * Interface that allows PullToRefreshBase to hijack the call to
22 | * AdapterView.setEmptyView()
23 | *
24 | * @author chris
25 | */
26 | public interface EmptyViewMethodAccessor {
27 |
28 | /**
29 | * Calls upto AdapterView.setEmptyView()
30 | *
31 | * @param emptyView - to set as Empty View
32 | */
33 | public void setEmptyViewInternal(View emptyView);
34 |
35 | /**
36 | * Should call PullToRefreshBase.setEmptyView() which will then
37 | * automatically call through to setEmptyViewInternal()
38 | *
39 | * @param emptyView - to set as Empty View
40 | */
41 | public void setEmptyView(View emptyView);
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/internal/FlipLoadingLayout.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.internal;
17 |
18 | import android.annotation.SuppressLint;
19 | import android.content.Context;
20 | import android.content.res.TypedArray;
21 | import android.graphics.Matrix;
22 | import android.graphics.drawable.Drawable;
23 | import android.view.View;
24 | import android.view.ViewGroup;
25 | import android.view.animation.Animation;
26 | import android.view.animation.RotateAnimation;
27 | import android.widget.ImageView.ScaleType;
28 |
29 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
30 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
31 | import com.handmark.pulltorefresh.library.R;
32 |
33 | @SuppressLint("ViewConstructor")
34 | public class FlipLoadingLayout extends LoadingLayout {
35 |
36 | static final int FLIP_ANIMATION_DURATION = 150;
37 |
38 | private final Animation mRotateAnimation, mResetRotateAnimation;
39 |
40 | public FlipLoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) {
41 | super(context, mode, scrollDirection, attrs);
42 |
43 | final int rotateAngle = mode == Mode.PULL_FROM_START ? -180 : 180;
44 |
45 | mRotateAnimation = new RotateAnimation(0, rotateAngle, Animation.RELATIVE_TO_SELF, 0.5f,
46 | Animation.RELATIVE_TO_SELF, 0.5f);
47 | mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
48 | mRotateAnimation.setDuration(FLIP_ANIMATION_DURATION);
49 | mRotateAnimation.setFillAfter(true);
50 |
51 | mResetRotateAnimation = new RotateAnimation(rotateAngle, 0, Animation.RELATIVE_TO_SELF, 0.5f,
52 | Animation.RELATIVE_TO_SELF, 0.5f);
53 | mResetRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
54 | mResetRotateAnimation.setDuration(FLIP_ANIMATION_DURATION);
55 | mResetRotateAnimation.setFillAfter(true);
56 | }
57 |
58 | @Override
59 | protected void onLoadingDrawableSet(Drawable imageDrawable) {
60 | if (null != imageDrawable) {
61 | final int dHeight = imageDrawable.getIntrinsicHeight();
62 | final int dWidth = imageDrawable.getIntrinsicWidth();
63 |
64 | /**
65 | * We need to set the width/height of the ImageView so that it is
66 | * square with each side the size of the largest drawable dimension.
67 | * This is so that it doesn't clip when rotated.
68 | */
69 | ViewGroup.LayoutParams lp = mHeaderImage.getLayoutParams();
70 | lp.width = lp.height = Math.max(dHeight, dWidth);
71 | mHeaderImage.requestLayout();
72 |
73 | /**
74 | * We now rotate the Drawable so that is at the correct rotation,
75 | * and is centered.
76 | */
77 | mHeaderImage.setScaleType(ScaleType.MATRIX);
78 | Matrix matrix = new Matrix();
79 | matrix.postTranslate((lp.width - dWidth) / 2f, (lp.height - dHeight) / 2f);
80 | matrix.postRotate(getDrawableRotationAngle(), lp.width / 2f, lp.height / 2f);
81 | mHeaderImage.setImageMatrix(matrix);
82 | }
83 | }
84 |
85 | @Override
86 | protected void onPullImpl(float scaleOfLayout) {
87 | // NO-OP
88 | }
89 |
90 | @Override
91 | protected void pullToRefreshImpl() {
92 | // Only start reset Animation, we've previously show the rotate anim
93 | if (mRotateAnimation == mHeaderImage.getAnimation()) {
94 | mHeaderImage.startAnimation(mResetRotateAnimation);
95 | }
96 | }
97 |
98 | @Override
99 | protected void refreshingImpl() {
100 | mHeaderImage.clearAnimation();
101 | mHeaderImage.setVisibility(View.INVISIBLE);
102 | mHeaderProgress.setVisibility(View.VISIBLE);
103 | }
104 |
105 | @Override
106 | protected void releaseToRefreshImpl() {
107 | mHeaderImage.startAnimation(mRotateAnimation);
108 | }
109 |
110 | @Override
111 | protected void resetImpl() {
112 | mHeaderImage.clearAnimation();
113 | mHeaderProgress.setVisibility(View.GONE);
114 | mHeaderImage.setVisibility(View.VISIBLE);
115 | }
116 |
117 | @Override
118 | protected int getDefaultDrawableResId() {
119 | return R.drawable.default_ptr_flip;
120 | }
121 |
122 | private float getDrawableRotationAngle() {
123 | float angle = 0f;
124 | switch (mMode) {
125 | case PULL_FROM_END:
126 | if (mScrollDirection == Orientation.HORIZONTAL) {
127 | angle = 90f;
128 | } else {
129 | angle = 180f;
130 | }
131 | break;
132 |
133 | case PULL_FROM_START:
134 | if (mScrollDirection == Orientation.HORIZONTAL) {
135 | angle = 270f;
136 | }
137 | break;
138 |
139 | default:
140 | break;
141 | }
142 |
143 | return angle;
144 | }
145 |
146 | }
147 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/internal/IndicatorLayout.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.internal;
17 |
18 | import android.annotation.SuppressLint;
19 | import android.content.Context;
20 | import android.graphics.Matrix;
21 | import android.graphics.drawable.Drawable;
22 | import android.view.View;
23 | import android.view.animation.Animation;
24 | import android.view.animation.Animation.AnimationListener;
25 | import android.view.animation.AnimationUtils;
26 | import android.view.animation.Interpolator;
27 | import android.view.animation.LinearInterpolator;
28 | import android.view.animation.RotateAnimation;
29 | import android.widget.FrameLayout;
30 | import android.widget.ImageView;
31 | import android.widget.ImageView.ScaleType;
32 |
33 | import com.handmark.pulltorefresh.library.PullToRefreshBase;
34 | import com.handmark.pulltorefresh.library.R;
35 |
36 | @SuppressLint("ViewConstructor")
37 | public class IndicatorLayout extends FrameLayout implements AnimationListener {
38 |
39 | static final int DEFAULT_ROTATION_ANIMATION_DURATION = 150;
40 |
41 | private Animation mInAnim, mOutAnim;
42 | private ImageView mArrowImageView;
43 |
44 | private final Animation mRotateAnimation, mResetRotateAnimation;
45 |
46 | public IndicatorLayout(Context context, PullToRefreshBase.Mode mode) {
47 | super(context);
48 | mArrowImageView = new ImageView(context);
49 |
50 | Drawable arrowD = getResources().getDrawable(R.drawable.indicator_arrow);
51 | mArrowImageView.setImageDrawable(arrowD);
52 |
53 | final int padding = getResources().getDimensionPixelSize(R.dimen.indicator_internal_padding);
54 | mArrowImageView.setPadding(padding, padding, padding, padding);
55 | addView(mArrowImageView);
56 |
57 | int inAnimResId, outAnimResId;
58 | switch (mode) {
59 | case PULL_FROM_END:
60 | inAnimResId = R.anim.slide_in_from_bottom;
61 | outAnimResId = R.anim.slide_out_to_bottom;
62 | setBackgroundResource(R.drawable.indicator_bg_bottom);
63 |
64 | // Rotate Arrow so it's pointing the correct way
65 | mArrowImageView.setScaleType(ScaleType.MATRIX);
66 | Matrix matrix = new Matrix();
67 | matrix.setRotate(180f, arrowD.getIntrinsicWidth() / 2f, arrowD.getIntrinsicHeight() / 2f);
68 | mArrowImageView.setImageMatrix(matrix);
69 | break;
70 | default:
71 | case PULL_FROM_START:
72 | inAnimResId = R.anim.slide_in_from_top;
73 | outAnimResId = R.anim.slide_out_to_top;
74 | setBackgroundResource(R.drawable.indicator_bg_top);
75 | break;
76 | }
77 |
78 | mInAnim = AnimationUtils.loadAnimation(context, inAnimResId);
79 | mInAnim.setAnimationListener(this);
80 |
81 | mOutAnim = AnimationUtils.loadAnimation(context, outAnimResId);
82 | mOutAnim.setAnimationListener(this);
83 |
84 | final Interpolator interpolator = new LinearInterpolator();
85 | mRotateAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
86 | 0.5f);
87 | mRotateAnimation.setInterpolator(interpolator);
88 | mRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION);
89 | mRotateAnimation.setFillAfter(true);
90 |
91 | mResetRotateAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f,
92 | Animation.RELATIVE_TO_SELF, 0.5f);
93 | mResetRotateAnimation.setInterpolator(interpolator);
94 | mResetRotateAnimation.setDuration(DEFAULT_ROTATION_ANIMATION_DURATION);
95 | mResetRotateAnimation.setFillAfter(true);
96 |
97 | }
98 |
99 | public final boolean isVisible() {
100 | Animation currentAnim = getAnimation();
101 | if (null != currentAnim) {
102 | return mInAnim == currentAnim;
103 | }
104 |
105 | return getVisibility() == View.VISIBLE;
106 | }
107 |
108 | public void hide() {
109 | startAnimation(mOutAnim);
110 | }
111 |
112 | public void show() {
113 | mArrowImageView.clearAnimation();
114 | startAnimation(mInAnim);
115 | }
116 |
117 | @Override
118 | public void onAnimationEnd(Animation animation) {
119 | if (animation == mOutAnim) {
120 | mArrowImageView.clearAnimation();
121 | setVisibility(View.GONE);
122 | } else if (animation == mInAnim) {
123 | setVisibility(View.VISIBLE);
124 | }
125 |
126 | clearAnimation();
127 | }
128 |
129 | @Override
130 | public void onAnimationRepeat(Animation animation) {
131 | // NO-OP
132 | }
133 |
134 | @Override
135 | public void onAnimationStart(Animation animation) {
136 | setVisibility(View.VISIBLE);
137 | }
138 |
139 | public void releaseToRefresh() {
140 | mArrowImageView.startAnimation(mRotateAnimation);
141 | }
142 |
143 | public void pullToRefresh() {
144 | mArrowImageView.startAnimation(mResetRotateAnimation);
145 | }
146 |
147 | }
148 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/internal/LoadingLayout.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.internal;
17 |
18 | import android.annotation.SuppressLint;
19 | import android.content.Context;
20 | import android.content.res.ColorStateList;
21 | import android.content.res.TypedArray;
22 | import android.graphics.Color;
23 | import android.graphics.Typeface;
24 | import android.graphics.drawable.AnimationDrawable;
25 | import android.graphics.drawable.Drawable;
26 | import android.text.TextUtils;
27 | import android.util.TypedValue;
28 | import android.view.Gravity;
29 | import android.view.LayoutInflater;
30 | import android.view.View;
31 | import android.view.ViewGroup;
32 | import android.view.animation.Interpolator;
33 | import android.view.animation.LinearInterpolator;
34 | import android.widget.FrameLayout;
35 | import android.widget.ImageView;
36 | import android.widget.ProgressBar;
37 | import android.widget.TextView;
38 |
39 | import com.handmark.pulltorefresh.library.ILoadingLayout;
40 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
41 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
42 | import com.handmark.pulltorefresh.library.R;
43 |
44 | @SuppressLint("ViewConstructor")
45 | public abstract class LoadingLayout extends FrameLayout implements ILoadingLayout {
46 |
47 | static final String LOG_TAG = "PullToRefresh-LoadingLayout";
48 |
49 | static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator();
50 |
51 | private FrameLayout mInnerLayout;
52 |
53 | protected final ImageView mHeaderImage;
54 | protected final ProgressBar mHeaderProgress;
55 |
56 | private boolean mUseIntrinsicAnimation;
57 |
58 | private final TextView mHeaderText;
59 | private final TextView mSubHeaderText;
60 |
61 | protected final Mode mMode;
62 | protected final Orientation mScrollDirection;
63 |
64 | private CharSequence mHeader ;
65 | private CharSequence mPullLabel;
66 | private CharSequence mRefreshingLabel;
67 | private CharSequence mReleaseLabel;
68 | private int rgb = Color.rgb(180,180,180) ;
69 | private int rgbHeader = Color.rgb(119,119,119) ;
70 | private int subHeaderTextSize = 14 ;
71 | private int headerTextSize = 19 ;
72 |
73 |
74 | public LoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) {
75 | super(context);
76 | mMode = mode;
77 | mScrollDirection = scrollDirection;
78 |
79 | switch (scrollDirection) {
80 | case HORIZONTAL:
81 | LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_horizontal, this);
82 | break;
83 | case VERTICAL:
84 | default:
85 | LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_vertical, this);
86 | break;
87 | }
88 |
89 | mInnerLayout = (FrameLayout) findViewById(R.id.fl_inner);
90 | mHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_text);
91 | // mHeaderText.setText(mHeader);
92 | // mHeaderText.setTextSize(headerTextSize);
93 | mHeaderProgress = (ProgressBar) mInnerLayout.findViewById(R.id.pull_to_refresh_progress);
94 | mSubHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_sub_text);
95 | // mSubHeaderText.setTextColor(rgb);
96 | // mSubHeaderText.setTextSize(subHeaderTextSize);
97 | setTextAttribute() ;
98 | mHeaderImage = (ImageView) mInnerLayout.findViewById(R.id.pull_to_refresh_image);
99 |
100 | FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInnerLayout.getLayoutParams();
101 |
102 | switch (mode) {
103 | case PULL_FROM_END:
104 | lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.TOP : Gravity.LEFT;
105 |
106 | // Load in labels
107 | mHeader = context.getString(R.string.pull_to_refresh_header) ;
108 | mPullLabel = context.getString(R.string.pull_to_refresh_pull_label);
109 | mRefreshingLabel = context.getString(R.string.pull_to_refresh_from_bottom_refreshing_label);
110 | mReleaseLabel = context.getString(R.string.pull_to_refresh_from_bottom_release_label);
111 | break;
112 |
113 | case PULL_FROM_START:
114 | default:
115 | lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.BOTTOM : Gravity.RIGHT;
116 |
117 | // Load in labels
118 | mHeader = context.getString(R.string.pull_to_refresh_header) ; //健康送到家
119 | mPullLabel = context.getString(R.string.pull_to_refresh_pull_label); //下拉刷新
120 | mReleaseLabel = context.getString(R.string.pull_to_refresh_release_label);//松开以刷新
121 | mRefreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label);//正在加载
122 | break;
123 | }
124 |
125 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderBackground)) {
126 | Drawable background = attrs.getDrawable(R.styleable.PullToRefresh_ptrHeaderBackground);
127 | if (null != background) {
128 | ViewCompat.setBackground(this, background);
129 | }
130 | }
131 |
132 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance)) {
133 | TypedValue styleID = new TypedValue();
134 | attrs.getValue(R.styleable.PullToRefresh_ptrHeaderTextAppearance, styleID);
135 | setTextAppearance(styleID.data);
136 | }
137 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance)) {
138 | TypedValue styleID = new TypedValue();
139 | attrs.getValue(R.styleable.PullToRefresh_ptrSubHeaderTextAppearance, styleID);
140 | setSubTextAppearance(styleID.data);
141 | }
142 |
143 | // Text Color attrs need to be set after TextAppearance attrs
144 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextColor)) {
145 | ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderTextColor);
146 | if (null != colors) {
147 | setTextColor(colors);
148 | }
149 | }
150 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderSubTextColor)) {
151 | ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderSubTextColor);
152 | if (null != colors) {
153 | setSubTextColor(colors);
154 | }
155 | }
156 |
157 | // Try and get defined drawable from Attrs
158 | Drawable imageDrawable = null;
159 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawable)) {
160 | imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawable);
161 | }
162 |
163 | // Check Specific Drawable from Attrs, these overrite the generic
164 | // drawable attr above
165 | switch (mode) {
166 | case PULL_FROM_START:
167 | default:
168 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableStart)) {
169 | imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableStart);
170 | } else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableTop)) {
171 | Utils.warnDeprecation("ptrDrawableTop", "ptrDrawableStart");
172 | imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableTop);
173 | }
174 | break;
175 |
176 | case PULL_FROM_END:
177 | if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableEnd)) {
178 | imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableEnd);
179 | } else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableBottom)) {
180 | Utils.warnDeprecation("ptrDrawableBottom", "ptrDrawableEnd");
181 | imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableBottom);
182 | }
183 | break;
184 | }
185 |
186 | // If we don't have a user defined drawable, load the default
187 | if (null == imageDrawable) {
188 | imageDrawable = context.getResources().getDrawable(getDefaultDrawableResId());
189 | }
190 |
191 | // Set Drawable, and save width/height
192 | setLoadingDrawable(imageDrawable);
193 |
194 | reset();
195 | }
196 |
197 | public final void setHeight(int height) {
198 | ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getLayoutParams();
199 | lp.height = height;
200 | requestLayout();
201 | }
202 |
203 | public final void setWidth(int width) {
204 | ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getLayoutParams();
205 | lp.width = width;
206 | requestLayout();
207 | }
208 |
209 | public final int getContentSize() {
210 | switch (mScrollDirection) {
211 | case HORIZONTAL:
212 | return mInnerLayout.getWidth();
213 | case VERTICAL:
214 | default:
215 | return mInnerLayout.getHeight();
216 | }
217 | }
218 |
219 | public final void hideAllViews() {
220 | if (View.VISIBLE == mHeaderText.getVisibility()) {
221 | mHeaderText.setVisibility(View.INVISIBLE);
222 | }
223 | if (View.VISIBLE == mHeaderProgress.getVisibility()) {
224 | mHeaderProgress.setVisibility(View.INVISIBLE);
225 | }
226 | if (View.VISIBLE == mHeaderImage.getVisibility()) {
227 | mHeaderImage.setVisibility(View.INVISIBLE);
228 | }
229 | if (View.VISIBLE == mSubHeaderText.getVisibility()) {
230 | mSubHeaderText.setVisibility(View.INVISIBLE);
231 | }
232 | }
233 |
234 | public final void onPull(float scaleOfLayout) {
235 | if (!mUseIntrinsicAnimation) {
236 | onPullImpl(scaleOfLayout);
237 | }
238 | }
239 |
240 | public final void pullToRefresh() {
241 | // if (null != mHeaderText) {
242 | // setTextAttribute() ;
243 | // mHeaderText.setText(mHeader);
244 | // mHeaderText.setTextSize(headerTextSize);
245 | // }
246 | setTextAttribute() ;//这里不调用这个函数就会显示错误的文字,没理由啊
247 | mSubHeaderText.setText(mPullLabel);//下拉刷新
248 | // mSubHeaderText.setTextColor(rgb);
249 | // mSubHeaderText.setTextSize(subHeaderTextSize);
250 | // Now call the callback
251 | pullToRefreshImpl();
252 | }
253 |
254 | public final void refreshing() {
255 | // if (null != mHeaderText) {
256 | // setTextAttribute() ;//3
257 | // mHeaderText.setText(mHeader);
258 | // mHeaderText.setTextSize(headerTextSize);
259 | // }
260 |
261 | if (mUseIntrinsicAnimation) {
262 | ((AnimationDrawable) mHeaderImage.getDrawable()).start();
263 | } else {
264 | // Now call the callback
265 | refreshingImpl();
266 | }
267 |
268 | if (null != mSubHeaderText) {
269 | mSubHeaderText.setVisibility(View.GONE);
270 | }
271 | }
272 |
273 | public final void releaseToRefresh() {
274 | // if (null != mHeaderText) {
275 | // setTextAttribute() ;//2
276 | // mHeaderText.setText(mHeader);//1
277 | // mHeaderText.setTextSize(headerTextSize);//1
278 | // }
279 | if (null != mSubHeaderText) {
280 | mSubHeaderText.setText(mReleaseLabel) ;//松开以刷新
281 | // setTextAttribute() ;//2
282 | // mSubHeaderText.setTextSize(subHeaderTextSize);//1
283 | // mSubHeaderText.setTextColor(rgb);//1
284 | }
285 | // Now call the callback
286 | releaseToRefreshImpl();
287 | }
288 |
289 | public final void reset() {
290 | if (null != mHeaderText) {
291 | // setTextAttribute() ;//2//3
292 | mHeaderText.setText(mPullLabel);//下拉刷新
293 | // mHeaderText.setTextSize(subHeaderTextSize);//1
294 | // mSubHeaderText.setTextColor(rgb);//1
295 | }
296 | mHeaderImage.setVisibility(View.VISIBLE);
297 |
298 | if (mUseIntrinsicAnimation) {
299 | ((AnimationDrawable) mHeaderImage.getDrawable()).stop();
300 | } else {
301 | // Now call the callback
302 | resetImpl();
303 | }
304 |
305 | if (null != mSubHeaderText) {
306 | if (TextUtils.isEmpty(mSubHeaderText.getText())) {
307 | mSubHeaderText.setVisibility(View.VISIBLE);
308 | } else {
309 | mSubHeaderText.setVisibility(View.VISIBLE);
310 | // setTextAttribute() ;//2//3
311 | // mSubHeaderText.setTextSize(subHeaderTextSize);//1
312 | // mSubHeaderText.setTextColor(rgb);//1
313 | }
314 | }
315 | }
316 |
317 | public void setTextAttribute() {
318 | mHeaderText.setText(mHeader);//健康送到家
319 | mHeaderText.setTextSize(headerTextSize);
320 | mHeaderText.setTextColor(rgbHeader);
321 | mSubHeaderText.setTextSize(subHeaderTextSize);
322 | mSubHeaderText.setTextColor(rgb);
323 | }
324 | @Override
325 | public void setLastUpdatedLabel(CharSequence label) {
326 | setSubHeaderText(label);
327 | }
328 |
329 | public final void setLoadingDrawable(Drawable imageDrawable) {
330 | // Set Drawable
331 | mHeaderImage.setImageDrawable(imageDrawable);
332 | mUseIntrinsicAnimation = (imageDrawable instanceof AnimationDrawable);
333 |
334 | // Now call the callback
335 | onLoadingDrawableSet(imageDrawable);
336 | }
337 |
338 | public void setPullLabel(CharSequence pullLabel) {
339 | mPullLabel = pullLabel;
340 | }
341 |
342 | public void setRefreshingLabel(CharSequence refreshingLabel) {
343 | mRefreshingLabel = refreshingLabel;
344 | }
345 |
346 | public void setReleaseLabel(CharSequence releaseLabel) {
347 | mReleaseLabel = releaseLabel;
348 | }
349 |
350 | @Override
351 | public void setTextTypeface(Typeface tf) {
352 | mHeaderText.setTypeface(tf);
353 | }
354 |
355 | public final void showInvisibleViews() {
356 | if (View.INVISIBLE == mHeaderText.getVisibility()) {
357 | mHeaderText.setVisibility(View.VISIBLE);
358 | }
359 | if (View.INVISIBLE == mHeaderProgress.getVisibility()) {
360 | mHeaderProgress.setVisibility(View.VISIBLE);
361 | }
362 | if (View.INVISIBLE == mHeaderImage.getVisibility()) {
363 | mHeaderImage.setVisibility(View.VISIBLE);
364 | }
365 | if (View.INVISIBLE == mSubHeaderText.getVisibility()) {
366 | mSubHeaderText.setVisibility(View.VISIBLE);
367 | }
368 | }
369 |
370 | /**
371 | * Callbacks for derivative Layouts
372 | */
373 |
374 | protected abstract int getDefaultDrawableResId();
375 |
376 | protected abstract void onLoadingDrawableSet(Drawable imageDrawable);
377 |
378 | protected abstract void onPullImpl(float scaleOfLayout);
379 |
380 | protected abstract void pullToRefreshImpl();
381 |
382 | protected abstract void refreshingImpl();
383 |
384 | protected abstract void releaseToRefreshImpl();
385 |
386 | protected abstract void resetImpl();
387 |
388 | private void setSubHeaderText(CharSequence label) {
389 | if (null != mSubHeaderText) {
390 | if (TextUtils.isEmpty(label)) {
391 | mSubHeaderText.setVisibility(View.GONE);
392 | } else {
393 | mSubHeaderText.setText(label);
394 | mSubHeaderText.setTextSize(subHeaderTextSize);
395 | // Only set it to Visible if we're GONE, otherwise VISIBLE will
396 | // be set soon
397 | if (View.GONE == mSubHeaderText.getVisibility()) {
398 | mSubHeaderText.setVisibility(View.VISIBLE);
399 | }
400 | }
401 | }
402 | }
403 |
404 | private void setSubTextAppearance(int value) {
405 | if (null != mSubHeaderText) {
406 | mSubHeaderText.setTextAppearance(getContext(), value);
407 | }
408 | }
409 |
410 | private void setSubTextColor(ColorStateList color) {
411 | if (null != mSubHeaderText) {
412 | mSubHeaderText.setTextColor(color);
413 | }
414 | }
415 |
416 | private void setTextAppearance(int value) {
417 | if (null != mHeaderText) {
418 | mHeaderText.setTextAppearance(getContext(), value);
419 | }
420 | if (null != mSubHeaderText) {
421 | mSubHeaderText.setTextAppearance(getContext(), value);
422 | }
423 | }
424 |
425 | private void setTextColor(ColorStateList color) {
426 | if (null != mHeaderText) {
427 | mHeaderText.setTextColor(color);
428 | }
429 | if (null != mSubHeaderText) {
430 | mSubHeaderText.setTextColor(color);
431 | }
432 | }
433 |
434 | }
435 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/internal/RotateLoadingLayout.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.internal;
17 |
18 | import android.content.Context;
19 | import android.content.res.TypedArray;
20 | import android.graphics.Matrix;
21 | import android.graphics.drawable.Drawable;
22 | import android.view.animation.Animation;
23 | import android.view.animation.RotateAnimation;
24 | import android.widget.ImageView.ScaleType;
25 |
26 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
27 | import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
28 | import com.handmark.pulltorefresh.library.R;
29 |
30 | public class RotateLoadingLayout extends LoadingLayout {
31 |
32 | static final int ROTATION_ANIMATION_DURATION = 1200;
33 |
34 | private final Animation mRotateAnimation;
35 | private final Matrix mHeaderImageMatrix;
36 |
37 | private float mRotationPivotX, mRotationPivotY;
38 |
39 | private final boolean mRotateDrawableWhilePulling;
40 |
41 | public RotateLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) {
42 | super(context, mode, scrollDirection, attrs);
43 |
44 | mRotateDrawableWhilePulling = attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true);
45 |
46 | mHeaderImage.setScaleType(ScaleType.MATRIX);
47 | mHeaderImageMatrix = new Matrix();
48 | mHeaderImage.setImageMatrix(mHeaderImageMatrix);
49 |
50 | mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
51 | 0.5f);
52 | mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
53 | mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION);
54 | mRotateAnimation.setRepeatCount(Animation.INFINITE);
55 | mRotateAnimation.setRepeatMode(Animation.RESTART);
56 | }
57 |
58 | public void onLoadingDrawableSet(Drawable imageDrawable) {
59 | if (null != imageDrawable) {
60 | mRotationPivotX = Math.round(imageDrawable.getIntrinsicWidth() / 2f);
61 | mRotationPivotY = Math.round(imageDrawable.getIntrinsicHeight() / 2f);
62 | }
63 | }
64 |
65 | protected void onPullImpl(float scaleOfLayout) {
66 | float angle;
67 | if (mRotateDrawableWhilePulling) {
68 | angle = scaleOfLayout * 90f;
69 | } else {
70 | angle = Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f));
71 | }
72 |
73 | mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY);
74 | mHeaderImage.setImageMatrix(mHeaderImageMatrix);
75 | }
76 |
77 | @Override
78 | protected void refreshingImpl() {
79 | mHeaderImage.startAnimation(mRotateAnimation);
80 | }
81 |
82 | @Override
83 | protected void resetImpl() {
84 | mHeaderImage.clearAnimation();
85 | resetImageRotation();
86 | }
87 |
88 | private void resetImageRotation() {
89 | if (null != mHeaderImageMatrix) {
90 | mHeaderImageMatrix.reset();
91 | mHeaderImage.setImageMatrix(mHeaderImageMatrix);
92 | }
93 | }
94 |
95 | @Override
96 | protected void pullToRefreshImpl() {
97 | // NO-OP
98 | }
99 |
100 | @Override
101 | protected void releaseToRefreshImpl() {
102 | // NO-OP
103 | }
104 |
105 | @Override
106 | protected int getDefaultDrawableResId() {
107 | return R.drawable.default_ptr_rotate;
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/internal/Utils.java:
--------------------------------------------------------------------------------
1 | package com.handmark.pulltorefresh.library.internal;
2 |
3 | import android.util.Log;
4 |
5 | public class Utils {
6 |
7 | static final String LOG_TAG = "PullToRefresh";
8 |
9 | public static void warnDeprecation(String depreacted, String replacement) {
10 | Log.w(LOG_TAG, "You're using the deprecated " + depreacted + " attr, please switch over to " + replacement);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/library/src/main/java/com/handmark/pulltorefresh/library/internal/ViewCompat.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright 2011, 2012 Chris Banes.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *******************************************************************************/
16 | package com.handmark.pulltorefresh.library.internal;
17 |
18 | import android.annotation.TargetApi;
19 | import android.graphics.drawable.Drawable;
20 | import android.os.Build.VERSION;
21 | import android.os.Build.VERSION_CODES;
22 | import android.view.View;
23 |
24 | @SuppressWarnings("deprecation")
25 | public class ViewCompat {
26 |
27 | public static void postOnAnimation(View view, Runnable runnable) {
28 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
29 | SDK16.postOnAnimation(view, runnable);
30 | } else {
31 | view.postDelayed(runnable, 16);
32 | }
33 | }
34 |
35 | public static void setBackground(View view, Drawable background) {
36 | if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
37 | SDK16.setBackground(view, background);
38 | } else {
39 | view.setBackgroundDrawable(background);
40 | }
41 | }
42 |
43 | public static void setLayerType(View view, int layerType) {
44 | if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
45 | SDK11.setLayerType(view, layerType);
46 | }
47 | }
48 |
49 | @TargetApi(11)
50 | static class SDK11 {
51 |
52 | public static void setLayerType(View view, int layerType) {
53 | view.setLayerType(layerType, null);
54 | }
55 | }
56 |
57 | @TargetApi(16)
58 | static class SDK16 {
59 |
60 | public static void postOnAnimation(View view, Runnable runnable) {
61 | view.postOnAnimation(runnable);
62 | }
63 |
64 | public static void setBackground(View view, Drawable background) {
65 | view.setBackground(background);
66 | }
67 |
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/slide_in_from_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/slide_in_from_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/slide_out_to_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/library/src/main/res/anim/slide_out_to_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
22 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/default_ptr_flip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-hdpi/default_ptr_flip.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/default_ptr_rotate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-hdpi/default_ptr_rotate.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-hdpi/indicator_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-hdpi/indicator_arrow.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/default_ptr_flip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-mdpi/default_ptr_flip.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/default_ptr_rotate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-mdpi/default_ptr_rotate.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-mdpi/indicator_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-mdpi/indicator_arrow.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/default_ptr_flip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-xhdpi/default_ptr_flip.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/default_ptr_rotate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-xhdpi/default_ptr_rotate.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/indicator_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leibing8912/LbaizxfPulltoRefresh/f7ffe9451624316a03a02da2f5a7332b3ee47a88/library/src/main/res/drawable-xhdpi/indicator_arrow.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable/indicator_bg_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
17 |
18 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable/indicator_bg_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
17 |
18 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/pull_to_refresh_header_horizontal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
18 |
19 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/pull_to_refresh_header_vertical.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
20 |
21 |
26 |
27 |
35 |
36 |
37 |
44 |
45 |
52 |
53 |
62 |
63 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ar/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | اسحب للتحديث…
4 | اترك للتحديث…
5 | تحميل…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-cs/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tažením aktualizujete…
4 | Uvolněním aktualizujete…
5 | Načítání…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-de/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Ziehen zum Aktualisieren…
4 | Loslassen zum Aktualisieren…
5 | Laden…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-es/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tirar para actualizar…
4 | Soltar para actualizar…
5 | Cargando…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-fi/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Päivitä vetämällä alas…
5 | Päivitä vapauttamalla…
6 | Päivitetään…
7 |
8 |
9 | Päivitä vetämällä ylös…
10 | @string/pull_to_refresh_release_label
11 | @string/pull_to_refresh_refreshing_label
12 |
13 |
--------------------------------------------------------------------------------
/library/src/main/res/values-fr/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tirez pour rafraîchir…
4 | Relâcher pour rafraîchir…
5 | Chargement…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-he/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | משוך לרענון…
4 | שחרר לרענון…
5 | טוען…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-it/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Tira per aggiornare…
4 | Rilascia per aggionare…
5 | Caricamento…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-iw/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | משוך לרענון…
4 | שחרר לרענון…
5 | טוען…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ja/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 画面を引っ張って…
4 | 指を離して更新…
5 | 読み込み中…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ko/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 당겨서 새로 고침…
4 | 놓아서 새로 고침…
5 | 로드 중…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-nl/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Sleep om te vernieuwen…
4 | Loslaten om te vernieuwen…
5 | Laden…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-pl/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Pociągnij, aby odświeżyć…
4 | Puść, aby odświeżyć…
5 | Wczytywanie…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-pt-rBR/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Puxe para atualizar…
4 | Libere para atualizar…
5 | Carregando…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-pt/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Puxe para atualizar…
4 | Liberação para atualizar…
5 | A carregar…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ro/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Trage pentru a reîmprospăta…
4 | Eliberează pentru a reîmprospăta…
5 | Încărcare…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-ru/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Потяните для обновления…
4 | Отпустите для обновления…
5 | Загрузка…
6 |
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values-zh/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 买正品药上健客
4 | 下拉刷新
5 | 松开以刷新
6 | 正在加载
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
66 |
67 |
68 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/library/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 10dp
5 | 12dp
6 | 4dp
7 | 24dp
8 | 12dp
9 |
10 |
--------------------------------------------------------------------------------
/library/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/library/src/main/res/values/pull_refresh_strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Pull to refresh…
5 | Release to refresh…
6 | Loading…
7 |
8 |
9 | @string/pull_to_refresh_pull_label
10 | @string/pull_to_refresh_release_label
11 | @string/pull_to_refresh_refreshing_label
12 |
13 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library'
2 |
--------------------------------------------------------------------------------