4 | * Copyright (c), 2009 深圳孔方兄金融信息服务有限公司(Shenzhen kfxiong 5 | * Financial Information Service Co. Ltd.) 6 | *
7 | * 著作权人保留一切权利,任何使用需经授权。
8 | */
9 | package space.sye.z.library.adapter;
10 |
11 | import android.support.v7.widget.RecyclerView;
12 | import android.support.v7.widget.StaggeredGridLayoutManager;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.widget.AdapterView;
16 |
17 | import java.util.ArrayList;
18 |
19 | import space.sye.z.library.holder.RecyclerHeaderViewHolder;
20 |
21 | /**
22 | * Created by Syehunter on 2015/11/2.
23 | */
24 | public class RefreshRecyclerViewAdapter extends RecyclerView.Adapter
4 | * Copyright (c), 2009 深圳孔方兄金融信息服务有限公司(Shenzhen kfxiong
5 | * Financial Information Service Co. Ltd.)
6 | *
7 | * 著作权人保留一切权利,任何使用需经授权。
8 | */
9 | package space.sye.z.library.manager;
10 |
11 | import android.content.Context;
12 | import android.support.v7.widget.GridLayoutManager;
13 | import android.support.v7.widget.RecyclerView;
14 | import android.view.View;
15 |
16 | import space.sye.z.library.adapter.RefreshRecyclerViewAdapter;
17 | import space.sye.z.library.listener.LoadMoreRecyclerListener;
18 | import space.sye.z.library.listener.OnLoadMoreListener;
19 | import space.sye.z.library.listener.OnPullDownListener;
20 | import space.sye.z.library.listener.OnBothRefreshListener;
21 | import space.sye.z.library.RefreshRecyclerView;
22 |
23 | /**
24 | * The Management Class for RefreshRecyclerViewAdapter
25 | * Created by Syehunter on 2015/11/19.
26 | */
27 | public class RefreshRecyclerAdapterManager {
28 |
29 | private RefreshRecyclerView recyclerView;
30 | private RefreshRecyclerViewAdapter mAdapter;
31 | private RecyclerView.LayoutManager mLayoutManager;
32 | private RecyclerMode mode;
33 |
34 | private OnBothRefreshListener mOnBothRefreshListener;
35 | private OnPullDownListener mOnPullDownListener;
36 | private OnLoadMoreListener mOnLoadMoreListener;
37 | private RefreshRecyclerViewAdapter.OnItemClickListener mOnItemClickListener;
38 | private RefreshRecyclerViewAdapter.OnItemLongClickListener mOnItemLongClickListener;
39 | private RecyclerView.ItemDecoration mDecor;
40 | private LoadMoreRecyclerListener loadMoreRecyclerListener;
41 | private RecyclerView.ItemAnimator mItemAnimator;
42 |
43 | public RefreshRecyclerAdapterManager(
44 | RecyclerView.Adapter adapter, RecyclerView.LayoutManager layoutManager) {
45 | this.mAdapter = new RefreshRecyclerViewAdapter(adapter);
46 |
47 | if (null == layoutManager){
48 | throw new NullPointerException("Couldn't resolve a null object reference of LayoutManager");
49 | }
50 | this.mLayoutManager = layoutManager;
51 | if (layoutManager instanceof GridLayoutManager){
52 | //如果是header或footer,设置其充满整列
53 | ((GridLayoutManager)layoutManager).setSpanSizeLookup(
54 | new HeaderSapnSizeLookUp(mAdapter, ((GridLayoutManager) layoutManager).getSpanCount()));
55 | }
56 | this.mLayoutManager = layoutManager;
57 | }
58 |
59 | private RefreshRecyclerAdapterManager getInstance(){
60 | return RefreshRecyclerAdapterManager.this;
61 | }
62 |
63 | public RefreshRecyclerAdapterManager addHeaderView(View v){
64 | mAdapter.addHeaderView(v);
65 | return getInstance();
66 | }
67 |
68 | public RefreshRecyclerAdapterManager addHeaderView(View v, int position){
69 | mAdapter.addHeaderView(v, position);
70 | return getInstance();
71 | }
72 |
73 | public RefreshRecyclerAdapterManager addFooterView(View v){
74 | mAdapter.addFooterView(v);
75 | return getInstance();
76 | }
77 |
78 | public RefreshRecyclerAdapterManager removeHeaderView(View v){
79 | mAdapter.removeHeader(v);
80 | return getInstance();
81 | }
82 |
83 | public RefreshRecyclerViewAdapter getAdapter(){
84 | return mAdapter;
85 | }
86 |
87 | public RefreshRecyclerAdapterManager setOnBothRefreshListener(OnBothRefreshListener onBothRefreshListener){
88 | this.mOnBothRefreshListener = onBothRefreshListener;
89 | return getInstance();
90 | }
91 |
92 | public RefreshRecyclerAdapterManager setOnPullDownListener(OnPullDownListener onPullDownListener){
93 | this.mOnPullDownListener = onPullDownListener;
94 | return getInstance();
95 | }
96 |
97 | public RefreshRecyclerAdapterManager setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener){
98 | this.mOnLoadMoreListener = onLoadMoreListener;
99 | return getInstance();
100 | }
101 |
102 | public RefreshRecyclerAdapterManager removeFooterView(View v){
103 | mAdapter.removeFooter(v);
104 | return getInstance();
105 | }
106 |
107 | public RefreshRecyclerAdapterManager setMode(RecyclerMode mode){
108 | this.mode = mode;
109 | return getInstance();
110 | }
111 |
112 | // public RefreshRecyclerAdapterManager setLayoutManager(RecyclerView.LayoutManager layoutManager){
113 | // if (null == layoutManager){
114 | // throw new NullPointerException("Couldn't resolve a null object reference of LayoutManager");
115 | // }
116 | // this.mLayoutManager = layoutManager;
117 | // if (layoutManager instanceof GridLayoutManager){
118 | // //如果是header或footer,设置其充满整列
119 | // ((GridLayoutManager)layoutManager).setSpanSizeLookup(
120 | // new HeaderSapnSizeLookUp(mAdapter, ((GridLayoutManager) layoutManager).getSpanCount()));
121 | // }
122 | // return getInstance();
123 | // }
124 |
125 | public RefreshRecyclerAdapterManager setOnItemClickListener
126 | (RefreshRecyclerViewAdapter.OnItemClickListener onItemClickListener){
127 | this.mOnItemClickListener = onItemClickListener;
128 | return getInstance();
129 | }
130 |
131 | public RefreshRecyclerAdapterManager setOnItemLongClickListener(
132 | RefreshRecyclerViewAdapter.OnItemLongClickListener onItemLongClickListener){
133 | this.mOnItemLongClickListener = onItemLongClickListener;
134 | return getInstance();
135 | }
136 |
137 | public void onRefreshCompleted(){
138 | if (null == recyclerView){
139 | throw new NullPointerException("recyclerView is null");
140 | }
141 | if (null == mAdapter){
142 | throw new NullPointerException("adapter is null");
143 | }
144 | if (RecyclerMode.BOTH == mode || RecyclerMode.TOP == mode){
145 | recyclerView.refreshComplete();
146 | }
147 | if (RecyclerMode.BOTH == mode || RecyclerMode.BOTTOM == mode){
148 | if(null != loadMoreRecyclerListener){
149 | loadMoreRecyclerListener.onRefreshComplete();
150 | }
151 | }
152 |
153 | }
154 |
155 | public RefreshRecyclerView getRecyclerView(){
156 | if (null == recyclerView){
157 | throw new NullPointerException("Couldn't resolve a null object reference of RefreshRecyclerView");
158 | }
159 | return recyclerView;
160 | }
161 |
162 | public RefreshRecyclerAdapterManager setItemAnimator(RecyclerView.ItemAnimator itemAnimator){
163 | this.mItemAnimator = itemAnimator;
164 | return getInstance();
165 | }
166 |
167 | public RefreshRecyclerAdapterManager addItemDecoration(RecyclerView.ItemDecoration decor){
168 | this.mDecor = decor;
169 | return getInstance();
170 | }
171 |
172 | public void into(RefreshRecyclerView recyclerView, Context context){
173 | if (null == recyclerView){
174 | throw new NullPointerException("Couldn't resolve a null object reference of RefreshRecyclerView");
175 | }
176 |
177 | mAdapter.putLayoutManager(mLayoutManager);
178 | recyclerView.setAdapter(mAdapter);
179 |
180 | recyclerView.setMode(mode);
181 | //为RefreshRecyclerView添加滚动监听
182 | loadMoreRecyclerListener = new LoadMoreRecyclerListener(context, mode);
183 | recyclerView.addOnScrollListener(loadMoreRecyclerListener);
184 | recyclerView.addItemDecoration(mDecor);
185 | if (RecyclerMode.BOTH == mode){
186 | if (null != mOnBothRefreshListener){
187 | recyclerView.setOnBothRefreshListener(mOnBothRefreshListener);
188 | }
189 | } else if (RecyclerMode.TOP == mode){
190 | if(null != mOnPullDownListener){
191 | recyclerView.setOnPullDownListener(mOnPullDownListener);
192 | }
193 | } else if (RecyclerMode.BOTTOM == mode){
194 | if (null != mOnLoadMoreListener){
195 | recyclerView.setOnLoadMoreListener(mOnLoadMoreListener);
196 | }
197 | }
198 |
199 | recyclerView.addItemDecoration(mDecor);
200 | recyclerView.setItemAnimator(mItemAnimator);
201 |
202 | mAdapter.setOnItemClickListener(mOnItemClickListener);
203 | mAdapter.setOnItemLongClickListener(mOnItemLongClickListener);
204 | recyclerView.setLayoutManager(mLayoutManager);
205 | this.recyclerView = recyclerView;
206 | }
207 |
208 | }
209 |
--------------------------------------------------------------------------------
/library/src/main/java/space/sye/z/library/widget/FlipLoadingLayout.java:
--------------------------------------------------------------------------------
1 | package space.sye.z.library.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.FrameLayout;
6 |
7 | import in.srain.cube.views.ptr.PtrFrameLayout;
8 | import in.srain.cube.views.ptr.PtrUIHandler;
9 | import in.srain.cube.views.ptr.indicator.PtrIndicator;
10 |
11 | /**
12 | * Created by Syehunter on 15/12/29.
13 | */
14 | public class FlipLoadingLayout extends FrameLayout implements PtrUIHandler {
15 |
16 | public FlipLoadingLayout(Context context) {
17 | super(context);
18 | }
19 |
20 | public FlipLoadingLayout(Context context, AttributeSet attrs) {
21 | super(context, attrs);
22 | }
23 |
24 | public FlipLoadingLayout(Context context, AttributeSet attrs, int defStyleAttr) {
25 | super(context, attrs, defStyleAttr);
26 | }
27 |
28 | @Override
29 | public void onUIReset(PtrFrameLayout frame) {
30 |
31 | }
32 |
33 | @Override
34 | public void onUIRefreshPrepare(PtrFrameLayout frame) {
35 |
36 | }
37 |
38 | @Override
39 | public void onUIRefreshBegin(PtrFrameLayout frame) {
40 |
41 | }
42 |
43 | @Override
44 | public void onUIRefreshComplete(PtrFrameLayout frame) {
45 |
46 | }
47 |
48 | @Override
49 | public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
50 |
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/library/src/main/java/space/sye/z/library/widget/RefreshHeader.java:
--------------------------------------------------------------------------------
1 | package space.sye.z.library.widget;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.content.res.TypedArray;
6 | import android.text.TextUtils;
7 | import android.util.AttributeSet;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.animation.LinearInterpolator;
11 | import android.view.animation.RotateAnimation;
12 | import android.widget.FrameLayout;
13 | import android.widget.TextView;
14 |
15 | import java.text.SimpleDateFormat;
16 | import java.util.Date;
17 |
18 | import in.srain.cube.views.ptr.PtrFrameLayout;
19 | import in.srain.cube.views.ptr.PtrUIHandler;
20 | import in.srain.cube.views.ptr.indicator.PtrIndicator;
21 | import space.sye.z.library.R;
22 |
23 | /**
24 | * Created by Syehunter on 2016/1/5.
25 | */
26 | public class RefreshHeader extends FrameLayout implements PtrUIHandler {
27 |
28 | private final static String KEY_SharedPreferences = "cube_ptr_classic_last_update";
29 | private static SimpleDateFormat sDataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
30 | private int mRotateAniTime = 150;
31 | private RotateAnimation mFlipAnimation;
32 | private RotateAnimation mReverseFlipAnimation;
33 | private TextView mTitleTextView;
34 | private View mRotateView;
35 | private View mProgressBar;
36 | private long mLastUpdateTime = -1;
37 | private TextView mLastUpdateTextView;
38 | private String mLastUpdateTimeKey;
39 | private boolean mShouldShowLastUpdate;
40 |
41 | private LastUpdateTimeUpdater mLastUpdateTimeUpdater = new LastUpdateTimeUpdater();
42 |
43 | public RefreshHeader(Context context) {
44 | super(context);
45 | initViews(null);
46 | }
47 |
48 | public RefreshHeader(Context context, AttributeSet attrs) {
49 | super(context, attrs);
50 | initViews(attrs);
51 | }
52 |
53 | public RefreshHeader(Context context, AttributeSet attrs, int defStyle) {
54 | super(context, attrs, defStyle);
55 | initViews(attrs);
56 | }
57 |
58 | protected void initViews(AttributeSet attrs) {
59 | TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.PtrClassicHeader, 0, 0);
60 | if (arr != null) {
61 | mRotateAniTime = arr.getInt(R.styleable.PtrClassicHeader_ptr_rotate_ani_time, mRotateAniTime);
62 | }
63 | buildAnimation();
64 | View header = LayoutInflater.from(getContext()).inflate(R.layout.header_refresh, this);
65 |
66 | mRotateView = header.findViewById(R.id.ptr_classic_header_rotate_view);
67 |
68 | mTitleTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_title);
69 | mLastUpdateTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_last_update);
70 | mProgressBar = header.findViewById(R.id.ptr_classic_header_rotate_view_progressbar);
71 |
72 | resetView();
73 | }
74 |
75 | @Override
76 | protected void onDetachedFromWindow() {
77 | super.onDetachedFromWindow();
78 | if (mLastUpdateTimeUpdater != null) {
79 | mLastUpdateTimeUpdater.stop();
80 | }
81 | }
82 |
83 | public void setRotateAniTime(int time) {
84 | if (time == mRotateAniTime || time == 0) {
85 | return;
86 | }
87 | mRotateAniTime = time;
88 | buildAnimation();
89 | }
90 |
91 | /**
92 | * Specify the last update time by this key string
93 | *
94 | * @param key
95 | */
96 | public void setLastUpdateTimeKey(String key) {
97 | if (TextUtils.isEmpty(key)) {
98 | return;
99 | }
100 | mLastUpdateTimeKey = key;
101 | }
102 |
103 | /**
104 | * Using an object to specify the last update time.
105 | *
106 | * @param object
107 | */
108 | public void setLastUpdateTimeRelateObject(Object object) {
109 | setLastUpdateTimeKey(object.getClass().getName());
110 | }
111 |
112 | private void buildAnimation() {
113 | mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
114 | mFlipAnimation.setInterpolator(new LinearInterpolator());
115 | mFlipAnimation.setDuration(mRotateAniTime);
116 | mFlipAnimation.setFillAfter(true);
117 |
118 | mReverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
119 | mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
120 | mReverseFlipAnimation.setDuration(mRotateAniTime);
121 | mReverseFlipAnimation.setFillAfter(true);
122 | }
123 |
124 | private void resetView() {
125 | hideRotateView();
126 | mProgressBar.setVisibility(INVISIBLE);
127 | }
128 |
129 | private void hideRotateView() {
130 | mRotateView.clearAnimation();
131 | mRotateView.setVisibility(INVISIBLE);
132 | }
133 |
134 | @Override
135 | public void onUIReset(PtrFrameLayout frame) {
136 | resetView();
137 | mShouldShowLastUpdate = true;
138 | tryUpdateLastUpdateTime();
139 | }
140 |
141 | @Override
142 | public void onUIRefreshPrepare(PtrFrameLayout frame) {
143 |
144 | mShouldShowLastUpdate = true;
145 | tryUpdateLastUpdateTime();
146 | mLastUpdateTimeUpdater.start();
147 |
148 | mProgressBar.setVisibility(INVISIBLE);
149 |
150 | mRotateView.setVisibility(VISIBLE);
151 | mTitleTextView.setVisibility(VISIBLE);
152 | if (frame.isPullToRefresh()) {
153 | mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh));
154 | } else {
155 | mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh));
156 | }
157 | }
158 |
159 | @Override
160 | public void onUIRefreshBegin(PtrFrameLayout frame) {
161 | mShouldShowLastUpdate = false;
162 | hideRotateView();
163 | mProgressBar.setVisibility(VISIBLE);
164 | mTitleTextView.setVisibility(VISIBLE);
165 | mTitleTextView.setText(R.string.cube_ptr_refreshing);
166 |
167 | tryUpdateLastUpdateTime();
168 | mLastUpdateTimeUpdater.stop();
169 | }
170 |
171 | @Override
172 | public void onUIRefreshComplete(PtrFrameLayout frame) {
173 |
174 | hideRotateView();
175 | mProgressBar.setVisibility(INVISIBLE);
176 |
177 | mTitleTextView.setVisibility(VISIBLE);
178 | mTitleTextView.setText(getResources().getString(R.string.cube_ptr_refresh_complete));
179 |
180 | // update last update time
181 | SharedPreferences sharedPreferences = getContext().getSharedPreferences(KEY_SharedPreferences, 0);
182 | if (!TextUtils.isEmpty(mLastUpdateTimeKey)) {
183 | mLastUpdateTime = new Date().getTime();
184 | sharedPreferences.edit().putLong(mLastUpdateTimeKey, mLastUpdateTime).commit();
185 | }
186 | }
187 |
188 | private void tryUpdateLastUpdateTime() {
189 | if (TextUtils.isEmpty(mLastUpdateTimeKey) || !mShouldShowLastUpdate) {
190 | mLastUpdateTextView.setVisibility(GONE);
191 | } else {
192 | String time = getLastUpdateTime();
193 | if (TextUtils.isEmpty(time)) {
194 | mLastUpdateTextView.setVisibility(GONE);
195 | } else {
196 | mLastUpdateTextView.setVisibility(VISIBLE);
197 | mLastUpdateTextView.setText(time);
198 | }
199 | }
200 | }
201 |
202 | private String getLastUpdateTime() {
203 |
204 | if (mLastUpdateTime == -1 && !TextUtils.isEmpty(mLastUpdateTimeKey)) {
205 | mLastUpdateTime = getContext().getSharedPreferences(KEY_SharedPreferences, 0).getLong(mLastUpdateTimeKey, -1);
206 | }
207 | if (mLastUpdateTime == -1) {
208 | return null;
209 | }
210 | long diffTime = new Date().getTime() - mLastUpdateTime;
211 | int seconds = (int) (diffTime / 1000);
212 | if (diffTime < 0) {
213 | return null;
214 | }
215 | if (seconds <= 0) {
216 | return null;
217 | }
218 | StringBuilder sb = new StringBuilder();
219 | sb.append(getContext().getString(R.string.cube_ptr_last_update));
220 |
221 | if (seconds < 60) {
222 | sb.append(seconds + getContext().getString(R.string.cube_ptr_seconds_ago));
223 | } else {
224 | int minutes = (seconds / 60);
225 | if (minutes > 60) {
226 | int hours = minutes / 60;
227 | if (hours > 24) {
228 | Date date = new Date(mLastUpdateTime);
229 | sb.append(sDataFormat.format(date));
230 | } else {
231 | sb.append(hours + getContext().getString(R.string.cube_ptr_hours_ago));
232 | }
233 |
234 | } else {
235 | sb.append(minutes + getContext().getString(R.string.cube_ptr_minutes_ago));
236 | }
237 | }
238 | return sb.toString();
239 | }
240 |
241 | @Override
242 | public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
243 |
244 | final int mOffsetToRefresh = frame.getOffsetToRefresh();
245 | final int currentPos = ptrIndicator.getCurrentPosY();
246 | final int lastPos = ptrIndicator.getLastPosY();
247 |
248 | if (currentPos < mOffsetToRefresh && lastPos >= mOffsetToRefresh) {
249 | if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {
250 | crossRotateLineFromBottomUnderTouch(frame);
251 | if (mRotateView != null) {
252 | mRotateView.clearAnimation();
253 | mRotateView.startAnimation(mReverseFlipAnimation);
254 | }
255 | }
256 | } else if (currentPos > mOffsetToRefresh && lastPos <= mOffsetToRefresh) {
257 | if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {
258 | crossRotateLineFromTopUnderTouch(frame);
259 | if (mRotateView != null) {
260 | mRotateView.clearAnimation();
261 | mRotateView.startAnimation(mFlipAnimation);
262 | }
263 | }
264 | }
265 | }
266 |
267 | private void crossRotateLineFromTopUnderTouch(PtrFrameLayout frame) {
268 | if (!frame.isPullToRefresh()) {
269 | mTitleTextView.setVisibility(VISIBLE);
270 | mTitleTextView.setText(R.string.cube_ptr_release_to_refresh);
271 | }
272 | }
273 |
274 | private void crossRotateLineFromBottomUnderTouch(PtrFrameLayout frame) {
275 | mTitleTextView.setVisibility(VISIBLE);
276 | if (frame.isPullToRefresh()) {
277 | mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh));
278 | } else {
279 | mTitleTextView.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh));
280 | }
281 | }
282 |
283 | private class LastUpdateTimeUpdater implements Runnable {
284 |
285 | private boolean mRunning = false;
286 |
287 | private void start() {
288 | if (TextUtils.isEmpty(mLastUpdateTimeKey)) {
289 | return;
290 | }
291 | mRunning = true;
292 | run();
293 | }
294 |
295 | private void stop() {
296 | mRunning = false;
297 | removeCallbacks(this);
298 | }
299 |
300 | @Override
301 | public void run() {
302 | tryUpdateLastUpdateTime();
303 | if (mRunning) {
304 | postDelayed(this, 1000);
305 | }
306 | }
307 | }
308 | }
309 |
--------------------------------------------------------------------------------
/library/src/main/java/space/sye/z/library/widget/RefreshLoadingLayout.java:
--------------------------------------------------------------------------------
1 | package space.sye.z.library.widget;
2 |
3 | import android.content.Context;
4 | import android.view.animation.Interpolator;
5 | import android.view.animation.LinearInterpolator;
6 | import android.widget.FrameLayout;
7 |
8 | import space.sye.z.library.manager.RecyclerMode;
9 |
10 | /**
11 | * Created by Syehunter on 2015/11/20.
12 | */
13 | public abstract class RefreshLoadingLayout extends FrameLayout {
14 |
15 | static final int ROTATION_ANIMATION_DURATION = 1200;
16 |
17 | static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator();
18 |
19 | protected Context mContext;
20 | protected RecyclerMode mode;
21 |
22 | public RefreshLoadingLayout(Context context, RecyclerMode mode) {
23 | super(context);
24 | this.mContext = context;
25 | this.mode = mode;
26 |
27 | init();
28 |
29 | reset();
30 | }
31 |
32 | protected void init() {
33 | }
34 |
35 | public final void onRefresh() {
36 | onRefreshImpl();
37 | }
38 |
39 | public void reset() {
40 | onResetImpl();
41 | }
42 |
43 | protected abstract void onRefreshImpl();
44 |
45 | protected abstract void onResetImpl();
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/library/src/main/java/space/sye/z/library/widget/RotateLoadingLayout.java:
--------------------------------------------------------------------------------
1 | package space.sye.z.library.widget;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.SharedPreferences;
6 | import android.graphics.Matrix;
7 | import android.graphics.drawable.AnimationDrawable;
8 | import android.graphics.drawable.Drawable;
9 | import android.text.TextUtils;
10 | import android.view.LayoutInflater;
11 | import android.view.View;
12 | import android.view.animation.Animation;
13 | import android.view.animation.RotateAnimation;
14 | import android.widget.ImageView;
15 | import android.widget.RelativeLayout;
16 | import android.widget.TextView;
17 |
18 | import space.sye.z.library.R;
19 | import space.sye.z.library.manager.RecyclerMode;
20 |
21 | /**
22 | * Created by Syehunter on 2015/11/22.
23 | */
24 | public class RotateLoadingLayout extends RefreshLoadingLayout {
25 |
26 | private RelativeLayout mRootView;
27 | private TextView mRefreshText;
28 | private TextView mRefreshTime;
29 | private ImageView mImage;
30 |
31 | private String mRefreshing;
32 | private String mLoading;
33 | private String mComplete;
34 | private String mLastUpdateTime;
35 | private Matrix mImageMatrix;
36 | private RotateAnimation mRotateAnimation;
37 |
38 | private Drawable imageDrawable;
39 | private LayoutParams layoutParams;
40 |
41 | private boolean mUseIntrinsicAnimation;
42 |
43 | public RotateLoadingLayout(Context context, RecyclerMode mode) {
44 | super(context, mode);
45 |
46 | }
47 |
48 | @Override
49 | protected void init() {
50 | View view = LayoutInflater.from(mContext).inflate(R.layout.loadinglayout, this, false);
51 | mRootView = (RelativeLayout) view.findViewById(R.id.fl_root);
52 | mRefreshText = (TextView) view.findViewById(R.id.tv_refresh);
53 | mRefreshTime = (TextView) view.findViewById(R.id.tv_refresh_time);
54 | mImage = (ImageView) view.findViewById(R.id.iv_image);
55 |
56 | layoutParams = (LayoutParams) mRootView.getLayoutParams();
57 |
58 | mRefreshing = mContext.getResources().getString(R.string.refreshing);
59 | mLoading = mContext.getResources().getString(R.string.loading);
60 | mComplete = mContext.getResources().getString(R.string.complete);
61 | mLastUpdateTime = getLastTime();
62 | if (!TextUtils.isEmpty(mLastUpdateTime)) {
63 | mRefreshTime.setText(mLastUpdateTime);
64 | }
65 |
66 | imageDrawable = mContext.getResources().getDrawable(R.mipmap.default_ptr_rotate);
67 | mImage.setScaleType(ImageView.ScaleType.MATRIX);
68 | mImageMatrix = new Matrix();
69 | mImage.setImageMatrix(mImageMatrix);
70 |
71 | mRotateAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f,
72 | Animation.RELATIVE_TO_SELF, 0.5f);
73 | mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
74 | mRotateAnimation.setDuration(ROTATION_ANIMATION_DURATION);
75 | mRotateAnimation.setRepeatCount(Animation.INFINITE);
76 | mRotateAnimation.setRepeatMode(Animation.RESTART);
77 |
78 |
79 | addView(view);
80 | }
81 |
82 | @Override
83 | protected void onRefreshImpl() {
84 | mImage.setImageDrawable(imageDrawable);
85 | if (null != mImage.getAnimation()){
86 | mImage.clearAnimation();
87 | }
88 | mImage.startAnimation(mRotateAnimation);
89 |
90 | if (RecyclerMode.BOTH == mode || RecyclerMode.TOP == mode) {
91 | if (null != mRefreshText) {
92 | mRefreshText.setText(mRefreshing);
93 | }
94 | if (null != mRefreshTime) {
95 | if (TextUtils.isEmpty(mLastUpdateTime)) {
96 | mRefreshTime.setVisibility(View.GONE);
97 | } else {
98 | mRefreshTime.setVisibility(View.VISIBLE);
99 | }
100 | }
101 | } else {
102 | if (null != mRefreshText) {
103 | mRefreshText.setText(mLoading);
104 | }
105 | }
106 | }
107 |
108 | @Override
109 | protected void onResetImpl() {
110 | if (null != mRefreshText) {
111 | mRefreshText.setText(mComplete);
112 | }
113 | mImage.setImageDrawable(getResources().getDrawable(R.mipmap.refresh_complete));
114 | mImage.setVisibility(View.VISIBLE);
115 |
116 | mImage.clearAnimation();
117 | resetImageRotation();
118 |
119 | mRefreshTime.setVisibility(GONE);
120 | }
121 |
122 | public final void setHeight(int height) {
123 | layoutParams.height = height;
124 | requestLayout();
125 | }
126 |
127 | public final void setWidth(int width) {
128 | layoutParams.width = width;
129 | requestLayout();
130 | }
131 |
132 | public final int getContentSize() {
133 | return mRootView.getHeight();
134 | }
135 |
136 | public void setLayoutPadding(int left, int top, int right, int bottom) {
137 | layoutParams.setMargins(left, top, right, bottom);
138 | setLayoutParams(layoutParams);
139 | }
140 |
141 | private void resetImageRotation() {
142 | if (null != mImageMatrix) {
143 | mImageMatrix.reset();
144 | mImage.setImageMatrix(mImageMatrix);
145 | }
146 | }
147 |
148 | private String getLastTime() {
149 | SharedPreferences sp = mContext.getSharedPreferences("RefreshRecycleView", Activity.MODE_PRIVATE);
150 | String lastUpdateTime = sp.getString("LastUpdateTime", "");
151 | return lastUpdateTime;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/header_refresh.xml:
--------------------------------------------------------------------------------
1 |
2 |