Skip to content

Commit 53a4ce4

Browse files
author
Issac
committed
添加下拉刷新以及卡片动画
1 parent e7eb7c7 commit 53a4ce4

File tree

85 files changed

+3681
-39
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

85 files changed

+3681
-39
lines changed

Driibo/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ apply plugin: 'android'
1010

1111
dependencies {
1212
compile 'com.android.support:support-v4:13.0.+'
13+
compile project(':extras:ActionBar-PullToRefresh')
14+
compile project(':extras:ListViewAnimationLib')
1315
compile files('libs/gson-2.2.4.jar')
1416
compile files('libs/volley.jar')
1517
}

Driibo/src/main/java/com/refactech/driibo/data/RequestManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ public class RequestManager {
3636

3737
private static DiskBasedCache mDiskCache = (DiskBasedCache) mRequestQueue.getCache();
3838

39+
private RequestManager(){
40+
41+
}
42+
3943
private static Cache openCache() {
4044
return new DiskBasedCache(CacheUtils.getExternalCacheDir(AppData.getContext()),
4145
10 * 1024 * 1024);

Driibo/src/main/java/com/refactech/driibo/ui/MainActivity.java

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import com.refactech.driibo.ui.fragment.DrawerFragment;
77
import com.refactech.driibo.ui.fragment.ShotsFragment;
88

9+
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher;
10+
911
import android.app.ActionBar;
1012
import android.content.Intent;
1113
import android.content.res.Configuration;
@@ -32,7 +34,7 @@ public class MainActivity extends FragmentActivity {
3234

3335
private Menu mMenu;
3436

35-
private boolean mRefreshing = false;
37+
private PullToRefreshAttacher mPullToRefreshAttacher;
3638

3739
@Override
3840
protected void onCreate(Bundle savedInstanceState) {
@@ -51,19 +53,22 @@ protected void onCreate(Bundle savedInstanceState) {
5153
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer,
5254
R.string.drawer_open, R.string.drawer_close) {
5355
public void onDrawerClosed(View view) {
54-
if (!mRefreshing) {
55-
mMenu.findItem(R.id.action_refresh).setVisible(true);
56-
}
56+
mMenu.findItem(R.id.action_refresh).setVisible(true);
5757
}
5858

5959
public void onDrawerOpened(View drawerView) {
60-
if (!mRefreshing) {
61-
mMenu.findItem(R.id.action_refresh).setVisible(false);
62-
}
60+
mMenu.findItem(R.id.action_refresh).setVisible(false);
6361
mContentFragment.finishActionMode();
6462
}
6563
};
6664
mDrawerLayout.setDrawerListener(mDrawerToggle);
65+
PullToRefreshAttacher.Options options = new PullToRefreshAttacher.Options();
66+
options.headerInAnimation = R.anim.pulldown_fade_in;
67+
options.headerOutAnimation = R.anim.pulldown_fade_out;
68+
options.refreshScrollDistance = 0.3f;
69+
options.headerLayout = R.layout.pulldown_header;
70+
mPullToRefreshAttacher = new PullToRefreshAttacher(this, options);
71+
6772
setCategory(Category.popular);
6873
FragmentManager fragmentManager = getSupportFragmentManager();
6974
fragmentManager.beginTransaction().replace(R.id.left_drawer, new DrawerFragment()).commit();
@@ -99,7 +104,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
99104
}
100105
switch (item.getItemId()) {
101106
case R.id.action_refresh:
102-
mContentFragment.loadFirstPage();
107+
mContentFragment.loadFirstPageAndScrollToTop();
103108
return true;
104109
case R.id.action_settings:
105110
startActivity(new Intent(this, PreferenceActivity.class));
@@ -115,26 +120,14 @@ public void setCategory(Category category) {
115120
if (mCategory == category) {
116121
return;
117122
}
118-
setRefreshing(false);
123+
mPullToRefreshAttacher.setRefreshing(false);
119124
mCategory = category;
120125
mContentFragment = ShotsFragment.newInstance(category);
121126
FragmentManager fragmentManager = getSupportFragmentManager();
122127
fragmentManager.beginTransaction().replace(R.id.content_frame, mContentFragment).commit();
123128
}
124129

125-
public void setRefreshing(boolean refreshing) {
126-
if (mRefreshing == refreshing) {
127-
return;
128-
}
129-
mRefreshing = refreshing;
130-
setProgressBarIndeterminateVisibility(refreshing);
131-
if (mMenu != null) {
132-
mMenu.findItem(R.id.action_refresh).setVisible(!refreshing);
133-
}
134-
}
135-
136-
public boolean isRefreshing() {
137-
return mRefreshing;
130+
public PullToRefreshAttacher getPullToRefreshAttacher() {
131+
return mPullToRefreshAttacher;
138132
}
139-
140133
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
package com.refactech.driibo.ui.adapter;
3+
4+
import com.haarman.listviewanimations.swinginadapters.AnimationAdapter;
5+
import com.refactech.driibo.AppData;
6+
7+
import android.R;
8+
import android.animation.Animator;
9+
import android.animation.ObjectAnimator;
10+
import android.view.View;
11+
import android.view.ViewGroup;
12+
import android.widget.BaseAdapter;
13+
14+
public class CardsAnimationAdapter extends AnimationAdapter {
15+
16+
private float mTranslationY = 150;
17+
18+
private float mRotationX = 8;
19+
20+
private long mDuration;
21+
22+
public CardsAnimationAdapter(BaseAdapter baseAdapter) {
23+
super(baseAdapter);
24+
mDuration = AppData.getContext().getResources().getInteger(R.integer.config_mediumAnimTime);
25+
}
26+
27+
@Override
28+
protected long getAnimationDelayMillis() {
29+
return 30;
30+
}
31+
32+
@Override
33+
protected long getAnimationDurationMillis() {
34+
return mDuration;
35+
}
36+
37+
@Override
38+
public Animator[] getAnimators(ViewGroup parent, View view) {
39+
return new Animator[] {
40+
ObjectAnimator.ofFloat(view, "translationY", mTranslationY, 0),
41+
ObjectAnimator.ofFloat(view, "rotationX", mRotationX, 0)
42+
};
43+
}
44+
45+
@Override
46+
protected void prepareAnimation(View view) {
47+
view.setTranslationY(mTranslationY);
48+
view.setRotationX(mRotationX);
49+
}
50+
}

Driibo/src/main/java/com/refactech/driibo/ui/adapter/ListViewUtils.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
import android.widget.ListView;
66

77
public class ListViewUtils {
8+
private ListViewUtils() {
9+
10+
}
11+
812
/**
913
* 滚动列表到顶端
1014
*

Driibo/src/main/java/com/refactech/driibo/ui/fragment/ShotsFragment.java

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,22 @@
33

44
import com.android.volley.Response;
55
import com.android.volley.VolleyError;
6+
import com.haarman.listviewanimations.swinginadapters.AnimationAdapter;
67
import com.refactech.driibo.AppData;
78
import com.refactech.driibo.R;
89
import com.refactech.driibo.dao.ShotsDataHelper;
910
import com.refactech.driibo.data.GsonRequest;
1011
import com.refactech.driibo.type.dribble.Category;
1112
import com.refactech.driibo.type.dribble.Shot;
1213
import com.refactech.driibo.ui.MainActivity;
14+
import com.refactech.driibo.ui.adapter.CardsAnimationAdapter;
1315
import com.refactech.driibo.ui.adapter.ListViewUtils;
1416
import com.refactech.driibo.ui.adapter.ShotsAdapter;
1517
import com.refactech.driibo.util.CommonUtils;
1618
import com.refactech.driibo.vendor.DribbbleApi;
19+
import com.refactech.driibo.view.LoadingFooter;
20+
21+
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher;
1722

1823
import android.content.Intent;
1924
import android.database.Cursor;
@@ -30,7 +35,8 @@
3035
/**
3136
* Created by Issac on 7/18/13.
3237
*/
33-
public class ShotsFragment extends BaseFragment implements LoaderManager.LoaderCallbacks<Cursor> {
38+
public class ShotsFragment extends BaseFragment implements LoaderManager.LoaderCallbacks<Cursor>,
39+
PullToRefreshAttacher.OnRefreshListener {
3440
public static final String EXTRA_CATEGORY = "EXTRA_CATEGORY";
3541

3642
private Category mCategory;
@@ -47,7 +53,11 @@ public class ShotsFragment extends BaseFragment implements LoaderManager.LoaderC
4753

4854
private ActionMode mActionMode;
4955

50-
ShareActionProvider mShareActionProvider;
56+
private ShareActionProvider mShareActionProvider;
57+
58+
private PullToRefreshAttacher mPullToRefreshAttacher;
59+
60+
private LoadingFooter mLoadingFooter;
5161

5262
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
5363

@@ -100,10 +110,15 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
100110
mDataHelper = new ShotsDataHelper(AppData.getContext(), mCategory);
101111
mAdapter = new ShotsAdapter(getActivity(), mListView);
102112
View header = new View(getActivity());
103-
View footer = new View(getActivity());
113+
mPullToRefreshAttacher = ((MainActivity) getActivity()).getPullToRefreshAttacher();
114+
mPullToRefreshAttacher.setRefreshableView(mListView, this);
115+
mLoadingFooter = new LoadingFooter(getActivity());
116+
104117
mListView.addHeaderView(header);
105-
mListView.addFooterView(footer);
106-
mListView.setAdapter(mAdapter);
118+
mListView.addFooterView(mLoadingFooter.getView());
119+
AnimationAdapter animationAdapter = new CardsAnimationAdapter(mAdapter);
120+
animationAdapter.setListView(mListView);
121+
mListView.setAdapter(animationAdapter);
107122
getLoaderManager().initLoader(0, null, this);
108123
mActivity = (MainActivity) getActivity();
109124

@@ -116,6 +131,10 @@ public void onScrollStateChanged(AbsListView view, int scrollState) {
116131
@Override
117132
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
118133
int totalItemCount) {
134+
if (mLoadingFooter.getState() == LoadingFooter.State.Loading
135+
|| mLoadingFooter.getState() == LoadingFooter.State.TheEnd) {
136+
return;
137+
}
119138
if (firstVisibleItem + visibleItemCount >= totalItemCount
120139
&& totalItemCount != 0
121140
&& totalItemCount != mListView.getHeaderViewsCount()
@@ -146,7 +165,7 @@ public boolean onItemLongClick(AdapterView<?> parent, View view, int position, l
146165
}
147166
});
148167

149-
//TODO Share Logic
168+
// TODO Share Logic
150169
// mListView.setOnItemLongClickListener(new
151170
// AdapterView.OnItemLongClickListener() {
152171
// @Override
@@ -228,11 +247,11 @@ public void onLoaderReset(Loader<Cursor> loader) {
228247
mAdapter.changeCursor(null);
229248
}
230249

231-
private void loadDate(final int page) {
232-
if (mActivity.isRefreshing()) {
233-
return;
250+
private void loadData(final int page) {
251+
final boolean isRefreshFromTop = page == 1;
252+
if (!mPullToRefreshAttacher.isRefreshing() && isRefreshFromTop) {
253+
mPullToRefreshAttacher.setRefreshing(true);
234254
}
235-
mActivity.setRefreshing(true);
236255
executeRequest(new GsonRequest<Shot.ShotsRequestData>(String.format(DribbbleApi.SHOTS_LIST,
237256
mCategory.name(), page), Shot.ShotsRequestData.class, null,
238257
new Response.Listener<Shot.ShotsRequestData>() {
@@ -253,7 +272,11 @@ protected Object doInBackground(Object... params) {
253272
@Override
254273
protected void onPostExecute(Object o) {
255274
super.onPostExecute(o);
256-
mActivity.setRefreshing(false);
275+
if (isRefreshFromTop) {
276+
mPullToRefreshAttacher.setRefreshComplete();
277+
} else {
278+
mLoadingFooter.setState(LoadingFooter.State.Idle, 3000);
279+
}
257280
}
258281
});
259282
}
@@ -262,23 +285,37 @@ protected void onPostExecute(Object o) {
262285
public void onErrorResponse(VolleyError volleyError) {
263286
Toast.makeText(getActivity(), R.string.refresh_list_failed,
264287
Toast.LENGTH_SHORT).show();
265-
mActivity.setRefreshing(false);
288+
if (isRefreshFromTop) {
289+
mPullToRefreshAttacher.setRefreshComplete();
290+
} else {
291+
mLoadingFooter.setState(LoadingFooter.State.Idle, 3000);
292+
}
266293
}
267294
}));
268295
}
269296

270297
private void loadNextPage() {
271-
loadDate(mPage + 1);
298+
mLoadingFooter.setState(LoadingFooter.State.Loading);
299+
loadData(mPage + 1);
272300
}
273301

274-
public void loadFirstPage() {
302+
private void loadFirstPage() {
303+
loadData(1);
304+
}
305+
306+
public void loadFirstPageAndScrollToTop() {
275307
ListViewUtils.smoothScrollListViewToTop(mListView);
276-
loadDate(1);
308+
loadFirstPage();
277309
}
278310

279311
public void finishActionMode() {
280312
if (mActionMode != null) {
281313
mActionMode.finish();
282314
}
283315
}
316+
317+
@Override
318+
public void onRefreshStarted(View view) {
319+
loadFirstPage();
320+
}
284321
}

0 commit comments

Comments
 (0)