├── .gitignore
├── Pics
├── ScrollingTabs.gif
├── SimpleApp.gif
└── SlidingMenu.gif
├── PullToRefreshListView.md
├── PullToRefreshListView
├── .project
├── AndroidManifest.xml
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ ├── ic_launcher.png
│ │ ├── indicator_arrow.png
│ │ └── loading_logo.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── load_more_footer.xml
│ │ └── pull_to_refresh_header.xml
│ ├── values-en
│ │ └── strings.xml
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── charon
│ └── pulltorefreshlistview
│ ├── LoadMoreGridView.java
│ ├── LoadMoreListView.java
│ ├── PullRefreshAndLoadMoreListView.java
│ └── PullToRefreshListView.java
├── PullToRefreshListViewDemo
├── .project
├── AndroidManifest.xml
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── activity_loadmore.xml
│ │ ├── activity_loadmoregrid.xml
│ │ ├── activity_main.xml
│ │ ├── activity_pull_and_loadmore.xml
│ │ └── activity_pulltorefresh.xml
│ ├── menu
│ │ └── main.xml
│ ├── values-en
│ │ └── strings.xml
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── charon
│ └── pulltorefresh
│ └── demo
│ ├── LoadMoreActivity.java
│ ├── LoadMoreGridActivity.java
│ ├── MainActivity.java
│ ├── PullAndLoadMoreActivity.java
│ └── PullToRefreshActivity.java
├── README.md
├── README_ScrollingTabs.md
├── README_SlidingMenu.md
├── ScrollingTabs.md
├── ScrollingTabs
├── .gitignore
├── .project
├── AndroidManifest.xml
├── libs
│ └── android-support-v4.jar
├── project.properties
├── res
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── drawable
│ │ └── triangle.xml
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ └── strings.xml
└── src
│ └── com
│ └── charon
│ └── scrollingtabs
│ └── view
│ ├── ScrollingTabs.java
│ └── TriangleScrollingTabs.java
├── ScrollingTabsDemo
├── .gitignore
├── .project
├── AndroidManifest.xml
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── layout
│ │ ├── activity_main.xml
│ │ ├── activity_scrollingtabs.xml
│ │ ├── activity_trianglescrollingtabs.xml
│ │ ├── tab.xml
│ │ └── triangletab.xml
│ ├── menu
│ │ └── main.xml
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── charon
│ └── scrollingtabsdemo
│ ├── MainActivity.java
│ ├── ScroolingTabsActivity.java
│ └── TriangleScroolingTabsActivity.java
├── SimpleApp
├── .project
├── AndroidManifest.xml
├── libs
│ └── android-support-v4.jar
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ ├── base_actionbar_bg.9.png
│ │ ├── base_main_action_personal_normal.png
│ │ ├── biz_news_main_back_normal.png
│ │ ├── head_default.jpg
│ │ ├── ic_launcher.png
│ │ ├── indicator_arrow.png
│ │ └── loading_logo.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── drawable
│ │ └── tab_bg.xml
│ ├── layout
│ │ ├── activity_main.xml
│ │ ├── fragment_center.xml
│ │ ├── fragment_left.xml
│ │ ├── fragment_right.xml
│ │ ├── frame_center.xml
│ │ ├── frame_left.xml
│ │ ├── frame_right.xml
│ │ ├── item_lv_center.xml
│ │ ├── load_more_footer.xml
│ │ ├── lv_pager_center.xml
│ │ ├── pull_to_refresh_header.xml
│ │ └── tab_center.xml
│ ├── menu
│ │ └── main.xml
│ └── values
│ │ ├── color.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── charon
│ └── simpleapp
│ ├── MainActivity.java
│ ├── base
│ └── BaseActivity.java
│ └── fragment
│ ├── CenterFragment.java
│ ├── LeftFragment.java
│ ├── PagerFragment.java
│ └── RightFragment.java
├── SlidingMenu.md
├── SlidingMenu
├── .gitignore
├── .project
├── AndroidManifest.xml
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ │ └── ic_launcher.png
│ ├── menu
│ │ └── main.xml
│ ├── values-sw600dp
│ │ └── dimens.xml
│ ├── values-sw720dp-land
│ │ └── dimens.xml
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── com
│ └── charon
│ └── slidingmenu
│ └── view
│ └── SlidingMenu.java
└── SlidingMenuDemo
├── .project
├── AndroidManifest.xml
├── libs
└── android-support-v4.jar
├── proguard-project.txt
├── project.properties
├── res
├── drawable-hdpi
│ ├── base_actionbar_bg.9.png
│ ├── base_main_action_personal_normal.png
│ ├── biz_news_main_back_normal.png
│ ├── head_default.jpg
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── drawable-xxhdpi
│ └── ic_launcher.png
├── layout
│ ├── activity_main.xml
│ ├── fragment_center.xml
│ ├── fragment_left.xml
│ ├── fragment_right.xml
│ ├── frame_center.xml
│ ├── frame_left.xml
│ └── frame_right.xml
├── menu
│ └── main.xml
├── values-sw600dp
│ └── dimens.xml
├── values-sw720dp-land
│ └── dimens.xml
├── values-v11
│ └── styles.xml
├── values-v14
│ └── styles.xml
└── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
└── src
└── com
└── charon
└── slidingmenudemo
├── MainActivity.java
└── fragment
├── CenterFragment.java
├── LeftFragment.java
├── PagerFragment.java
└── RightFragment.java
/.gitignore:
--------------------------------------------------------------------------------
1 | /PullToRefreshListView/.classpath
2 | /PullToRefreshListView/.settings
3 | /PullToRefreshListViewDemo/proguard-project.txt
4 | /PullToRefreshListViewDemo/.settings
5 | /PullToRefreshListViewDemo/assets
6 | /PullToRefreshListViewDemo/bin
7 | /PullToRefreshListViewDemo/gen
8 | /PullToRefreshListViewDemo/libs
9 | /PullToRefreshListViewDemo/.classpath
10 | /ScrollingTabs/.settings
11 | /ScrollingTabs/.classpath
12 | /ScrollingTabsDemo/.settings
13 | /ScrollingTabsDemo/.classpath
14 | /SimpleApp/.classpath
15 | /SimpleApp/.settings
16 | /SimpleApp/assets
17 | /SimpleApp/bin
18 | /SimpleApp/gen
19 | /PullToRefreshListView/bin
20 | /PullToRefreshListView/gen
21 | /PullToRefreshListView/assets
22 | /SlidingMenu/.classpath
23 | /SlidingMenu/.settings
24 | /SlidingMenuDemo/.classpath
25 | /SlidingMenuDemo/.settings
26 | /SlidingMenuDemo/assets
27 | /SlidingMenuDemo/bin
28 | /SlidingMenuDemo/gen
29 |
--------------------------------------------------------------------------------
/Pics/ScrollingTabs.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/Pics/ScrollingTabs.gif
--------------------------------------------------------------------------------
/Pics/SimpleApp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/Pics/SimpleApp.gif
--------------------------------------------------------------------------------
/Pics/SlidingMenu.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/Pics/SlidingMenu.gif
--------------------------------------------------------------------------------
/PullToRefreshListView.md:
--------------------------------------------------------------------------------
1 | 自定义下拉刷新ListView
2 | ===
3 |
4 | PullToRefreshListView
5 | ---
6 |
7 | **原理:**
8 | 拉刷新`ListView`无非就是对普通的`List View`添加一个`HeaderView`,然后通过对`ListView onTouchEvent`来获取当前下拉刷新的状态。然后去改变`HeaderView`的状态。
9 |
10 | 1. 自定义`ListView`,在构造方法中去添加`HeaderView`
11 | 通过`ListView.addHeaderView()`去添加`HeaderView`的时候,`HeaderView`会显示在屏幕的最初位置,我们需要它默认的时候是在屏幕的上方,这样默认时是不可见的,但是我们下拉`ListView`的时候,它就能够显示出来。这就要通过设置`HeaderView`的`padding`来实现它的隐藏。注意:View的显示最初要经过`Measure`测量宽高,我们在构造方法去添加的时候,该View可能并没有被测量,所以在获取`HeaderView`高度的时候会为0,这时候我们要手动的去测量一下`HeaderView`。
12 | ```java
13 |
14 | /**
15 | * 当前状态
16 | */
17 | private State mState = State.ORIGNAL;
18 |
19 | public PullToRefreshListView(Context context, AttributeSet attrs,
20 | int defStyle) {
21 | super(context, attrs, defStyle);
22 | initView(context);
23 | }
24 |
25 | public PullToRefreshListView(Context context, AttributeSet attrs) {
26 | super(context, attrs);
27 | initView(context);
28 | }
29 |
30 | public PullToRefreshListView(Context context) {
31 | super(context);
32 | initView(context);
33 | }
34 |
35 | private void initView(Context context) {
36 | LayoutInflater inflater = (LayoutInflater) context
37 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
38 |
39 | mHeader = inflater.inflate(R.layout.pull_to_refresh_header, null);
40 | iv_arrow = (ImageView) mHeader.findViewById(R.id.iv_arrow);
41 | pb_refresh = (ProgressBar) mHeader.findViewById(R.id.pb_refresh);
42 | tv_title = (TextView) mHeader.findViewById(R.id.tv_title);
43 | tv_time = (TextView) mHeader.findViewById(R.id.tv_time);
44 |
45 | measureHeaderView(mHeader);
46 |
47 | mHeaderHeight = mHeader.getMeasuredHeight();
48 | // To make header view above the window, so use -mHeaderHeight.
49 | mHeader.setPadding(0, -mHeaderHeight, 0, 0);
50 |
51 | mHeader.invalidate();
52 |
53 | addHeaderView(mHeader);
54 | }
55 |
56 | /**
57 | * 下拉刷新所有的状态
58 | */
59 | public enum State {
60 | ORIGNAL, PULL_TO_REFRESH, REFRESHING, RELEASE_TO_REFRESH;
61 | }
62 | ```
63 |
64 | 2. 重写onTouchEvent,来监听手指的下拉
65 | ```java
66 | public boolean onTouchEvent(MotionEvent ev) {
67 | int y = (int) ev.getRawY();
68 | int action = ev.getAction();
69 | switch (action) {
70 | case MotionEvent.ACTION_DOWN:
71 | //记录手指点下的位置
72 | downPositionY = y;
73 | break;
74 | case MotionEvent.ACTION_MOVE:
75 | //手指当前滑动的位置
76 | currentPositionY = y;
77 | //手指移动的距离,由于HeaderView高度固定,但是手指下拉的高度可以最大为屏幕的高度,如手指下拉屏幕高度时,HeaderView会很难看,所以我们让下拉的距离进行一个缩放。
78 | pullDistance = (currentPositionY - downPositionY) / RATIO;
79 |
80 | if (mState == State.REFRESHING) {
81 | break;
82 | } else if (mState == State.ORIGNAL && pullDistance > 0) {
83 | //如果现在处理起始的状态,并且距离大于0,就说明是下拉了,这时候状态需要变为下拉刷新的状态
84 | mState = State.PULL_TO_REFRESH;
85 | changeState();
86 | } else if (mState == State.PULL_TO_REFRESH
87 | && pullDistance > mHeaderHeight) {
88 | //当时为下拉刷新的状态,但是下拉的距离大于HeaderView的高度。这时状态要变为松手即可刷新
89 | mState = State.RELEASE_TO_REFRESH;
90 | changeState();
91 | } else if (mState == State.RELEASE_TO_REFRESH) {
92 | //释放刷新时有三种情况,一是我继续下啦,这时候不用管,因为继续下拉还是释放刷新。二是我手指往上移动,此时HeaderView不完全可见,这时候状态要改变为下拉刷新了。三是我手指上移的很厉害,导致HeaderView完全不可见了,这是状态要改变为起始状态。
93 | if (pullDistance < 0) {
94 | // 如果当时状态为松手刷新,但是这时候我并没有松手,而是直接将手指往上移动,移动回手指最先的位置,这时候状态要变为起始状态。
95 | mState = State.ORIGNAL;
96 | changeState();
97 | } else if (pullDistance < mHeaderHeight) {
98 | //手指上移,但是并没有移动到HeaderView完全不可见,这时候要将状态改变为下拉刷新
99 | mState = State.PULL_TO_REFRESH;
100 | isBack = true;
101 | changeState();
102 | }
103 |
104 | }
105 |
106 | //在移动的过程中不断的去改版Padding的值,控制其显示的大小
107 | if (mState != State.REFRESHING) {
108 | mHeader.setPadding(0, (int) (pullDistance - mHeaderHeight), 0,
109 | 0);
110 | }
111 |
112 | break;
113 | case MotionEvent.ACTION_UP:
114 | if (mState == State.REFRESHING) {
115 | //如果当前已经是正在刷新中了,再去下拉就不要处理了
116 | break;
117 | } else if (mState == State.PULL_TO_REFRESH) {
118 | //显现下拉刷新时,松手了,这时候要将其改为起始状态
119 | mState = State.ORIGNAL;
120 | } else if (mState == State.RELEASE_TO_REFRESH) {
121 | //松手刷新时松手了,这时候状态要变为正在刷新中。
122 | mState = State.REFRESHING;
123 | } else {
124 | break;
125 | }
126 | changeState();
127 | break;
128 |
129 | default:
130 | break;
131 | }
132 |
133 | return super.onTouchEvent(ev);
134 | }
135 | ```
136 |
137 | 3. 上面的写法仍有些问题。就是我们在`onTouchEvent`中`Move`里面对移动的距离进行了判断,但是`ListView`本身就是一个可以上下滑动的组件,如果我们直接这样判断,那`ListView`本上上下滑动的功能就被我们给抹去了。
138 | ```java
139 | @Override
140 | public boolean onTouchEvent(MotionEvent ev) {
141 | int y = (int) ev.getRawY();
142 | int action = ev.getAction();
143 | switch (action) {
144 | case MotionEvent.ACTION_DOWN:
145 | downPositionY = y;
146 | break;
147 | case MotionEvent.ACTION_MOVE:
148 | //一定要加上这句话,来判断当前是否可以下拉刷新
149 | if (!isCanPullToRefresh) {
150 | break;
151 | }
152 | .....
153 | break;
154 | ```
155 | 而对于`isCanPullToRefresh`的判断是通过`ListView.setOnScrollListener`去进行判断当前第一个可见条目是不是`ListView`的第一个条目,只有第一个条目在最顶端位置的时候才可以进行下拉刷新。
156 | ```java
157 | super.setOnScrollListener(new OnScrollListener() {
158 |
159 | @Override
160 | public void onScrollStateChanged(AbsListView view, int scrollState) {
161 | }
162 |
163 | @Override
164 | public void onScroll(AbsListView view, int firstVisibleItem,
165 | int visibleItemCount, int totalItemCount) {
166 |
167 | if (firstVisibleItem == 0) {
168 | isCanPullToRefresh = true;
169 | } else {
170 | isCanPullToRefresh = false;
171 | }
172 | }
173 | });
174 | ```
175 | 4. 提供刷新接口
176 | ```java
177 | public interface OnRefreshListener {
178 | abstract void onRefresh();
179 | }
180 | ```
181 | 5. ChangeState方法
182 | ```java
183 | /**
184 | * Change the state of header view when ListView in different state.
185 | */
186 | private void changeState() {
187 | //在该方法中对mState进行判断,根据不同状态作出处理,并且去调用刷新方法
188 | }
189 |
190 | /**
191 | *数据刷新完成后需要调用此方法去恢复装填
192 | */
193 | @SuppressWarnings("deprecation")
194 | public void onRefreshComplete() {
195 | mState = State.ORIGNAL;
196 | changeState();
197 | tv_time.setText(getResources().getString(R.string.update_time)
198 | + new Date().toLocaleString());
199 | }
200 | ```
201 |
202 | LoadMoreListView
203 | ---
204 |
205 | **原理:**
206 | 滑动到底部自动加载更多的`ListView`,无非就是通过对其滑动过程进行监听,一旦滑动到底部的时候我们就去加载新的数据。通过对`ListView`添加`FooterView`,然后在不同的状态控制它的显示与隐藏。
207 |
208 | 1. 自定义ListView的子类,在构造方法中去添加FooterView.
209 | ```java
210 | public class LoadMoreListView extends ListView {
211 |
212 | public LoadMoreListView(Context context, AttributeSet attrs, int defStyle) {
213 | super(context, attrs, defStyle);
214 | init(context);
215 | }
216 |
217 | public LoadMoreListView(Context context, AttributeSet attrs) {
218 | super(context, attrs);
219 | init(context);
220 | }
221 |
222 | public LoadMoreListView(Context context) {
223 | super(context);
224 | init(context);
225 | }
226 |
227 | private void init(Context context) {
228 | mFooterView = View.inflate(context, R.layout.load_more_footer, null);
229 | addFooterView(mFooterView);
230 | hideFooterView();
231 | }
232 | ```
233 |
234 | 2. 监听滑动状态,通过`setOnScrollListener`即可实现对状态的监听。
235 | ```java
236 | private void init(Context context) {
237 | mFooterView = View.inflate(context, R.layout.load_more_footer, null);
238 | addFooterView(mFooterView);
239 | hideFooterView();
240 | //为了防止在使用时调用setOnScrollListener会覆盖此时设置的Listener,我们在此使用super.setOnScrollListenr()
241 | super.setOnScrollListener(superOnScrollListener);
242 | }
243 | ```
244 |
245 | 3. 在`ScrollListener`中去判断当前滑动的状态。从而依据不同的状态去控制`FooterView`的显示与隐藏。
246 | ```java
247 | private OnScrollListener superOnScrollListener = new OnScrollListener() {
248 |
249 | @Override
250 | public void onScrollStateChanged(AbsListView view, int scrollState) {
251 | mCurrentScrollState = scrollState;
252 | }
253 |
254 | @Override
255 | public void onScroll(AbsListView view, int firstVisibleItem,
256 | int visibleItemCount, int totalItemCount) {
257 | if (visibleItemCount == totalItemCount) {
258 | //此时说明当前ListView所有的条目比较少,不足一屏
259 | hideFooterView();
260 | } else if (!mIsLoading
261 | && (firstVisibleItem + visibleItemCount >= totalItemCount)
262 | && mCurrentScrollState != SCROLL_STATE_IDLE) {
263 | //当第一个可见的条目位置加上当前也所有可见的条目数 等于 ListView当前总的条目数时,就说明已经滑动到了底部,这时候就要去显示FooterView。
264 | showFooterView();
265 | mIsLoading = true;
266 | if (mOnLoadMoreListener != null) {
267 | mOnLoadMoreListener.onLoadMore();
268 | }
269 | }
270 | }
271 | };
272 | ```
273 |
274 | 4. 提供自动加载更多的接口。
275 | ```java
276 | public interface OnLoadMoreListener {
277 | /**
278 | * Load more data.
279 | */
280 | void onLoadMore();
281 | }
282 | ```
283 |
284 | 在使用的时候,与ListView使用方法相同,只需调用`setOnLoadMoreListener`对其设置`OnLoadMoreListener`即可,然后在数据加载完成后调用`onLoadComplete`方法去恢复状态。
285 |
286 |
287 | PullAndLoadMoreListView
288 | ---
289 |
290 | 将下拉刷新和自动加载更多进行整合。就不多说了
291 |
292 | ------------------------------------------
293 |
294 | - 邮箱 :charon.chui@gmail.com
295 | - Good Luck!
--------------------------------------------------------------------------------
/PullToRefreshListView/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | PullToRefreshListView
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/PullToRefreshListView/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/PullToRefreshListView/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-20
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListView/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListView/res/drawable-hdpi/indicator_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListView/res/drawable-hdpi/indicator_arrow.png
--------------------------------------------------------------------------------
/PullToRefreshListView/res/drawable-hdpi/loading_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListView/res/drawable-hdpi/loading_logo.png
--------------------------------------------------------------------------------
/PullToRefreshListView/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListView/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListView/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListView/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListView/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListView/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListView/res/layout/load_more_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
22 |
23 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/layout/pull_to_refresh_header.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
8 |
9 |
15 |
16 |
21 |
22 |
27 |
28 |
29 |
34 |
35 |
41 |
42 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values-en/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PullToRefreshListView
5 | Settings
6 | Hello world!
7 | Pull To Refresh
8 | Load More
9 | Both
10 | Release To Refresh
11 | Refreshing...
12 | Update
13 |
14 |
15 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 下拉刷新
5 | 松开刷新
6 | 正在刷新中...
7 | 更新于
8 |
9 |
10 |
--------------------------------------------------------------------------------
/PullToRefreshListView/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/PullToRefreshListView/src/com/charon/pulltorefreshlistview/LoadMoreGridView.java:
--------------------------------------------------------------------------------
1 | package com.charon.pulltorefreshlistview;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.AbsListView;
6 | import android.widget.GridView;
7 |
8 | /**
9 | * Android load more GridView when scroll down.
10 | *
11 | * @author CharonChui
12 | */
13 | public class LoadMoreGridView extends GridView {
14 | private OnScrollListener mOnScrollListener;
15 | private OnLoadMoreListener mOnLoadMoreListener;
16 |
17 | /**
18 | * If is loading now.
19 | */
20 | private boolean mIsLoading;
21 |
22 | private int mCurrentScrollState;
23 |
24 | public LoadMoreGridView(Context context, AttributeSet attrs, int defStyle) {
25 | super(context, attrs, defStyle);
26 | init(context);
27 | }
28 |
29 | public LoadMoreGridView(Context context, AttributeSet attrs) {
30 | super(context, attrs);
31 | init(context);
32 | }
33 |
34 | public LoadMoreGridView(Context context) {
35 | super(context);
36 | init(context);
37 | }
38 |
39 | private void init(Context context) {
40 | /*
41 | * Must use super.setOnScrollListener() here to avoid override when call this view's setOnScrollListener method
42 | */
43 | super.setOnScrollListener(mSuperOnScrollListener);
44 | }
45 |
46 | @Override
47 | public void setOnScrollListener(OnScrollListener l) {
48 | mOnScrollListener = l;
49 | }
50 |
51 | /**
52 | * Set load more listener, usually you should get more data here.
53 | *
54 | * @param listener OnLoadMoreListener
55 | * @see OnLoadMoreListener
56 | */
57 | public void setOnLoadMoreListener(OnLoadMoreListener listener) {
58 | mOnLoadMoreListener = listener;
59 | }
60 |
61 | /**
62 | * When complete load more data, you must use this method to hide the footer view, if not the footer view will be
63 | * shown all the time.
64 | */
65 | public void onLoadMoreComplete() {
66 | mIsLoading = false;
67 | }
68 |
69 | private OnScrollListener mSuperOnScrollListener = new OnScrollListener() {
70 |
71 | @Override
72 | public void onScrollStateChanged(AbsListView view, int scrollState) {
73 | mCurrentScrollState = scrollState;
74 | // Avoid override when use setOnScrollListener
75 | if (mOnScrollListener != null) {
76 | mOnScrollListener.onScrollStateChanged(view, scrollState);
77 | }
78 | }
79 |
80 | @Override
81 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
82 | if (mOnScrollListener != null) {
83 | mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
84 | }
85 | // The count of footer view will be add to visibleItemCount also are
86 | // added to totalItemCount
87 | if (visibleItemCount == totalItemCount) {
88 | // If all the item can not fill screen, we should make the
89 | // footer view invisible.
90 | } else if (!mIsLoading && (firstVisibleItem + visibleItemCount >= totalItemCount)
91 | && mCurrentScrollState != SCROLL_STATE_IDLE) {
92 | mIsLoading = true;
93 | if (mOnLoadMoreListener != null) {
94 | mOnLoadMoreListener.onLoadMore();
95 | }
96 | }
97 | }
98 | };
99 |
100 | /**
101 | * Interface for load more
102 | */
103 | public interface OnLoadMoreListener {
104 | /**
105 | * Load more data.
106 | */
107 | void onLoadMore();
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/PullToRefreshListView/src/com/charon/pulltorefreshlistview/LoadMoreListView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Charon Chui
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 |
17 | package com.charon.pulltorefreshlistview;
18 |
19 | import com.charon.pulltorefreshlistview.R;
20 |
21 | import android.content.Context;
22 | import android.util.AttributeSet;
23 | import android.view.View;
24 | import android.widget.AbsListView;
25 | import android.widget.ListView;
26 |
27 | /**
28 | * Android load more ListView when scroll down.
29 | *
30 | * @author Charon Chui
31 | */
32 | public class LoadMoreListView extends ListView {
33 | protected static final String TAG = "LoadMoreListView";
34 | private View mFooterView;
35 | private OnScrollListener mOnScrollListener;
36 | private OnLoadMoreListener mOnLoadMoreListener;
37 |
38 | /**
39 | * If is loading now.
40 | */
41 | private boolean mIsLoading;
42 |
43 | private int mCurrentScrollState;
44 |
45 | public LoadMoreListView(Context context, AttributeSet attrs, int defStyle) {
46 | super(context, attrs, defStyle);
47 | init(context);
48 | }
49 |
50 | public LoadMoreListView(Context context, AttributeSet attrs) {
51 | super(context, attrs);
52 | init(context);
53 | }
54 |
55 | public LoadMoreListView(Context context) {
56 | super(context);
57 | init(context);
58 | }
59 |
60 | private void init(Context context) {
61 | mFooterView = View.inflate(context, R.layout.load_more_footer, null);
62 | addFooterView(mFooterView);
63 | hideFooterView();
64 | /*
65 | * Must use super.setOnScrollListener() here to avoid override when call this view's setOnScrollListener method
66 | */
67 | super.setOnScrollListener(superOnScrollListener);
68 | }
69 |
70 | /**
71 | * Hide the load more view(footer view)
72 | */
73 | private void hideFooterView() {
74 | mFooterView.setVisibility(View.GONE);
75 | }
76 |
77 | /**
78 | * Show load more view
79 | */
80 | private void showFooterView() {
81 | mFooterView.setVisibility(View.VISIBLE);
82 | }
83 |
84 | @Override
85 | public void setOnScrollListener(OnScrollListener l) {
86 | mOnScrollListener = l;
87 | }
88 |
89 | /**
90 | * Set load more listener, usually you should get more data here.
91 | *
92 | * @param listener OnLoadMoreListener
93 | * @see OnLoadMoreListener
94 | */
95 | public void setOnLoadMoreListener(OnLoadMoreListener listener) {
96 | mOnLoadMoreListener = listener;
97 | }
98 |
99 | /**
100 | * When complete load more data, you must use this method to hide the footer view, if not the footer view will be
101 | * shown all the time.
102 | */
103 | public void onLoadMoreComplete() {
104 | mIsLoading = false;
105 | hideFooterView();
106 | }
107 |
108 | private OnScrollListener superOnScrollListener = new OnScrollListener() {
109 |
110 | @Override
111 | public void onScrollStateChanged(AbsListView view, int scrollState) {
112 | mCurrentScrollState = scrollState;
113 | // Avoid override when use setOnScrollListener
114 | if (mOnScrollListener != null) {
115 | mOnScrollListener.onScrollStateChanged(view, scrollState);
116 | }
117 | }
118 |
119 | @Override
120 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
121 | if (mOnScrollListener != null) {
122 | mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
123 | }
124 | // The count of footer view will be add to visibleItemCount also are
125 | // added to totalItemCount
126 | if (visibleItemCount == totalItemCount) {
127 | // If all the item can not fill screen, we should make the
128 | // footer view invisible.
129 | hideFooterView();
130 | } else if (!mIsLoading && (firstVisibleItem + visibleItemCount >= totalItemCount)
131 | && mCurrentScrollState != SCROLL_STATE_IDLE) {
132 | showFooterView();
133 | mIsLoading = true;
134 | if (mOnLoadMoreListener != null) {
135 | mOnLoadMoreListener.onLoadMore();
136 | }
137 | }
138 | }
139 | };
140 |
141 | /**
142 | * Interface for load more
143 | */
144 | public interface OnLoadMoreListener {
145 | /**
146 | * Load more data.
147 | */
148 | void onLoadMore();
149 | }
150 |
151 | }
152 |
--------------------------------------------------------------------------------
/PullToRefreshListView/src/com/charon/pulltorefreshlistview/PullRefreshAndLoadMoreListView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Charon Chui
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 |
17 | package com.charon.pulltorefreshlistview;
18 |
19 | import com.charon.pulltorefreshlistview.R;
20 |
21 | import android.content.Context;
22 | import android.util.AttributeSet;
23 | import android.view.View;
24 | import android.widget.AbsListView;
25 |
26 | /**
27 | * Android load more ListView when scroll down.
28 | *
29 | * @author Charon Chui
30 | */
31 | public class PullRefreshAndLoadMoreListView extends PullToRefreshListView {
32 | protected static final String TAG = "LoadMoreListView";
33 | private View mFooterView;
34 | private OnScrollListener mOnScrollListener;
35 | private OnLoadMoreListener mOnLoadMoreListener;
36 |
37 | /**
38 | * If is loading now.
39 | */
40 | private boolean mIsLoading;
41 |
42 | private int mCurrentScrollState;
43 |
44 | public PullRefreshAndLoadMoreListView(Context context, AttributeSet attrs, int defStyle) {
45 | super(context, attrs, defStyle);
46 | init(context);
47 | }
48 |
49 | public PullRefreshAndLoadMoreListView(Context context, AttributeSet attrs) {
50 | super(context, attrs);
51 | init(context);
52 | }
53 |
54 | public PullRefreshAndLoadMoreListView(Context context) {
55 | super(context);
56 | init(context);
57 | }
58 |
59 | private void init(Context context) {
60 | mFooterView = View.inflate(context, R.layout.load_more_footer, null);
61 | addFooterView(mFooterView);
62 | hideFooterView();
63 | /*
64 | * Must use super.setOnScrollListener() here to avoid override when call this view's setOnScrollListener method
65 | */
66 | super.setOnScrollListener(superOnScrollListener);
67 | }
68 |
69 | /**
70 | * Hide the load more view(footer view)
71 | */
72 | private void hideFooterView() {
73 | mFooterView.setVisibility(View.GONE);
74 | }
75 |
76 | /**
77 | * Show load more view
78 | */
79 | private void showFooterView() {
80 | mFooterView.setVisibility(View.VISIBLE);
81 | }
82 |
83 | @Override
84 | public void setOnScrollListener(OnScrollListener l) {
85 | mOnScrollListener = l;
86 | }
87 |
88 | /**
89 | * Set load more listener, usually you should get more data here.
90 | *
91 | * @param listener OnLoadMoreListener
92 | * @see OnLoadMoreListener
93 | */
94 | public void setOnLoadMoreListener(OnLoadMoreListener listener) {
95 | mOnLoadMoreListener = listener;
96 | }
97 |
98 | /**
99 | * When complete load more data, you must use this method to hide the footer view, if not the footer view will be
100 | * shown all the time.
101 | */
102 | public void onLoadMoreComplete() {
103 | mIsLoading = false;
104 | hideFooterView();
105 | }
106 |
107 | private OnScrollListener superOnScrollListener = new OnScrollListener() {
108 |
109 | @Override
110 | public void onScrollStateChanged(AbsListView view, int scrollState) {
111 | mCurrentScrollState = scrollState;
112 | // Avoid override when use setOnScrollListener
113 | if (mOnScrollListener != null) {
114 | mOnScrollListener.onScrollStateChanged(view, scrollState);
115 | }
116 | }
117 |
118 | @Override
119 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
120 | if (mOnScrollListener != null) {
121 | mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
122 | }
123 | // The count of footer view will be add to visibleItemCount also are
124 | // added to totalItemCount
125 | if (visibleItemCount == totalItemCount) {
126 | // If all the item can not fill screen, we should make the
127 | // footer view invisible.
128 | hideFooterView();
129 | } else if (!mIsLoading && (firstVisibleItem + visibleItemCount >= totalItemCount)
130 | && mCurrentScrollState != SCROLL_STATE_IDLE) {
131 | showFooterView();
132 | mIsLoading = true;
133 | if (mOnLoadMoreListener != null) {
134 | mOnLoadMoreListener.onLoadMore();
135 | }
136 | }
137 | }
138 | };
139 |
140 | /**
141 | * Interface for load more
142 | */
143 | public interface OnLoadMoreListener {
144 | /**
145 | * Load more data.
146 | */
147 | void onLoadMore();
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/PullToRefreshListView/src/com/charon/pulltorefreshlistview/PullToRefreshListView.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Charon Chui
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 |
17 | package com.charon.pulltorefreshlistview;
18 |
19 | import java.util.Date;
20 |
21 | import android.annotation.SuppressLint;
22 | import android.content.Context;
23 | import android.util.AttributeSet;
24 | import android.view.LayoutInflater;
25 | import android.view.MotionEvent;
26 | import android.view.View;
27 | import android.view.ViewGroup;
28 | import android.view.animation.Animation;
29 | import android.view.animation.LinearInterpolator;
30 | import android.view.animation.RotateAnimation;
31 | import android.widget.AbsListView;
32 | import android.widget.ImageView;
33 | import android.widget.ListAdapter;
34 | import android.widget.ListView;
35 | import android.widget.ProgressBar;
36 | import android.widget.TextView;
37 |
38 | import com.charon.pulltorefreshlistview.R;
39 |
40 | /**
41 | * Android pull to refresh ListView.
42 | */
43 | public class PullToRefreshListView extends ListView {
44 |
45 | /**
46 | * Avoid pull all the screen height will make header view too large, so make a scale ratio.
47 | */
48 | private static final int RATIO = 3;
49 |
50 | private View mHeader;
51 | private ImageView iv_arrow;
52 | private ProgressBar pb_refresh;
53 | private TextView tv_title;
54 | private TextView tv_time;
55 |
56 | /**
57 | * Height of the HeaderView
58 | */
59 | private int mHeaderHeight;
60 |
61 | /**
62 | * The Y axis position when finger onTouch down.
63 | */
64 | private int downPositionY;
65 |
66 | /**
67 | * The Y axis position when finger onTouch moving
68 | */
69 | private int currentPositionY;
70 |
71 | /**
72 | * The pull distance.
73 | */
74 | private int pullDistance;
75 |
76 | /**
77 | * Current State
78 | */
79 | private State mState;
80 |
81 | /**
82 | * Animation for the arrow when is moving clockwise.
83 | */
84 | private Animation animation;
85 |
86 | /**
87 | * Animation for the arrow when is moving anticlockwise.
88 | */
89 | private Animation reverseAnimation;
90 |
91 | /**
92 | * If can pull now
93 | */
94 | private boolean isCanPullToRefresh;
95 |
96 | private OnRefreshListener mOnRefreshListener;
97 |
98 | /**
99 | * If you pull down but not release, your finger move up, this time we should play a reverse Animation.
100 | */
101 | private boolean isBack;
102 |
103 | private OnScrollListener mOnScrollListener;
104 |
105 | public PullToRefreshListView(Context context, AttributeSet attrs, int defStyle) {
106 | super(context, attrs, defStyle);
107 | initView(context);
108 | }
109 |
110 | public PullToRefreshListView(Context context, AttributeSet attrs) {
111 | super(context, attrs);
112 | initView(context);
113 | }
114 |
115 | public PullToRefreshListView(Context context) {
116 | super(context);
117 | initView(context);
118 | }
119 |
120 | @SuppressLint("InflateParams")
121 | private void initView(Context context) {
122 | LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
123 |
124 | mHeader = inflater.inflate(R.layout.pull_to_refresh_header, null);
125 | iv_arrow = (ImageView) mHeader.findViewById(R.id.iv_arrow);
126 | pb_refresh = (ProgressBar) mHeader.findViewById(R.id.pb_refresh);
127 | tv_title = (TextView) mHeader.findViewById(R.id.tv_title);
128 | tv_time = (TextView) mHeader.findViewById(R.id.tv_time);
129 |
130 | measureHeaderView(mHeader);
131 |
132 | mHeaderHeight = mHeader.getMeasuredHeight();
133 | // To make header view above the window, so use -mHeaderHeight.
134 | mHeader.setPadding(0, -mHeaderHeight, 0, 0);
135 |
136 | mHeader.invalidate();
137 |
138 | addHeaderView(mHeader);
139 |
140 | mState = State.ORIGNAL;
141 |
142 | super.setOnScrollListener(new OnScrollListener() {
143 |
144 | @Override
145 | public void onScrollStateChanged(AbsListView view, int scrollState) {
146 | // Avoid override when use setOnScrollListener
147 | if (mOnScrollListener != null) {
148 | mOnScrollListener.onScrollStateChanged(view, scrollState);
149 | }
150 | }
151 |
152 | @Override
153 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
154 |
155 | if (mOnScrollListener != null) {
156 | mOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount);
157 | }
158 |
159 | if (firstVisibleItem == 0) {
160 | isCanPullToRefresh = true;
161 | } else {
162 | isCanPullToRefresh = false;
163 | }
164 | }
165 | });
166 |
167 | animation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
168 | animation.setDuration(250);
169 | animation.setFillAfter(true);
170 | animation.setInterpolator(new LinearInterpolator());
171 |
172 | reverseAnimation =
173 | new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
174 | reverseAnimation.setDuration(200);
175 | reverseAnimation.setFillAfter(true);
176 | reverseAnimation.setInterpolator(new LinearInterpolator());
177 | }
178 |
179 | /**
180 | * Measure the height of the view will be when showing.
181 | *
182 | * @param view View to measure.
183 | */
184 | private void measureHeaderView(View view) {
185 | ViewGroup.LayoutParams lp = view.getLayoutParams();
186 | if (lp == null) {
187 | lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
188 | }
189 |
190 | int childMeasureWidth = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
191 | int childMeasureHeight;
192 | if (lp.height > 0) {
193 | childMeasureHeight = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
194 | } else {
195 | // Measure specification mode: The parent has not imposed any
196 | // constraint on the child. It can be whatever size it wants.
197 | childMeasureHeight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
198 | }
199 | view.measure(childMeasureWidth, childMeasureHeight);
200 | }
201 |
202 | @SuppressLint("ClickableViewAccessibility")
203 | @Override
204 | public boolean onTouchEvent(MotionEvent ev) {
205 | int y = (int) ev.getRawY();
206 | int action = ev.getAction();
207 | switch (action) {
208 | case MotionEvent.ACTION_DOWN:
209 | downPositionY = y;
210 | break;
211 | case MotionEvent.ACTION_MOVE:
212 | if (!isCanPullToRefresh) {
213 | break;
214 | }
215 | currentPositionY = y;
216 |
217 | pullDistance = (currentPositionY - downPositionY) / RATIO;
218 |
219 | if (mState == State.REFRESHING) {
220 | break;
221 | } else if (mState == State.ORIGNAL && pullDistance > 0) {
222 | mState = State.PULL_TO_REFRESH;
223 | changeState();
224 | } else if (mState == State.PULL_TO_REFRESH && pullDistance > mHeaderHeight) {
225 | mState = State.RELEASE_TO_REFRESH;
226 | changeState();
227 | } else if (mState == State.RELEASE_TO_REFRESH) {
228 | if (pullDistance < 0) {
229 | // invisible
230 | mState = State.ORIGNAL;
231 | changeState();
232 | } else if (pullDistance < mHeaderHeight) {
233 | mState = State.PULL_TO_REFRESH;
234 | isBack = true;
235 | changeState();
236 | }
237 |
238 | }
239 |
240 | if (mState != State.REFRESHING) {
241 | mHeader.setPadding(0, (int) (pullDistance - mHeaderHeight), 0, 0);
242 | }
243 |
244 | break;
245 | case MotionEvent.ACTION_UP:
246 | if (mState == State.REFRESHING) {
247 | break;
248 | } else if (mState == State.PULL_TO_REFRESH) {
249 | mState = State.ORIGNAL;
250 | } else if (mState == State.RELEASE_TO_REFRESH) {
251 | mState = State.REFRESHING;
252 | } else {
253 | break;
254 | }
255 | changeState();
256 | break;
257 |
258 | default:
259 | break;
260 | }
261 |
262 | return super.onTouchEvent(ev);
263 | }
264 |
265 | /**
266 | * Change the state of header view when ListView in different state.
267 | */
268 | private void changeState() {
269 | if (mState == State.ORIGNAL) {
270 | iv_arrow.setVisibility(View.VISIBLE);
271 | pb_refresh.setVisibility(View.GONE);
272 | tv_time.setVisibility(View.VISIBLE);
273 | tv_title.setVisibility(View.VISIBLE);
274 | iv_arrow.clearAnimation();
275 | mHeader.setPadding(0, -mHeaderHeight, 0, 0);
276 | } else if (mState == State.PULL_TO_REFRESH) {
277 | iv_arrow.setVisibility(View.VISIBLE);
278 | pb_refresh.setVisibility(View.GONE);
279 | tv_title.setVisibility(View.VISIBLE);
280 | tv_time.setVisibility(View.VISIBLE);
281 |
282 | iv_arrow.clearAnimation();
283 | tv_title.setText(getResources().getString(R.string.pull_refresh));
284 |
285 | if (isBack) {
286 | // Come from release to refresh to pull to refresh
287 | iv_arrow.startAnimation(animation);
288 | isBack = false;
289 | }
290 | } else if (mState == State.RELEASE_TO_REFRESH) {
291 | iv_arrow.setVisibility(View.VISIBLE);
292 | pb_refresh.setVisibility(View.GONE);
293 | tv_title.setVisibility(View.VISIBLE);
294 | tv_time.setVisibility(View.VISIBLE);
295 |
296 | iv_arrow.clearAnimation();
297 | tv_time.setText(getResources().getString(R.string.release_to_refresh));
298 |
299 | iv_arrow.startAnimation(reverseAnimation);
300 | } else if (mState == State.REFRESHING) {
301 | iv_arrow.setVisibility(View.GONE);
302 | pb_refresh.setVisibility(View.VISIBLE);
303 | tv_title.setVisibility(View.VISIBLE);
304 | tv_time.setVisibility(View.VISIBLE);
305 |
306 | iv_arrow.clearAnimation();
307 | tv_title.setText(getResources().getString(R.string.refreshing));
308 |
309 | mHeader.setPadding(0, 0, 0, 0);
310 |
311 | if (mOnRefreshListener != null) {
312 | mOnRefreshListener.onRefresh();
313 | }
314 | }
315 |
316 | }
317 |
318 | /**
319 | * When complete refresh data, you must use this method to hide the header view, if not the header view will be
320 | * shown all the time.
321 | */
322 | @SuppressWarnings("deprecation")
323 | public void onRefreshComplete() {
324 | mState = State.ORIGNAL;
325 | changeState();
326 | tv_time.setText(getResources().getString(R.string.update_time) + new Date().toLocaleString());
327 | }
328 |
329 | @SuppressWarnings("deprecation")
330 | @Override
331 | public void setAdapter(ListAdapter adapter) {
332 | tv_time.setText(getResources().getString(R.string.update_time) + new Date().toLocaleString());
333 | super.setAdapter(adapter);
334 | }
335 |
336 | @Override
337 | public void setOnScrollListener(OnScrollListener l) {
338 | this.mOnScrollListener = l;
339 | }
340 |
341 | /**
342 | * Set refresh data listener.
343 | *
344 | * @param listener OnRefreshListener
345 | */
346 | public void setOnRefreshListener(OnRefreshListener listener) {
347 | this.mOnRefreshListener = listener;
348 | }
349 |
350 | /**
351 | * All the state of ListView
352 | */
353 | public enum State {
354 | ORIGNAL, PULL_TO_REFRESH, REFRESHING, RELEASE_TO_REFRESH;
355 | }
356 |
357 | /**
358 | * Interface when refresh data.
359 | */
360 | public interface OnRefreshListener {
361 | abstract void onRefresh();
362 | }
363 |
364 | }
365 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | PullToRefreshListViewDemo
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-20
15 | android.library.reference.1=../PullToRefreshListView
16 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListViewDemo/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListViewDemo/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListViewDemo/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/PullToRefreshListViewDemo/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/layout/activity_loadmore.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/layout/activity_loadmoregrid.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
27 |
28 |
29 |
39 |
40 |
44 |
45 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
12 |
13 |
19 |
20 |
26 |
27 |
33 |
34 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/layout/activity_pull_and_loadmore.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/layout/activity_pulltorefresh.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values-en/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PullToRefreshListViewDemo
5 | Settings
6 | Hello world!
7 | Pull To Refresh
8 | Load More
9 | Both
10 |
11 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PullToRefreshListViewDemo
5 | Settings
6 | Hello world!
7 | 下拉刷新
8 | 加载更多
9 | 二合一
10 | 自动加载GridView
11 |
12 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/src/com/charon/pulltorefresh/demo/LoadMoreActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.pulltorefresh.demo;
2 |
3 | import java.util.Arrays;
4 | import java.util.LinkedList;
5 |
6 | import android.app.Activity;
7 | import android.os.AsyncTask;
8 | import android.os.Bundle;
9 | import android.os.SystemClock;
10 | import android.view.Gravity;
11 | import android.view.View;
12 | import android.view.ViewGroup;
13 | import android.widget.BaseAdapter;
14 | import android.widget.TextView;
15 |
16 | import com.charon.pulltorefreshlistview.LoadMoreListView;
17 | import com.charon.pulltorefreshlistview.LoadMoreListView.OnLoadMoreListener;
18 |
19 | public class LoadMoreActivity extends Activity {
20 | private LoadMoreListView mLoadMoreListView;
21 | private String[] mNames = { "Fabian", "Carlos", "Alex", "Andrea", "Karla",
22 | "Freddy", "Lazaro", "Hector", "Carolina", "Edwin", "Jhon",
23 | "Edelmira", "Andres" };
24 | private LinkedList mListItems;
25 |
26 | @Override
27 | protected void onCreate(Bundle savedInstanceState) {
28 | super.onCreate(savedInstanceState);
29 | setContentView(R.layout.activity_loadmore);
30 | findView();
31 | initView();
32 | }
33 |
34 | private void findView() {
35 | mLoadMoreListView = (LoadMoreListView) findViewById(R.id.lmlv);
36 | }
37 |
38 | private void initView() {
39 | mListItems = new LinkedList();
40 | mListItems.addAll(Arrays.asList(mNames));
41 |
42 | mLoadMoreListView.setAdapter(adapter);
43 |
44 | mLoadMoreListView.setOnLoadMoreListener(new OnLoadMoreListener() {
45 |
46 | @Override
47 | public void onLoadMore() {
48 | new LoadDataTask().execute();
49 | }
50 | });
51 | }
52 |
53 | private BaseAdapter adapter = new BaseAdapter() {
54 |
55 | @Override
56 | public int getCount() {
57 | return mListItems.size();
58 | }
59 |
60 | @Override
61 | public Object getItem(int position) {
62 | return position;
63 | }
64 |
65 | @Override
66 | public long getItemId(int position) {
67 | return position;
68 | }
69 |
70 | @Override
71 | public View getView(int position, View convertView, ViewGroup parent) {
72 | TextView view = new TextView(LoadMoreActivity.this);
73 | view.setTextSize(20);
74 | view.setHeight(100);
75 | view.setGravity(Gravity.CENTER_VERTICAL);
76 | view.setText(mListItems.get(position));
77 | return view;
78 | }
79 |
80 | };
81 |
82 | private class LoadDataTask extends AsyncTask {
83 |
84 | @Override
85 | protected Void doInBackground(Void... params) {
86 |
87 | if (isCancelled()) {
88 | return null;
89 | }
90 |
91 | SystemClock.sleep(1000);
92 |
93 | mListItems.add("Load More...........");
94 |
95 | return null;
96 | }
97 |
98 | @Override
99 | protected void onPostExecute(Void result) {
100 | adapter.notifyDataSetChanged();
101 |
102 | mLoadMoreListView.onLoadMoreComplete();
103 |
104 | super.onPostExecute(result);
105 | }
106 |
107 | @Override
108 | protected void onCancelled() {
109 | mLoadMoreListView.onLoadMoreComplete();
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/src/com/charon/pulltorefresh/demo/LoadMoreGridActivity.java:
--------------------------------------------------------------------------------
1 |
2 | package com.charon.pulltorefresh.demo;
3 |
4 | import java.util.Arrays;
5 | import java.util.LinkedList;
6 |
7 | import android.app.Activity;
8 | import android.os.AsyncTask;
9 | import android.os.Bundle;
10 | import android.os.SystemClock;
11 | import android.view.Gravity;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.BaseAdapter;
15 | import android.widget.TextView;
16 |
17 | import com.charon.pulltorefreshlistview.LoadMoreGridView;
18 | import com.charon.pulltorefreshlistview.LoadMoreGridView.OnLoadMoreListener;
19 |
20 | public class LoadMoreGridActivity extends Activity {
21 | private LoadMoreGridView mGridView;
22 | private View mAutoLoadView;
23 | private String[] mNames = {
24 | "Fabian", "Carlos", "Alex", "Andrea", "Karla",
25 | "Freddy", "Lazaro", "Hector", "Carolina", "Edwin", "Jhon",
26 | "Edelmira", "Andres", "Fabian", "Carlos", "Alex", "Andrea", "Karla",
27 | "Freddy", "Lazaro", "Hector", "Carolina", "Edwin", "Jhon",
28 | "Edelmira", "Andres"
29 | };
30 | private LinkedList mListItems;
31 |
32 | @Override
33 | protected void onCreate(Bundle savedInstanceState) {
34 | super.onCreate(savedInstanceState);
35 | setContentView(R.layout.activity_loadmoregrid);
36 | findView();
37 | initView();
38 | }
39 |
40 | private void findView() {
41 | mGridView = (LoadMoreGridView) findViewById(R.id.lmgv);
42 | mAutoLoadView = findViewById(R.id.auto_load_view);
43 | }
44 |
45 | private void initView() {
46 | mListItems = new LinkedList();
47 | mListItems.addAll(Arrays.asList(mNames));
48 |
49 | mGridView.setAdapter(adapter);
50 |
51 | mGridView.setOnLoadMoreListener(new OnLoadMoreListener() {
52 |
53 | @Override
54 | public void onLoadMore() {
55 | new LoadDataTask().execute();
56 | }
57 | });
58 | }
59 |
60 | private BaseAdapter adapter = new BaseAdapter() {
61 |
62 | @Override
63 | public int getCount() {
64 | return mListItems.size();
65 | }
66 |
67 | @Override
68 | public Object getItem(int position) {
69 | return position;
70 | }
71 |
72 | @Override
73 | public long getItemId(int position) {
74 | return position;
75 | }
76 |
77 | @Override
78 | public View getView(int position, View convertView, ViewGroup parent) {
79 | TextView view = new TextView(LoadMoreGridActivity.this);
80 | view.setTextSize(20);
81 | view.setHeight(100);
82 | view.setGravity(Gravity.CENTER_VERTICAL);
83 | view.setText(mListItems.get(position));
84 | return view;
85 | }
86 |
87 | };
88 |
89 | private class LoadDataTask extends AsyncTask {
90 |
91 | @Override
92 | protected Void doInBackground(Void... params) {
93 | if (isCancelled()) {
94 | return null;
95 | }
96 | SystemClock.sleep(1000);
97 | mListItems.add("Load More...........");
98 | mListItems.add("Load More...........");
99 | return null;
100 | }
101 |
102 | @Override
103 | protected void onPostExecute(Void result) {
104 | if (mAutoLoadView != null) {
105 | mAutoLoadView.setVisibility(View.GONE);
106 | }
107 | adapter.notifyDataSetChanged();
108 | mGridView.onLoadMoreComplete();
109 | super.onPostExecute(result);
110 | }
111 |
112 | @Override
113 | protected void onPreExecute() {
114 | if (mAutoLoadView != null) {
115 | mAutoLoadView.setVisibility(View.VISIBLE);
116 | }
117 | super.onPreExecute();
118 | }
119 |
120 | @Override
121 | protected void onCancelled() {
122 | mGridView.onLoadMoreComplete();
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/src/com/charon/pulltorefresh/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 |
2 | package com.charon.pulltorefresh.demo;
3 |
4 | import android.app.Activity;
5 | import android.content.Intent;
6 | import android.os.Bundle;
7 | import android.view.View;
8 | import android.view.View.OnClickListener;
9 | import android.widget.Button;
10 |
11 | public class MainActivity extends Activity implements OnClickListener {
12 | private Button bt_pull_to_refresh;
13 | private Button bt_load_more;
14 | private Button bt_pull_and_loadmore;
15 | private Button bt_pull_loadmore_grid;
16 |
17 | @Override
18 | protected void onCreate(Bundle savedInstanceState) {
19 | super.onCreate(savedInstanceState);
20 | setContentView(R.layout.activity_main);
21 | findView();
22 | }
23 |
24 | private void findView() {
25 | bt_pull_to_refresh = (Button) findViewById(R.id.bt_pull_to_refresh);
26 | bt_load_more = (Button) findViewById(R.id.bt_load_more);
27 | bt_pull_and_loadmore = (Button) findViewById(R.id.bt_pull_and_loadmore);
28 | bt_pull_to_refresh.setOnClickListener(this);
29 | bt_load_more.setOnClickListener(this);
30 | bt_pull_and_loadmore.setOnClickListener(this);
31 | bt_pull_loadmore_grid = (Button) findViewById(R.id.bt_pull_loadmore_grid);
32 | bt_pull_loadmore_grid.setOnClickListener(this);
33 | }
34 |
35 | @Override
36 | public void onClick(View v) {
37 | switch (v.getId()) {
38 | case R.id.bt_pull_to_refresh:
39 | startActivity(new Intent(this, PullToRefreshActivity.class));
40 | break;
41 | case R.id.bt_load_more:
42 | startActivity(new Intent(this, LoadMoreActivity.class));
43 | break;
44 | case R.id.bt_pull_and_loadmore:
45 | startActivity(new Intent(this, PullAndLoadMoreActivity.class));
46 | break;
47 | case R.id.bt_pull_loadmore_grid:
48 | startActivity(new Intent(this, LoadMoreGridActivity.class));
49 | break;
50 |
51 | default:
52 | break;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/src/com/charon/pulltorefresh/demo/PullAndLoadMoreActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.pulltorefresh.demo;
2 |
3 | import java.util.Arrays;
4 | import java.util.LinkedList;
5 |
6 | import android.app.Activity;
7 | import android.os.AsyncTask;
8 | import android.os.Bundle;
9 | import android.os.SystemClock;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.AdapterView;
13 | import android.widget.BaseAdapter;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 | import android.widget.AdapterView.OnItemClickListener;
17 |
18 | import com.charon.pulltorefreshlistview.PullRefreshAndLoadMoreListView;
19 | import com.charon.pulltorefreshlistview.PullRefreshAndLoadMoreListView.OnLoadMoreListener;
20 | import com.charon.pulltorefreshlistview.PullToRefreshListView.OnRefreshListener;
21 |
22 | public class PullAndLoadMoreActivity extends Activity {
23 | private PullRefreshAndLoadMoreListView mPullRefreshAndLoadMoreListView;
24 | private MyAdapter adapter;
25 |
26 | private String[] mNames = { "Fabian", "Carlos", "Alex", "Andrea", "Karla",
27 | "Freddy", "Lazaro", "Hector", "Carolina", "Edwin", "Jhon",
28 | "Edelmira", "Andres", "Fabian", "Carlos", "Alex", "Andrea", "Karla",
29 | "Freddy", "Lazaro", "Hector", "Carolina", "Edwin", "Jhon",
30 | "Edelmira", "Andres" };
31 | private LinkedList mListItems;
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_pull_and_loadmore);
37 | findView();
38 | initView();
39 | }
40 |
41 | private void findView() {
42 | mPullRefreshAndLoadMoreListView = (PullRefreshAndLoadMoreListView) findViewById(R.id.palmlv);
43 | }
44 |
45 | private void initView() {
46 | mListItems = new LinkedList();
47 | mListItems.addAll(Arrays.asList(mNames));
48 |
49 | adapter = new MyAdapter();
50 | mPullRefreshAndLoadMoreListView.setAdapter(adapter);
51 |
52 | mPullRefreshAndLoadMoreListView
53 | .setOnRefreshListener(new OnRefreshListener() {
54 |
55 | @Override
56 | public void onRefresh() {
57 | new AsyncTask() {
58 |
59 | @Override
60 | protected Void doInBackground(Void... params) {
61 | SystemClock.sleep(1000);
62 | mListItems.add("add after refresh");
63 | return null;
64 | }
65 |
66 | @Override
67 | protected void onPostExecute(Void result) {
68 | super.onPostExecute(result);
69 | adapter.notifyDataSetChanged();
70 | mPullRefreshAndLoadMoreListView
71 | .onRefreshComplete();
72 | }
73 | }.execute();
74 | }
75 | });
76 |
77 | mPullRefreshAndLoadMoreListView
78 | .setOnLoadMoreListener(new OnLoadMoreListener() {
79 |
80 | @Override
81 | public void onLoadMore() {
82 | new LoadDataTask().execute();
83 | }
84 | });
85 |
86 | mPullRefreshAndLoadMoreListView
87 | .setOnItemClickListener(new OnItemClickListener() {
88 |
89 | @Override
90 | public void onItemClick(AdapterView> parent, View view,
91 | int position, long id) {
92 | // If you call addHeaderView, the position will contains
93 | // the count of header view.
94 | // int realPosition = position
95 | // -
96 | // mPullRefreshAndLoadMoreListView.getHeaderViewsCount();
97 | // Toast.makeText(PullAndLoadMoreActivity.this,
98 | // mListItems.get(realPosition),
99 | // Toast.LENGTH_SHORT).show();
100 |
101 | Toast.makeText(
102 | PullAndLoadMoreActivity.this,
103 | (String) mPullRefreshAndLoadMoreListView
104 | .getAdapter().getItem(position),
105 | Toast.LENGTH_SHORT).show();
106 |
107 | }
108 |
109 | });
110 |
111 | }
112 |
113 | private class MyAdapter extends BaseAdapter {
114 |
115 | @Override
116 | public int getCount() {
117 | return mListItems.size();
118 | }
119 |
120 | @Override
121 | public Object getItem(int position) {
122 | return mListItems.get(position);
123 | }
124 |
125 | @Override
126 | public long getItemId(int position) {
127 | return position;
128 | }
129 |
130 | @Override
131 | public View getView(int position, View convertView, ViewGroup parent) {
132 | TextView textView = new TextView(getApplicationContext());
133 | textView.setTextSize(20);
134 | textView.setText(mListItems.get(position));
135 |
136 | return textView;
137 | }
138 | }
139 |
140 | private class LoadDataTask extends AsyncTask {
141 |
142 | @Override
143 | protected Void doInBackground(Void... params) {
144 |
145 | if (isCancelled()) {
146 | return null;
147 | }
148 |
149 | SystemClock.sleep(1000);
150 |
151 | mListItems.add("Load More....");
152 | return null;
153 | }
154 |
155 | @Override
156 | protected void onPostExecute(Void result) {
157 | adapter.notifyDataSetChanged();
158 |
159 | mPullRefreshAndLoadMoreListView.onLoadMoreComplete();
160 |
161 | super.onPostExecute(result);
162 | }
163 |
164 | @Override
165 | protected void onCancelled() {
166 | mPullRefreshAndLoadMoreListView.onLoadMoreComplete();
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/PullToRefreshListViewDemo/src/com/charon/pulltorefresh/demo/PullToRefreshActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.pulltorefresh.demo;
2 |
3 | import java.util.ArrayList;
4 |
5 | import android.app.Activity;
6 | import android.os.AsyncTask;
7 | import android.os.Bundle;
8 | import android.os.SystemClock;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.AdapterView;
12 | import android.widget.AdapterView.OnItemClickListener;
13 | import android.widget.BaseAdapter;
14 | import android.widget.TextView;
15 | import android.widget.Toast;
16 |
17 | import com.charon.pulltorefreshlistview.PullToRefreshListView;
18 | import com.charon.pulltorefreshlistview.PullToRefreshListView.OnRefreshListener;
19 |
20 | public class PullToRefreshActivity extends Activity {
21 | private PullToRefreshListView mPullToRefreshListView;
22 | private MyAdapter adapter;
23 | private ArrayList data;
24 |
25 | @Override
26 | protected void onCreate(Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView(R.layout.activity_pulltorefresh);
29 | findView();
30 | initView();
31 | }
32 |
33 | private void findView() {
34 | mPullToRefreshListView = (PullToRefreshListView) findViewById(R.id.ptlv);
35 | }
36 |
37 | private void initView() {
38 |
39 | data = new ArrayList();
40 | data.add("a");
41 | data.add("b");
42 | data.add("c");
43 |
44 | adapter = new MyAdapter();
45 |
46 | mPullToRefreshListView.setAdapter(adapter);
47 |
48 | mPullToRefreshListView.setOnRefreshListener(new OnRefreshListener() {
49 |
50 | @Override
51 | public void onRefresh() {
52 | new AsyncTask() {
53 |
54 | @Override
55 | protected Void doInBackground(Void... params) {
56 | SystemClock.sleep(1000);
57 | data.add("add after refresh");
58 | return null;
59 | }
60 |
61 | @Override
62 | protected void onPostExecute(Void result) {
63 | super.onPostExecute(result);
64 | adapter.notifyDataSetChanged();
65 | mPullToRefreshListView.onRefreshComplete();
66 | }
67 | }.execute();
68 | }
69 | });
70 |
71 | mPullToRefreshListView
72 | .setOnItemClickListener(new OnItemClickListener() {
73 |
74 | @Override
75 | public void onItemClick(AdapterView> parent, View view,
76 | int position, long id) {
77 | // If you call addHeaderView, the position will contains
78 | // the count of header view.
79 | // int realPosition = position
80 | // - mPullToRefreshListView.getHeaderViewsCount();
81 | // Toast.makeText(PullToRefreshActivity.this,
82 | // data.get(realPosition), Toast.LENGTH_SHORT).show();
83 |
84 | Toast.makeText(
85 | PullToRefreshActivity.this,
86 | (String) mPullToRefreshListView.getAdapter()
87 | .getItem(position), Toast.LENGTH_SHORT)
88 | .show();
89 |
90 | }
91 |
92 | });
93 |
94 | }
95 |
96 | private class MyAdapter extends BaseAdapter {
97 |
98 | @Override
99 | public int getCount() {
100 | return data.size();
101 | }
102 |
103 | @Override
104 | public Object getItem(int position) {
105 | return data.get(position);
106 | }
107 |
108 | @Override
109 | public long getItemId(int position) {
110 | return position;
111 | }
112 |
113 | @Override
114 | public View getView(int position, View convertView, ViewGroup parent) {
115 | TextView textView = new TextView(getApplicationContext());
116 | textView.setTextSize(20);
117 | textView.setText(data.get(position));
118 |
119 | return textView;
120 | }
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PullRefresh-SlidingMenu
2 | ===
3 |
4 | Bundle contains PullToRefreshListView、 SlidingMenu、 ScrollingTabs.
5 |
6 |
7 | PullToRefreshListView
8 | ===
9 |
10 | A customizable ListView implementation that has 'Pull to Refresh' functionality. This ListView can be used as a replacement of the normal Android android.widget.ListView class.
11 |
12 | 
13 |
14 | Usage
15 | ---
16 |
17 | Check out the [example project](https://github.com/CharonChui/PullToRefreshListView)
18 | in this repository for an implementation example.
19 |
20 | 1. Use PullToRefreshListView in your layout
21 | ```xml
22 |
26 | ```
27 |
28 | 2. Setup in your Activity
29 | ```java
30 | mPullToRefreshListView = (PullToRefreshListView) findViewById(R.id.ptlv);
31 | mPullToRefreshListView.setAdapter(adapter);
32 | mPullToRefreshListView.setOnRefreshListener(new OnRefreshListener() {
33 |
34 | @Override
35 | public void onRefresh() {
36 | new AsyncTask() {
37 |
38 | @Override
39 | protected Void doInBackground(Void... params) {
40 | //TODO Refresh data.
41 | return null;
42 | }
43 |
44 | @Override
45 | protected void onPostExecute(Void result) {
46 | super.onPostExecute(result);
47 | adapter.notifyDataSetChanged();
48 | //Do not forget use this method after refreshed data.
49 | mPullToRefreshListView.onRefreshComplete();
50 |
51 | }
52 | });
53 | ```
54 |
55 | SlidingMenu
56 | ===
57 |
58 | SlidingMenu with left and right menu,This is an original component demo, does not rely on any third-party lib library.
59 |
60 | 
61 |
62 | Usage
63 | ===
64 |
65 | 1. Include the SlidingMenu widget in your view.
66 |
67 | ```xml
68 |
72 |
73 | ```
74 |
75 | 2. In your `onCreate` method (or `onCreateView` for a fragment), bind the widget to the `SlidingMenu`.
76 |
77 | ```java
78 | mSlidingMenu = (SlidingMenu) findViewById(R.id.sm);
79 |
80 | //prepare three view for the slidingmenu
81 | View leftView = View.inflate(this, R.layout.frame_left, null);
82 | View rightView = View.inflate(this, R.layout.frame_right, null);
83 | View centerView = View.inflate(this, R.layout.frame_center, null);
84 |
85 | //add the three view to SlidingMenu
86 | mSlidingMenu.setView(leftView, rightView, centerView, 200, 250);
87 |
88 | //replace the three view by three fragment
89 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
90 | mLeftFragment = new LeftFragment();
91 | transaction.replace(R.id.fl_left, mLeftFragment);
92 | mRightFragment = new RightFragment();
93 | transaction.replace(R.id.fl_right, mRightFragment);
94 | mCenterFragment = new CenterFragment();
95 | transaction.replace(R.id.fl_center, mCenterFragment);
96 | transaction.commit();
97 |
98 | //set which side can show of SlidingMenu use the interface made by
99 | mCenterFragment.setOnViewPagerChangeListener(new OnViewPagerChangeListener() {
100 |
101 | @Override
102 | public void onPageChage(int position) {
103 | if (mCenterFragment.isFirst()) {
104 | mSlidingMenu.setWhichSideCanShow(true, false);
105 | } else if (mCenterFragment.isLast()) {
106 | mSlidingMenu.setWhichSideCanShow(false, true);
107 | } else {
108 | mSlidingMenu.setWhichSideCanShow(false, false);
109 | }
110 | }
111 | });
112 |
113 | //make two method for CenterFragment to use
114 | public void showLeftViewToogle() {
115 | mSlidingMenu.showLeftViewToogle();
116 | }
117 |
118 | public void showRightViewToogle() {
119 | mSlidingMenu.showRightViewToogle();
120 | }
121 | ```
122 |
123 |
124 | ScrollingTabs
125 | ===
126 |
127 | Interactive paging indicator widget, compatible with the ViewPager from the Android Support Library.
128 |
129 | 
130 |
131 | Usage
132 | ===
133 |
134 | 1. Include the ScrollingTabsView widget in your view. This should usually be placed adjacent to the `ViewPager` it represents.
135 |
136 | ```java
137 |
141 |
142 |
146 |
147 |
148 |
152 |
153 |
154 |
155 | ```
156 |
157 | 2. In your `onCreate` method (or `onCreateView` for a fragment), bind the widget to the `ViewPager`.
158 |
159 | ```java
160 | // Set the pager with an adapter
161 | mViewPager = (ViewPager) findViewById(R.id.vp);
162 |
163 | mViewPager.setAdapter(new TestAdapter(getSupportFragmentManager()));
164 |
165 | // Bind the widget to the adapter
166 | mScrollingTabsView = (ScrollingTabsView) findViewById(R.id.stv);
167 | mScrollingTabsView.setViewPager(mViewPager);
168 | mScrollingTabsView.setTabAdapter(new MyTabAdapter());
169 | ```
170 |
171 | SimpleApp
172 | ===
173 |
174 | SimpleApp using this three projects and [AndroidDevelopFramework](https://github.com/CharonChui/AndroidDevelopFramework)
175 |
176 | 
177 |
178 |
179 | Developed By
180 | ===
181 |
182 | * Charon Chui -
183 |
184 |
185 | License
186 | ===
187 |
188 | Copyright (C) 2013 Charon Chui
189 |
190 | Licensed under the Apache License, Version 2.0 (the "License");
191 | you may not use this file except in compliance with the License.
192 | You may obtain a copy of the License at
193 |
194 | http://www.apache.org/licenses/LICENSE-2.0
195 |
196 | Unless required by applicable law or agreed to in writing, software
197 | distributed under the License is distributed on an "AS IS" BASIS,
198 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199 | See the License for the specific language governing permissions and
200 | limitations under the License.
201 |
--------------------------------------------------------------------------------
/README_ScrollingTabs.md:
--------------------------------------------------------------------------------
1 | ScrollingTabs
2 | ===
3 |
4 | Interactive paging indicator widget, compatible with the ViewPager from the Android Support Library.
5 |
6 | Usage
7 | ===
8 | 1. Include the ScrollingTabsView widget in your view. This should usually be placed
9 | adjacent to the `ViewPager` it represents.
10 |
11 |
12 |
16 |
17 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 | 2. In your `onCreate` method (or `onCreateView` for a fragment), bind the
32 | widget to the `ViewPager`.
33 |
34 | // Set the pager with an adapter
35 | mViewPager = (ViewPager) findViewById(R.id.vp);
36 |
37 | mViewPager.setAdapter(new TestAdapter(getSupportFragmentManager()));
38 |
39 | // Bind the widget to the adapter
40 | mScrollingTabsView = (ScrollingTabsView) findViewById(R.id.stv);
41 | mScrollingTabsView.setViewPager(mViewPager);
42 | mScrollingTabsView.setTabAdapter(new MyTabAdapter());
43 |
44 |
45 |
46 | Developed By
47 | ============
48 |
49 | * Charon Chui -
50 |
51 |
52 | License
53 | =======
54 |
55 | Copyright (C) 2013 Charon Chui
56 |
57 | Licensed under the Apache License, Version 2.0 (the "License");
58 | you may not use this file except in compliance with the License.
59 | You may obtain a copy of the License at
60 |
61 | http://www.apache.org/licenses/LICENSE-2.0
62 |
63 | Unless required by applicable law or agreed to in writing, software
64 | distributed under the License is distributed on an "AS IS" BASIS,
65 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66 | See the License for the specific language governing permissions and
67 | limitations under the License.
68 |
--------------------------------------------------------------------------------
/README_SlidingMenu.md:
--------------------------------------------------------------------------------
1 | SlidingMenu
2 | ===
3 |
4 | SlidingMenu with left and right menu,This is an original component demo, does not rely on any third-party lib library.
5 |
6 | Usage
7 | ===
8 | 1. Include the SlidingMenu widget in your view.
9 | ```xml
10 |
14 |
15 |
16 | ```
17 | 2. In your `onCreate` method (or `onCreateView` for a fragment), bind the
18 | widget to the `SlidingMenu`.
19 |
20 | mSlidingMenu = (SlidingMenu) findViewById(R.id.sm);
21 |
22 | //prepare three view for the slidingmenu
23 | View leftView = View.inflate(this, R.layout.frame_left, null);
24 | View rightView = View.inflate(this, R.layout.frame_right, null);
25 | View centerView = View.inflate(this, R.layout.frame_center, null);
26 |
27 | //add the three view to SlidingMenu
28 | mSlidingMenu.setView(leftView, rightView, centerView, 200, 250);
29 |
30 | //replace the three view by three fragment
31 | FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
32 | mLeftFragment = new LeftFragment();
33 | transaction.replace(R.id.fl_left, mLeftFragment);
34 | mRightFragment = new RightFragment();
35 | transaction.replace(R.id.fl_right, mRightFragment);
36 | mCenterFragment = new CenterFragment();
37 | transaction.replace(R.id.fl_center, mCenterFragment);
38 | transaction.commit();
39 |
40 | //set which side can show of SlidingMenu use the interface made by
41 | mCenterFragment.setOnViewPagerChangeListener(new OnViewPagerChangeListener() {
42 |
43 | @Override
44 | public void onPageChage(int position) {
45 | if (mCenterFragment.isFirst()) {
46 | mSlidingMenu.setWhichSideCanShow(true, false);
47 | } else if (mCenterFragment.isLast()) {
48 | mSlidingMenu.setWhichSideCanShow(false, true);
49 | } else {
50 | mSlidingMenu.setWhichSideCanShow(false, false);
51 | }
52 | }
53 | });
54 |
55 | //make two method for CenterFragment to use
56 | public void showLeftViewToogle() {
57 | mSlidingMenu.showLeftViewToogle();
58 | }
59 |
60 | public void showRightViewToogle() {
61 | mSlidingMenu.showRightViewToogle();
62 | }
63 |
64 |
65 |
66 |
67 | Developed By
68 | ============
69 |
70 | * Charon Chui -
71 |
72 |
73 | License
74 | =======
75 |
76 | Copyright (C) 2013 Charon Chui
77 |
78 | Licensed under the Apache License, Version 2.0 (the "License");
79 | you may not use this file except in compliance with the License.
80 | You may obtain a copy of the License at
81 |
82 | http://www.apache.org/licenses/LICENSE-2.0
83 |
84 | Unless required by applicable law or agreed to in writing, software
85 | distributed under the License is distributed on an "AS IS" BASIS,
86 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
87 | See the License for the specific language governing permissions and
88 | limitations under the License.
89 |
--------------------------------------------------------------------------------
/ScrollingTabs.md:
--------------------------------------------------------------------------------
1 | ScrollingTabs
2 | ===
3 |
4 | 自定义ScrollingTabs结合ViewPager实现指引的效果。
5 | 
6 | **原理:**
7 | 由于`ScrollingTabs`即可以点击又可以实现左右滑动,首先想到的就是继承`HorizontalScrollView`来实现滑动,至于点击的实现需要通过对`View`
8 | 设置点击。
9 | 通过对`ViewPager`设置`OnPageChangeListener`来监听页面变化,从而实现对`ScrollingTabs`的改变,而在每个`Tab`上设置
10 | 点击事件,当点击的时候就去设置`ViewPager`的当前页面
11 |
12 | 1. 继承HorizontalScrollView,并且添加一个水平方向的线性布局,作为Tab的父布局
13 | ```java
14 | public class ScrollingTabs extends HorizontalScrollView {
15 |
16 | private LinearLayout mContainer;
17 |
18 | public ScrollingTabs(Context context, AttributeSet attrs, int defStyle) {
19 | super(context, attrs, defStyle);
20 | init(context);
21 | }
22 |
23 | public ScrollingTabs(Context context, AttributeSet attrs) {
24 | super(context, attrs);
25 | init(context);
26 | }
27 |
28 | public ScrollingTabs(Context context) {
29 | super(context);
30 | init(context);
31 | }
32 |
33 | private void init(Context context) {
34 | this.setHorizontalScrollBarEnabled(false);
35 | this.setHorizontalFadingEdgeEnabled(false);
36 |
37 | mContainer = new LinearLayout(context);
38 | LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
39 | android.view.ViewGroup.LayoutParams.MATCH_PARENT,
40 | android.view.ViewGroup.LayoutParams.MATCH_PARENT);
41 | mContainer.setLayoutParams(params);
42 | mContainer.setOrientation(LinearLayout.HORIZONTAL);
43 |
44 | addView(mContainer);
45 | }
46 | ```
47 |
48 | 2. 提供接口供调用者设置每个Tab的视图。
49 | ```java
50 | public interface TabAdapter {
51 | /**
52 | * 每个Tab的视图
53 | */
54 | public View getView(int position);
55 | /**
56 | * Tab之间的分割线
57 | */
58 | public View getSeparator();
59 | }
60 | ```
61 | 3. 暴露方法,初始化Tab。
62 | ```java
63 | public void setTabAdapter(TabAdapter adapter) {
64 | this.mTabAdapter = adapter;
65 | initTabView();
66 | }
67 |
68 | public void setViewPager(ViewPager pager) {
69 | this.mViewPager = pager;
70 | mViewPager.setOnPageChangeListener(this);
71 | initTabView();
72 | }
73 |
74 | /**
75 | * 必须等到ViewPager和TabAdapter都设置完成后才可以调用
76 | */
77 | private void initTabView() {
78 | if (mViewPager != null && mTabAdapter != null) {
79 | //清空父布局,保险起见
80 | mContainer.removeAllViews();
81 | //根据ViewPager的页数去设置Tab
82 | for (int i = 0; i < mViewPager.getAdapter().getCount(); i++) {
83 | final View tab = mTabAdapter.getView(i);
84 | tab.setTag(i);
85 |
86 | mContainer.addView(tab);
87 |
88 | // Segmentation view
89 | if (mTabAdapter.getSeparator() != null
90 | && i != mViewPager.getAdapter().getCount() - 1) {
91 | //Tabs之间使用分割线
92 | isUseSeperator = true;
93 | mContainer.addView(mTabAdapter.getSeparator());
94 | }
95 |
96 | // 对每个Tab设置点击事件
97 | tab.setOnClickListener(new OnClickListener() {
98 |
99 | @Override
100 | public void onClick(View v) {
101 | int index = (Integer) tab.getTag();
102 | if (mTabClickListener != null) {
103 | //暴露接口
104 | mTabClickListener.onClick(index);
105 | } else {
106 | if (mViewPager.getCurrentItem() == index) {
107 | //如果当前ViewPager已经显示到了该Tab也,就直接让其选中
108 | selectTab(index);
109 | } else {
110 | //当前ViewPager并没有显示该Tab页,要让ViewPager去显示相应的Tab页
111 | mViewPager.setCurrentItem(index, true);
112 | }
113 | }
114 | }
115 | });
116 |
117 | }
118 |
119 | // 初始化时核对一下Tab
120 | selectTab(mViewPager.getCurrentItem());
121 | }
122 | }
123 | ```
124 | 4. selectTab的实现,选中相应的Tab,并且实现滑动到屏幕中间位置
125 | ```java
126 | private void selectTab(int position) {
127 | if (!isUseSeperator) {
128 | //没有分割线
129 | for (int i = 0; i < mContainer.getChildCount(); i++) {
130 | View tab = mContainer.getChildAt(i);
131 | tab.setSelected(i == position);
132 | }
133 | } else {
134 | //有分割线
135 | for (int i = 0, pos = 0; i < mContainer.getChildCount(); i += 2, pos++) {
136 | View tab = mContainer.getChildAt(i);
137 | tab.setSelected(pos == position);
138 | }
139 | }
140 | //得到当前的Tab
141 | View selectedView = null;
142 | if (!isUseSeperator) {
143 | selectedView = mContainer.getChildAt(position);
144 | } else {
145 | selectedView = mContainer.getChildAt(position * 2);
146 | }
147 |
148 | int tabWidth = selectedView.getMeasuredWidth();
149 | int tabLeft = selectedView.getLeft();
150 |
151 | //距离左边屏幕的位置加上该Tab宽度的一半正好是该Tab中心点的位置。我们需要让该Tab的中心点移动到屏幕的中心点。
152 | int distance = (tabLeft + tabWidth / 2) - mWindowWidth / 2;
153 | //移动
154 | smoothScrollTo(distance, this.getScrollY());
155 | }
156 | ```
157 |
158 | ------------------------------------------
159 |
160 | - 邮箱 :charon.chui@gmail.com
161 | - Good Luck!
162 |
--------------------------------------------------------------------------------
/ScrollingTabs/.gitignore:
--------------------------------------------------------------------------------
1 | /gen
2 | /assets
3 | /bin
4 |
--------------------------------------------------------------------------------
/ScrollingTabs/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ScrollingTabs
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ScrollingTabs/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/ScrollingTabs/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabs/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/ScrollingTabs/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-22
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/ScrollingTabs/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabs/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ScrollingTabs/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabs/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ScrollingTabs/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabs/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ScrollingTabs/res/drawable/triangle.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ScrollingTabs/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ScrollingTabs/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ScrollingTabs/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ScrollingTabs/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ScrollingTabs/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ScrollingTabs
5 |
6 |
--------------------------------------------------------------------------------
/ScrollingTabs/src/com/charon/scrollingtabs/view/TriangleScrollingTabs.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2013 Charon Chui
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 |
17 | package com.charon.scrollingtabs.view;
18 |
19 | import android.content.Context;
20 | import android.graphics.Canvas;
21 | import android.graphics.Color;
22 | import android.graphics.CornerPathEffect;
23 | import android.graphics.Paint;
24 | import android.graphics.Paint.Style;
25 | import android.graphics.Path;
26 | import android.util.AttributeSet;
27 | import android.view.View;
28 |
29 | public class TriangleScrollingTabs extends ScrollingTabs {
30 | public static final int TRIANGLE_WIDHT = 50;
31 | public static final int TRIANGLE_HEIGHT = 25;
32 | public static final int STROKE_WIDHT = 5;
33 | public static final int STROKE_COLOR = Color.parseColor("#ff0000");
34 | public static final int FILL_COLOR = Color.parseColor("#ffffff");
35 |
36 | private Paint mStrokePaint;
37 | private Paint mFillPaint;
38 | private Path mStrokePath;
39 | private Path mFillPath;
40 |
41 | private int mTriangleStartPosition;
42 | private int mTriangleCurrentPosition;
43 |
44 | public TriangleScrollingTabs(Context context, AttributeSet attrs,
45 | int defStyle) {
46 | super(context, attrs, defStyle);
47 | initPaint();
48 | }
49 |
50 | public TriangleScrollingTabs(Context context, AttributeSet attrs) {
51 | super(context, attrs);
52 | initPaint();
53 | }
54 |
55 | public TriangleScrollingTabs(Context context) {
56 | super(context);
57 | initPaint();
58 | }
59 |
60 | protected void initPaint() {
61 | mStrokePaint = getPaint(STROKE_COLOR, Style.STROKE);
62 | mFillPaint = getPaint(FILL_COLOR, Style.FILL);
63 |
64 | mStrokePath = getPath(0, 0, TRIANGLE_WIDHT / 2, -TRIANGLE_HEIGHT,
65 | TRIANGLE_WIDHT, 0);
66 | mFillPath = getPath(0, STROKE_WIDHT, TRIANGLE_WIDHT / 2,
67 | -TRIANGLE_HEIGHT + STROKE_WIDHT, TRIANGLE_WIDHT - STROKE_WIDHT,
68 | 0);
69 | }
70 |
71 | public Paint getPaint(int color, Style style) {
72 | Paint paint = new Paint();
73 | paint.setAntiAlias(true);
74 | paint.setColor(color);
75 | paint.setStyle(style);
76 | paint.setStrokeWidth(STROKE_WIDHT);
77 | paint.setPathEffect(new CornerPathEffect(3));
78 | return paint;
79 | }
80 |
81 | public Path getPath(int leftX, int leftY, int topX, int topY, int rightX,
82 | int rightY) {
83 | Path path = new Path();
84 | path.moveTo(leftX, leftY);
85 | path.lineTo(topX, topY);
86 | path.lineTo(rightX, rightY);
87 | path.close();
88 | return path;
89 | }
90 |
91 | /**
92 | * Select the tab, and move the tab to the middle position
93 | *
94 | * @param position
95 | * Position of the tab.
96 | */
97 | protected void selectTab(int position) {
98 | super.selectTab(position);
99 |
100 | View selectedView = getSelectedView(position);
101 | if (selectedView != null) {
102 | int width = selectedView.getMeasuredWidth();
103 | if (width != 0) {
104 | tabWidth = width;
105 | }
106 | if (tabWidth != 0 && mTriangleStartPosition == 0) {
107 | mTriangleStartPosition = (int) (tabWidth / 2 - TRIANGLE_WIDHT / 2);
108 | }
109 | }
110 | }
111 |
112 | @Override
113 | public void onPageScrolled(int arg0, float arg1, int arg2) {
114 | drawTriangle(arg0, arg1);
115 | }
116 |
117 | private void drawTriangle(int position, float offset) {
118 | int distance = (int) (tabWidth * (offset + position));
119 | if (distance != 0) {
120 | mTriangleCurrentPosition = distance;
121 | }
122 | invalidate();
123 | }
124 |
125 | @Override
126 | protected void onDraw(Canvas canvas) {
127 | super.onDraw(canvas);
128 | if (mTriangleStartPosition != 0) {
129 | canvas.save();
130 | canvas.translate(mTriangleStartPosition + mTriangleCurrentPosition,
131 | getHeight());
132 | canvas.drawPath(mStrokePath, mStrokePaint);
133 | canvas.drawPath(mFillPath, mFillPaint);
134 | canvas.restore();
135 | }
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/.gitignore:
--------------------------------------------------------------------------------
1 | /gen
2 | /assets
3 | /bin
4 | /libs
5 | /ic_launcher-web.png
6 | /proguard-project.txt
7 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | ScrollingTabsDemo
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-22
15 | android.library.reference.1=../ScrollingTabs
16 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabsDemo/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabsDemo/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabsDemo/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/ScrollingTabsDemo/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
13 |
14 |
21 |
22 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/layout/activity_scrollingtabs.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
11 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/layout/activity_trianglescrollingtabs.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
11 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/layout/tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
24 |
25 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/layout/triangletab.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
18 |
19 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ScrollingTabsDemo
5 | Settings
6 | Hello world!
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/src/com/charon/scrollingtabsdemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.scrollingtabsdemo;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.widget.Button;
9 |
10 | public class MainActivity extends Activity implements OnClickListener {
11 | private Button mScrollingTabsButton;
12 | private Button mTriangleScrollingTabsButton;
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_main);
18 | findView();
19 | initView();
20 | }
21 |
22 | private void findView() {
23 | mScrollingTabsButton = (Button) findViewById(R.id.bt_scrollingtabs_main);
24 | mTriangleScrollingTabsButton = (Button) findViewById(R.id.bt_trianglescrollingtabs_main);
25 | }
26 |
27 | private void initView() {
28 | mScrollingTabsButton.setOnClickListener(this);
29 | mTriangleScrollingTabsButton.setOnClickListener(this);
30 | }
31 |
32 | @Override
33 | public void onClick(View v) {
34 | int id = v.getId();
35 | switch (id) {
36 | case R.id.bt_scrollingtabs_main:
37 | startActivity(new Intent(MainActivity.this,
38 | ScroolingTabsActivity.class));
39 | break;
40 | case R.id.bt_trianglescrollingtabs_main:
41 | startActivity(new Intent(MainActivity.this,
42 | TriangleScroolingTabsActivity.class));
43 | break;
44 | default:
45 | break;
46 | }
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/src/com/charon/scrollingtabsdemo/ScroolingTabsActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.scrollingtabsdemo;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.annotation.SuppressLint;
7 | import android.app.Activity;
8 | import android.graphics.Color;
9 | import android.os.Bundle;
10 | import android.support.v4.view.PagerAdapter;
11 | import android.support.v4.view.ViewPager;
12 | import android.view.LayoutInflater;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.view.ViewGroup.LayoutParams;
16 | import android.widget.Button;
17 | import android.widget.ImageView;
18 | import android.widget.TextView;
19 |
20 | import com.charon.scrollingtabs.view.ScrollingTabs;
21 | import com.charon.scrollingtabs.view.ScrollingTabs.TabAdapter;
22 | import com.charon.scrollingtabs.view.TriangleScrollingTabs;
23 |
24 | public class ScroolingTabsActivity extends Activity {
25 |
26 | private ViewPager mViewPager;
27 |
28 | private ScrollingTabs mScrollingTabs;
29 |
30 | private List views = new ArrayList();
31 |
32 | private int count = 6;
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 | setContentView(R.layout.activity_scrollingtabs);
38 | findView();
39 | initView();
40 | }
41 |
42 | private void findView() {
43 | mViewPager = (ViewPager) findViewById(R.id.vp);
44 | mScrollingTabs = (ScrollingTabs) findViewById(R.id.stv);
45 | }
46 |
47 | private void initView() {
48 |
49 | for (int i = 0; i < count; i++) {
50 | Button button = new Button(this);
51 | button.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
52 | button.setText("ViewPager:" + i);
53 | views.add(button);
54 | }
55 |
56 | mViewPager.setAdapter(new PagerAdapter() {
57 |
58 | public int getCount() {
59 | return views.size();
60 | }
61 |
62 | @Override
63 | public boolean isViewFromObject(View arg0, Object arg1) {
64 | return arg0 == arg1;
65 | }
66 |
67 | @Override
68 | public void destroyItem(ViewGroup container, int position, Object object) {
69 | container.removeView(views.get(position));
70 | }
71 |
72 | @Override
73 | public Object instantiateItem(ViewGroup container, int position) {
74 | container.addView(views.get(position));
75 | return views.get(position);
76 | }
77 | });
78 |
79 | // mScrollingTabs.setEqualWidth(true);
80 | mScrollingTabs.setViewPager(mViewPager);
81 | mScrollingTabs.setTabAdapter(new TabAdapter() {
82 |
83 | @SuppressLint("InflateParams")
84 | @Override
85 | public View getView(int position) {
86 | LayoutInflater inflater = ScroolingTabsActivity.this.getLayoutInflater();
87 | final View tab = (View) inflater.inflate(R.layout.tab, null);
88 |
89 | TextView tv = (TextView) tab.findViewById(R.id.tv_tabs);
90 |
91 | final String[] mTitles =
92 | new String[] { "Button0", "Button1", "Button2", "Button3", "Button4", "Button5", };
93 |
94 | if (position < mTitles.length)
95 | tv.setText(mTitles[position]);
96 |
97 | return tab;
98 | }
99 |
100 | @Override
101 | public View getSeparator() {
102 | View view = new ImageView(ScroolingTabsActivity.this);
103 | view.setLayoutParams(new LayoutParams(1, LayoutParams.MATCH_PARENT));
104 | view.setBackgroundColor(Color.RED);
105 | return view;
106 | }
107 |
108 | @Override
109 | public void onTabSelected(int position, ViewGroup mContainer) {
110 | View tab = (View) mContainer.getChildAt(position);
111 | TextView tv = (TextView) tab.findViewById(R.id.tv_tabs);
112 | ImageView iv = (ImageView) tab.findViewById(R.id.iv_tabs);
113 |
114 | tv.setTextColor(Color.RED);
115 | iv.setVisibility(View.VISIBLE);
116 | }
117 |
118 | @Override
119 | public void onTabUnSelected(int position, ViewGroup mContainer) {
120 | View tab = (View) mContainer.getChildAt(position);
121 | TextView tv = (TextView) tab.findViewById(R.id.tv_tabs);
122 | ImageView iv = (ImageView) tab.findViewById(R.id.iv_tabs);
123 |
124 | tv.setTextColor(Color.BLACK);
125 | iv.setVisibility(View.INVISIBLE);
126 | }
127 | });
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/ScrollingTabsDemo/src/com/charon/scrollingtabsdemo/TriangleScroolingTabsActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.scrollingtabsdemo;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.annotation.SuppressLint;
7 | import android.app.Activity;
8 | import android.graphics.Color;
9 | import android.os.Bundle;
10 | import android.support.v4.view.PagerAdapter;
11 | import android.support.v4.view.ViewPager;
12 | import android.view.LayoutInflater;
13 | import android.view.View;
14 | import android.view.ViewGroup;
15 | import android.view.ViewGroup.LayoutParams;
16 | import android.widget.Button;
17 | import android.widget.ImageView;
18 | import android.widget.TextView;
19 |
20 | import com.charon.scrollingtabs.view.ScrollingTabs.TabAdapter;
21 | import com.charon.scrollingtabs.view.TriangleScrollingTabs;
22 |
23 | public class TriangleScroolingTabsActivity extends Activity {
24 |
25 | private ViewPager mViewPager;
26 |
27 | private TriangleScrollingTabs mScrollingTabs;
28 |
29 | private List views = new ArrayList();
30 |
31 | private int count = 6;
32 |
33 | @Override
34 | protected void onCreate(Bundle savedInstanceState) {
35 | super.onCreate(savedInstanceState);
36 | setContentView(R.layout.activity_trianglescrollingtabs);
37 | findView();
38 | initView();
39 | }
40 |
41 | private void findView() {
42 | mViewPager = (ViewPager) findViewById(R.id.vp);
43 | mScrollingTabs = (TriangleScrollingTabs) findViewById(R.id.stv);
44 | }
45 |
46 | private void initView() {
47 |
48 | for (int i = 0; i < count; i++) {
49 | Button button = new Button(this);
50 | button.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
51 | button.setText("ViewPager:" + i);
52 | views.add(button);
53 | }
54 |
55 | mViewPager.setAdapter(new PagerAdapter() {
56 |
57 | public int getCount() {
58 | return views.size();
59 | }
60 |
61 | @Override
62 | public boolean isViewFromObject(View arg0, Object arg1) {
63 | return arg0 == arg1;
64 | }
65 |
66 | @Override
67 | public void destroyItem(ViewGroup container, int position, Object object) {
68 | container.removeView(views.get(position));
69 | }
70 |
71 | @Override
72 | public Object instantiateItem(ViewGroup container, int position) {
73 | container.addView(views.get(position));
74 | return views.get(position);
75 | }
76 | });
77 |
78 | // mScrollingTabs.setEqualWidth(true);
79 | mScrollingTabs.setViewPager(mViewPager);
80 | mScrollingTabs.setTabAdapter(new TabAdapter() {
81 |
82 | @SuppressLint("InflateParams")
83 | @Override
84 | public View getView(int position) {
85 | LayoutInflater inflater = TriangleScroolingTabsActivity.this.getLayoutInflater();
86 | final View tab = (View) inflater.inflate(R.layout.triangletab, null);
87 |
88 | TextView tv = (TextView) tab.findViewById(R.id.tv_tabs);
89 |
90 | final String[] mTitles =
91 | new String[] { "Button0", "Button1", "Button2", "Button3", "Button4", "Button5", };
92 |
93 | if (position < mTitles.length)
94 | tv.setText(mTitles[position]);
95 |
96 | return tab;
97 | }
98 |
99 | @Override
100 | public View getSeparator() {
101 | View view = new ImageView(TriangleScroolingTabsActivity.this);
102 | view.setLayoutParams(new LayoutParams(1, LayoutParams.MATCH_PARENT));
103 | view.setBackgroundColor(Color.RED);
104 | return view;
105 | }
106 |
107 | @Override
108 | public void onTabSelected(int position, ViewGroup mContainer) {
109 | View tab = (View) mContainer.getChildAt(position);
110 | TextView tv = (TextView) tab.findViewById(R.id.tv_tabs);
111 |
112 | tv.setTextColor(Color.RED);
113 | }
114 |
115 | @Override
116 | public void onTabUnSelected(int position, ViewGroup mContainer) {
117 | View tab = (View) mContainer.getChildAt(position);
118 | TextView tv = (TextView) tab.findViewById(R.id.tv_tabs);
119 |
120 | tv.setTextColor(Color.BLACK);
121 | }
122 | });
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/SimpleApp/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SimpleApp
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/SimpleApp/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
13 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/SimpleApp/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/SimpleApp/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-20
15 | android.library.reference.1=..\\..\\AndroidDevelopFramework\\AndroidDevelopFramework
16 | android.library.reference.3=../ScrollingTabs
17 | android.library.reference.4=../SlidingMenu
18 | android.library.reference.2=../PullToRefreshListView
19 |
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-hdpi/base_actionbar_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-hdpi/base_actionbar_bg.9.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-hdpi/base_main_action_personal_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-hdpi/base_main_action_personal_normal.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-hdpi/biz_news_main_back_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-hdpi/biz_news_main_back_normal.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-hdpi/head_default.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-hdpi/head_default.jpg
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-hdpi/indicator_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-hdpi/indicator_arrow.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-hdpi/loading_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-hdpi/loading_logo.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SimpleApp/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SimpleApp/res/drawable/tab_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/fragment_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
23 |
24 |
31 |
32 |
33 |
37 |
38 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/fragment_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
17 |
18 |
24 |
25 |
35 |
36 |
44 |
45 |
46 |
51 |
52 |
57 |
58 |
63 |
64 |
69 |
70 |
75 |
76 |
81 |
82 |
87 |
88 |
93 |
94 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/fragment_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/frame_center.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/frame_left.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/frame_right.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/item_lv_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/load_more_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
24 |
25 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/lv_pager_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/pull_to_refresh_header.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
8 |
9 |
15 |
16 |
21 |
22 |
27 |
28 |
29 |
34 |
35 |
41 |
42 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/SimpleApp/res/layout/tab_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
--------------------------------------------------------------------------------
/SimpleApp/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/SimpleApp/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #77000000
4 | #99990000
5 |
6 |
--------------------------------------------------------------------------------
/SimpleApp/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SimpleApp/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SimpleApp
5 | Settings
6 | Hello world!
7 | 下拉刷新
8 | 加载更多
9 | 二合一
10 | 松开刷新
11 | 正在刷新中...
12 | 更新于
13 |
14 |
--------------------------------------------------------------------------------
/SimpleApp/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/SimpleApp/src/com/charon/simpleapp/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.simpleapp;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.FragmentTransaction;
5 | import android.view.View;
6 |
7 | import com.charon.framework.util.LogUtil;
8 | import com.charon.framework.util.ShortCutUtils;
9 | import com.charon.simpleapp.base.BaseActivity;
10 | import com.charon.simpleapp.fragment.CenterFragment;
11 | import com.charon.simpleapp.fragment.CenterFragment.OnViewPagerChangeListener;
12 | import com.charon.simpleapp.fragment.LeftFragment;
13 | import com.charon.simpleapp.fragment.RightFragment;
14 | import com.charon.slidingmenu.view.SlidingMenu;
15 |
16 | /**
17 | * 首页,包含了一个SlidingMenu
18 | */
19 | public class MainActivity extends BaseActivity {
20 | private static final String TAG = "MainActivity";
21 | private SlidingMenu mSlidingMenu;
22 | private LeftFragment mLeftFragment;
23 | private RightFragment mRightFragment;
24 | private CenterFragment mCenterFragment;
25 | private final String ISFIRSTUSE = "isFirstUse";
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_main);
31 | findView();
32 | initView();
33 | addShortCut();
34 | }
35 |
36 | private void findView() {
37 | mSlidingMenu = (SlidingMenu) findViewById(R.id.sm);
38 | }
39 |
40 | private void initView() {
41 | View leftView = View.inflate(this, R.layout.frame_left, null);
42 | View rightView = View.inflate(this, R.layout.frame_right, null);
43 | View centerView = View.inflate(this, R.layout.frame_center, null);
44 | LogUtil.e(TAG, "slidingMenu:::" + (mSlidingMenu == null));
45 | LogUtil.e(TAG, "leftView:::" + (leftView == null));
46 | LogUtil.e(TAG, "rightView:::" + (rightView == null));
47 | // 设置SlidingMenu左、中、右三个子View
48 | mSlidingMenu.setView(leftView, rightView, centerView, 200, 250);
49 |
50 | // 将SlidingMenu中左、中、右三个View替换成相应的Fragment
51 | FragmentTransaction transaction = getSupportFragmentManager()
52 | .beginTransaction();
53 | mLeftFragment = new LeftFragment();
54 | transaction.replace(R.id.fl_left, mLeftFragment);
55 | mRightFragment = new RightFragment();
56 | transaction.replace(R.id.fl_right, mRightFragment);
57 | mCenterFragment = new CenterFragment();
58 | transaction.replace(R.id.fl_center, mCenterFragment);
59 | transaction.commit();
60 |
61 | // 给中间视图的Fragment设置ViewPager发生切换时的监听
62 | mCenterFragment
63 | .setOnViewPagerChangeListener(new OnViewPagerChangeListener() {
64 |
65 | @Override
66 | public void onPageChage(int position) {
67 | if (mCenterFragment.isFirst()) {
68 | mSlidingMenu.setWhichSideCanShow(true, false);
69 | } else if (mCenterFragment.isLast()) {
70 | mSlidingMenu.setWhichSideCanShow(false, true);
71 | } else {
72 | mSlidingMenu.setWhichSideCanShow(false, false);
73 | }
74 | }
75 | });
76 | }
77 |
78 | private void addShortCut() {
79 | boolean isFirstUse = sp.getBoolean(ISFIRSTUSE, true);
80 | if (isFirstUse) {
81 | ShortCutUtils.addShortcut(this, R.drawable.ic_launcher);
82 | sp.edit().putBoolean(ISFIRSTUSE, false).commit();
83 | }
84 | }
85 |
86 | // 暴露出显示左边的控制开关供Fragment使用
87 | public void showLeftViewToogle() {
88 | mSlidingMenu.showLeftViewToogle();
89 | }
90 |
91 | public void showRightViewToogle() {
92 | mSlidingMenu.showRightViewToogle();
93 | }
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/SimpleApp/src/com/charon/simpleapp/base/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.simpleapp.base;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.os.Bundle;
6 | import android.support.v4.app.FragmentActivity;
7 |
8 | public class BaseActivity extends FragmentActivity {
9 | protected SharedPreferences sp;
10 | private final String name = "SimpleApp";
11 |
12 | @Override
13 | protected void onCreate(Bundle arg0) {
14 | super.onCreate(arg0);
15 | sp = getSharedPreferences(name, Context.MODE_PRIVATE);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SimpleApp/src/com/charon/simpleapp/fragment/CenterFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.simpleapp.fragment;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import android.os.Bundle;
7 | import android.support.v4.app.Fragment;
8 | import android.support.v4.app.FragmentManager;
9 | import android.support.v4.app.FragmentStatePagerAdapter;
10 | import android.support.v4.view.ViewPager;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.View.OnClickListener;
14 | import android.view.ViewGroup;
15 | import android.widget.ImageView;
16 | import android.widget.TextView;
17 |
18 | import com.charon.scrollingtabs.view.ScrollingTabs;
19 | import com.charon.scrollingtabs.view.ScrollingTabs.PageSelectedListener;
20 | import com.charon.scrollingtabs.view.ScrollingTabs.TabAdapter;
21 | import com.charon.simpleapp.MainActivity;
22 | import com.charon.simpleapp.R;
23 |
24 | public class CenterFragment extends Fragment implements OnClickListener {
25 | private ViewPager mViewPager;
26 | private ImageView mLeftToogle;
27 | private ImageView mRightToogle;
28 | private ScrollingTabs mScrollingTabsView;
29 |
30 | private OnViewPagerChangeListener listener;
31 |
32 | private MyPagerAdapter adapter;
33 | private MyTabAdapter mTabAdapter;
34 |
35 | private List tabs;
36 |
37 | private ArrayList pagerItemList = new ArrayList();
38 |
39 | @Override
40 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
41 | Bundle savedInstanceState) {
42 | View view = inflater.inflate(R.layout.fragment_center, null);
43 | findView(view);
44 | initView(view);
45 | return view;
46 | }
47 |
48 | private void findView(View view) {
49 | mViewPager = (ViewPager) view.findViewById(R.id.vp);
50 | mLeftToogle = (ImageView) view.findViewById(R.id.iv_center_left);
51 | mRightToogle = (ImageView) view.findViewById(R.id.iv_center_right);
52 | mScrollingTabsView = (ScrollingTabs) view.findViewById(R.id.stv);
53 | }
54 |
55 | private void initView(View view) {
56 | mLeftToogle.setOnClickListener(this);
57 | mRightToogle.setOnClickListener(this);
58 |
59 | pagerItemList.add(PagerFragment.getInstance(1));
60 | pagerItemList.add(PagerFragment.getInstance(2));
61 | pagerItemList.add(PagerFragment.getInstance(3));
62 | pagerItemList.add(PagerFragment.getInstance(4));
63 | pagerItemList.add(PagerFragment.getInstance(5));
64 | pagerItemList.add(PagerFragment.getInstance(6));
65 |
66 | adapter = new MyPagerAdapter(getFragmentManager());
67 |
68 | mViewPager.setAdapter(adapter);
69 |
70 | // 这样会有问题,在ScrollingTabsView中也会对ViewPager设置onPageChangeListener会导致覆盖
71 | // mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
72 | //
73 | // @Override
74 | // public void onPageSelected(int position) {
75 | // listener.onPageChage(position);
76 | // }
77 | //
78 | // @Override
79 | // public void onPageScrolled(int arg0, float arg1, int arg2) {
80 | //
81 | // }
82 | //
83 | // @Override
84 | // public void onPageScrollStateChanged(int arg0) {
85 | //
86 | // }
87 | // });
88 |
89 | // 对ScrollingTabsView进行初始化设置
90 | tabs = new ArrayList();
91 | tabs.add("新闻");
92 | tabs.add("趣事");
93 | tabs.add("微博");
94 | tabs.add("秘密");
95 | tabs.add("军事");
96 | tabs.add("交友");
97 |
98 | mTabAdapter = new MyTabAdapter();
99 | mScrollingTabsView.setTabAdapter(mTabAdapter);
100 | mScrollingTabsView.setViewPager(mViewPager);
101 |
102 | // 解决上面对同一个ViewPager设置多次setonPageChangeListener导致覆盖的问题。我们通过这个回调方法来得到ScrollingTabsView中
103 | // 设置的ViewPageChangeListener中的onPageSelected方法,这样就解决了覆盖的问题
104 | mScrollingTabsView.setPageSelectedListener(new PageSelectedListener() {
105 |
106 | @Override
107 | public void onPageSelected(int position) {
108 | listener.onPageChage(position);
109 | }
110 | });
111 |
112 | }
113 |
114 | @Override
115 | public void onClick(View v) {
116 | int id = v.getId();
117 | switch (id) {
118 | case R.id.iv_center_left:
119 | ((MainActivity) this.getActivity()).showLeftViewToogle();
120 | break;
121 | case R.id.iv_center_right:
122 | ((MainActivity) this.getActivity()).showRightViewToogle();
123 | break;
124 | default:
125 | break;
126 | }
127 | }
128 |
129 | public void setOnViewPagerChangeListener(OnViewPagerChangeListener listener) {
130 | this.listener = listener;
131 | }
132 |
133 | public boolean isFirst() {
134 | return mViewPager.getCurrentItem() == 0;
135 | }
136 |
137 | public boolean isLast() {
138 | return mViewPager.getCurrentItem() == pagerItemList.size() - 1;
139 | }
140 |
141 | private class MyPagerAdapter extends FragmentStatePagerAdapter {
142 |
143 | public MyPagerAdapter(FragmentManager fm) {
144 | super(fm);
145 | }
146 |
147 | @Override
148 | public Fragment getItem(int arg0) {
149 | return pagerItemList.get(arg0);
150 | }
151 |
152 | @Override
153 | public int getCount() {
154 | return pagerItemList.size();
155 | }
156 |
157 | }
158 |
159 | private class MyTabAdapter implements TabAdapter {
160 |
161 | @Override
162 | public View getView(int position) {
163 | View view = View.inflate(CenterFragment.this.getActivity(),
164 | R.layout.tab_center, null);
165 | TextView tv = (TextView) view.findViewById(R.id.tv_tab_center);
166 | tv.setText(tabs.get(position));
167 | return view;
168 | }
169 |
170 | @Override
171 | public View getSeparator() {
172 | return null;
173 | }
174 |
175 | @Override
176 | public void onTabSelected(int position, ViewGroup mContainer) {
177 |
178 | }
179 |
180 | @Override
181 | public void onTabUnSelected(int position, ViewGroup mContainer) {
182 |
183 | }
184 | }
185 |
186 | /**
187 | * 当ViewPager中发生页面改变后的回调
188 | */
189 | public interface OnViewPagerChangeListener {
190 | void onPageChage(int position);
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/SimpleApp/src/com/charon/simpleapp/fragment/LeftFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.simpleapp.fragment;
2 |
3 | import com.charon.simpleapp.R;
4 |
5 | import android.os.Bundle;
6 | import android.support.v4.app.Fragment;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 |
11 | public class LeftFragment extends Fragment {
12 | @Override
13 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
14 | Bundle savedInstanceState) {
15 | return inflater.inflate(R.layout.fragment_left, null);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SimpleApp/src/com/charon/simpleapp/fragment/PagerFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.simpleapp.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.widget.BaseAdapter;
10 | import android.widget.TextView;
11 |
12 | import com.charon.pulltorefreshlistview.PullToRefreshListView;
13 | import com.charon.pulltorefreshlistview.PullToRefreshListView.OnRefreshListener;
14 | import com.charon.simpleapp.R;
15 |
16 | /**
17 | * ViewPager中每个页面对应的Fragment
18 | */
19 | public class PagerFragment extends Fragment {
20 | private int index;
21 | private PullToRefreshListView mPullToRefreshListView;
22 |
23 | private Handler handler = new Handler();
24 |
25 | public PagerFragment() {
26 | super();
27 | }
28 |
29 | public static PagerFragment getInstance(int index) {
30 | PagerFragment fragment = new PagerFragment();
31 | fragment.setIndex(index);
32 | return fragment;
33 | }
34 |
35 | private void setIndex(int index) {
36 | this.index = index;
37 | }
38 |
39 | @Override
40 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
41 | Bundle savedInstanceState) {
42 | View view = inflater.inflate(R.layout.lv_pager_center, null);
43 | findView(view);
44 | initView(view);
45 | return view;
46 | }
47 |
48 | private void findView(View view) {
49 | mPullToRefreshListView = (PullToRefreshListView) view
50 | .findViewById(R.id.ptrlv_pager);
51 |
52 | }
53 |
54 | private void initView(View view) {
55 | mPullToRefreshListView.setAdapter(new BaseAdapter() {
56 |
57 | private ViewHolder holder;
58 |
59 | @Override
60 | public View getView(int position, View convertView, ViewGroup parent) {
61 | if (convertView == null) {
62 | convertView = View.inflate(
63 | PagerFragment.this.getActivity(),
64 | R.layout.item_lv_center, null);
65 | TextView tv = (TextView) convertView
66 | .findViewById(R.id.tv_item_lv);
67 | holder = new ViewHolder();
68 | holder.tv_item_lv = tv;
69 | convertView.setTag(holder);
70 | } else {
71 | holder = (ViewHolder) convertView.getTag();
72 | }
73 |
74 | holder.tv_item_lv.setText(index + ":::" + position);
75 | return convertView;
76 | }
77 |
78 | @Override
79 | public long getItemId(int position) {
80 | return 0;
81 | }
82 |
83 | @Override
84 | public Object getItem(int position) {
85 | return null;
86 | }
87 |
88 | @Override
89 | public int getCount() {
90 | return 50;
91 | }
92 | });
93 | mPullToRefreshListView.setOnRefreshListener(new OnRefreshListener() {
94 |
95 | @Override
96 | public void onRefresh() {
97 | new Thread() {
98 | @Override
99 | public void run() {
100 | super.run();
101 | try {
102 | Thread.sleep(2000);
103 | } catch (InterruptedException e) {
104 | e.printStackTrace();
105 | }
106 | handler.post(new Runnable() {
107 |
108 | @Override
109 | public void run() {
110 | mPullToRefreshListView.onRefreshComplete();
111 | }
112 | });
113 | }
114 | }.start();
115 | }
116 | });
117 |
118 | }
119 |
120 | static class ViewHolder {
121 | private TextView tv_item_lv;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/SimpleApp/src/com/charon/simpleapp/fragment/RightFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.simpleapp.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.charon.simpleapp.R;
10 |
11 | public class RightFragment extends Fragment {
12 | @Override
13 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
14 | Bundle savedInstanceState) {
15 | return inflater.inflate(R.layout.fragment_right, null);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SlidingMenu.md:
--------------------------------------------------------------------------------
1 | SlidingMenu
2 | ===
3 |
4 | 先看一下图片
5 | ![image]{https://github.com/CharonChui/AndroidNote/blob/master/Pic/slidingmenu_1.png?raw=true}
6 | ![image]{https://github.com/CharonChui/AndroidNote/blob/master/Pic/slidingmenu_2.png?raw=true}
7 | ![image]{https://github.com/CharonChui/AndroidNote/blob/master/Pic/slidingmenu_3.png?raw=true}
8 |
9 | 原理
10 | ---
11 |
12 | `SlidingMenu`无非就是一个包含三个`View`的控件,**左边View**、**中间View(默认时全屏)**、**右边View**,默认的情况下中间`View`会把两边的`View`覆盖住,在手指滑动的时候,会根据手指的滑动方向以及滑动距离去移动中间的那个`View`,从而能让两边`View`完全可见。
13 | 在定义该View的时候,首先会想到继承`RelativeLayout`,能简单的实现这种左、中、右三个View的布局。
14 |
15 | 1. 继承RelativeLayout
16 | ```java
17 | public class SlidingMenu extends RelativeLayout {
18 |
19 | public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
20 | super(context, attrs, defStyle);
21 | init(context);
22 | }
23 |
24 | public SlidingMenu(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | init(context);
27 | }
28 |
29 | public SlidingMenu(Context context) {
30 | super(context);
31 | init(context);
32 | }
33 |
34 | private void init(Context context) {
35 | mContext = context;
36 | mScroller = new Scroller(context);
37 | mWindowWidth = getWindowWidth(context);
38 | }
39 | }
40 | ```
41 |
42 | 2. 具体的三个View需要暴露给外界调用,所以我们要提供一个setView()的方法。
43 | ```java
44 | public void setView(View leftView, View rightView, View centerView,
45 | int leftViewWidth, int rightViewWidth) {
46 | //添加左边View
47 | RelativeLayout.LayoutParams leftParams = new LayoutParams(
48 | (int) convertDpToPixel(leftViewWidth, mContext),
49 | LayoutParams.MATCH_PARENT);
50 | leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
51 | addView(leftView, leftParams);
52 |
53 | //右边的View
54 | RelativeLayout.LayoutParams rightParams = new LayoutParams(
55 | (int) convertDpToPixel(rightViewWidth, mContext),
56 | LayoutParams.MATCH_PARENT);
57 | rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
58 | addView(rightView, rightParams);
59 |
60 | //添加中间的View
61 | RelativeLayout.LayoutParams centerParams = new LayoutParams(
62 | LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
63 | addView(centerView, centerParams);
64 |
65 | mLeftView = leftView;
66 | mRightView = rightView;
67 | mCenterView = centerView;
68 | }
69 | ```
70 | 外界使用`SlidingMenu`类的时候需要首先调用该方法去设置相应的View,一旦调用该方法后,我们就将布局设置完了,下一步就是对`touch`事件进行处理,然后去移动中间的View。
71 |
72 | 3. 处理Touch事件
73 | 在手指按下的时候,我们去控制两边View的显示与隐藏
74 | ```java
75 | public boolean onInterceptTouchEvent(MotionEvent ev) {
76 | int x = (int) ev.getRawX();
77 | int y = (int) ev.getRawY();
78 |
79 | int action = ev.getAction();
80 |
81 | switch (action) {
82 | case MotionEvent.ACTION_DOWN:
83 | mLastPostionX = x;
84 | mLastPostionY = y;
85 | //通过变量记录当前可以显示左边的View还是可以显示右边的View
86 | if (mCanLeftViewShow) {
87 | //如果当前,中间的View往右滑,那么这时候左边的View就要能显示了
88 | mLeftView.setVisibility(View.VISIBLE);
89 | mRightView.setVisibility(View.GONE);
90 | } else if (mCanRightViewShow) {
91 | mLeftView.setVisibility(View.GONE);
92 | mRightView.setVisibility(View.VISIBLE);
93 | }
94 |
95 | break;
96 | case MotionEvent.ACTION_MOVE:
97 |
98 | break;
99 | case MotionEvent.ACTION_UP:
100 |
101 | break;
102 |
103 | default:
104 | break;
105 | }
106 |
107 | return false;
108 | }
109 | ```
110 | 在`onTouch()`中,我们去获取手指移动的距离
111 | ```java
112 | public boolean onTouchEvent(MotionEvent event) {
113 | int x = (int) event.getRawX();
114 | int y = (int) event.getRawY();
115 |
116 | int action = event.getAction();
117 | switch (action) {
118 | case MotionEvent.ACTION_DOWN:
119 | mLastPostionX = x;
120 | mLastPostionY = y;
121 |
122 | if (!mScroller.isFinished()) {
123 | mScroller.abortAnimation();
124 | }
125 |
126 | break;
127 | case MotionEvent.ACTION_MOVE:
128 | int distance = x - mLastPostionX;
129 | int targetPositon = mCenterView.getScrollX() - distance;
130 | mLastPostionX = x;
131 |
132 | if (mCanLeftViewShow) {
133 | if (targetPositon > 0) {
134 | targetPositon = 0;
135 | }
136 |
137 | if (targetPositon < -mLeftViewWidth) {
138 | targetPositon = -mLeftViewWidth;
139 | }
140 | }
141 |
142 | if (mCanRightViewShow) {
143 | if (targetPositon < 0) {
144 | targetPositon = 0;
145 | }
146 |
147 | if (targetPositon > mRightViewWidth) {
148 | targetPositon = mRightViewWidth;
149 | }
150 | }
151 |
152 | mClicked = false;
153 | //让中间的View随着手指的移动而移动
154 | mCenterView.scrollTo(targetPositon, 0);
155 |
156 | break;
157 | case MotionEvent.ACTION_UP:
158 | //你手指移动后抬起的时候需要注意,如果现在左边的View已经超过一半可见了,这时候就算你抬起手指了,SlidingMenu也要滑动到右边让左边View完全可见。当然还有就是你滑动的飞快,然后突然抬起了手指,这时候就要进行速率的计算了,我们先不说速率
159 | int dx = 0;
160 | if (mCanLeftViewShow) {
161 | if (mCenterView.getScrollX() <= -mLeftViewWidth / 2) {
162 | //已经超过左边View的一般了,应该让中间View继续移动,移动到左边View完全可见
163 | dx = -mLeftViewWidth - mCenterView.getScrollX();
164 | } else {
165 | // 滚回原来的位置
166 | dx = -mCenterView.getScrollX();
167 | resumeLeftViewClickState();
168 | }
169 |
170 | } else if (mCanRightViewShow) {
171 | if (mCenterView.getScrollX() >= mRightViewWidth / 2) {
172 | dx = mRightViewWidth - mCenterView.getScrollX();
173 | } else {
174 | dx = -mCenterView.getScrollX();
175 | resumeRightViewClickState();
176 | }
177 | }
178 | //手指抬起后,要让中间View有过程的滑过去,所以要用到Scroller类
179 | smoothScrollTo(dx);
180 | break;
181 |
182 | default:
183 | break;
184 | }
185 |
186 | return true;
187 | }
188 | ```
189 | `Scroller`的实现
190 | ```java
191 |
192 | private void smoothScrollTo(int distance) {
193 | mScroller.startScroll(mCenterView.getScrollX(), 0, distance, 0,
194 | sDuration);
195 | invalidate();
196 | }
197 |
198 | @Override
199 | public void computeScroll() {
200 | if (mScroller.computeScrollOffset()) {
201 | mCenterView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
202 | postInvalidate();
203 | }
204 | }
205 | ```
206 |
207 | 4. 到这里SlidingMenu的大体实现已经完成了
208 | 剩下的就是对速率的计算,已经添加显示左边与显示右边的View的按钮。当左边View完全显示的时候,点击中间View可见部分时需要让中间View全屏。至于这些细节的东西就不再仔细说了,大家自己看源码吧。
209 |
210 | ------------------------------------------
211 |
212 | - 邮箱 :charon.chui@gmail.com
213 | - Good Luck!
214 |
--------------------------------------------------------------------------------
/SlidingMenu/.gitignore:
--------------------------------------------------------------------------------
1 | /gen
2 | /assets
3 | /bin
4 |
--------------------------------------------------------------------------------
/SlidingMenu/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SlidingMenu
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/SlidingMenu/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SlidingMenu/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-20
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/SlidingMenu/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenu/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenu/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenu/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenu/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenu/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenu/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenu/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenu/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/SlidingMenu/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SlidingMenu/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/SlidingMenu/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SlidingMenu/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/SlidingMenu/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SlidingMenu/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | MySlidingMenu
5 | Settings
6 | Hello world!
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SlidingMenu/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SlidingMenuDemo
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/SlidingMenuDemo/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-20
15 | android.library.reference.1=../SlidingMenu
16 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-hdpi/base_actionbar_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-hdpi/base_actionbar_bg.9.png
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-hdpi/base_main_action_personal_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-hdpi/base_main_action_personal_normal.png
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-hdpi/biz_news_main_back_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-hdpi/biz_news_main_back_normal.png
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-hdpi/head_default.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-hdpi/head_default.jpg
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CharonChui/PullRefresh-SlidingMenu/81246fa6d8f8708f8ab53f13bc3b09f38ede24ee/SlidingMenuDemo/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/layout/fragment_center.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
21 |
22 |
28 |
29 |
30 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/layout/fragment_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
17 |
18 |
24 |
25 |
35 |
36 |
44 |
45 |
46 |
51 |
52 |
57 |
58 |
63 |
64 |
69 |
70 |
75 |
76 |
81 |
82 |
87 |
88 |
93 |
94 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/layout/fragment_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
14 |
15 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/layout/frame_center.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/layout/frame_left.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/layout/frame_right.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SlidingMenuDemo
5 | Settings
6 | Hello world!
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/src/com/charon/slidingmenudemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.charon.slidingmenudemo;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.FragmentActivity;
5 | import android.support.v4.app.FragmentTransaction;
6 | import android.view.View;
7 |
8 | import com.charon.slidingmenu.view.SlidingMenu;
9 | import com.charon.slidingmenudemo.fragment.CenterFragment;
10 | import com.charon.slidingmenudemo.fragment.CenterFragment.OnViewPagerChangeListener;
11 | import com.charon.slidingmenudemo.fragment.LeftFragment;
12 | import com.charon.slidingmenudemo.fragment.RightFragment;
13 |
14 | public class MainActivity extends FragmentActivity {
15 | private SlidingMenu mSlidingMenu;
16 | private LeftFragment mLeftFragment;
17 | private RightFragment mRightFragment;
18 | private CenterFragment mCenterFragment;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_main);
24 | findView();
25 | initView();
26 | }
27 |
28 | private void findView() {
29 | mSlidingMenu = (SlidingMenu) findViewById(R.id.sm);
30 | }
31 |
32 | private void initView() {
33 | View leftView = View.inflate(this, R.layout.frame_left, null);
34 | View rightView = View.inflate(this, R.layout.frame_right, null);
35 | View centerView = View.inflate(this, R.layout.frame_center, null);
36 |
37 | mSlidingMenu.setView(leftView, rightView, centerView, 200, 250);
38 |
39 | FragmentTransaction transaction = getSupportFragmentManager()
40 | .beginTransaction();
41 | mLeftFragment = new LeftFragment();
42 | transaction.replace(R.id.fl_left, mLeftFragment);
43 | mRightFragment = new RightFragment();
44 | transaction.replace(R.id.fl_right, mRightFragment);
45 | mCenterFragment = new CenterFragment();
46 | transaction.replace(R.id.fl_center, mCenterFragment);
47 | transaction.commit();
48 |
49 | mCenterFragment
50 | .setOnViewPagerChangeListener(new OnViewPagerChangeListener() {
51 |
52 | @Override
53 | public void onPageChage(int position) {
54 | if (mCenterFragment.isFirst()) {
55 | mSlidingMenu.setWhichSideCanShow(true, false);
56 | } else if (mCenterFragment.isLast()) {
57 | mSlidingMenu.setWhichSideCanShow(false, true);
58 | } else {
59 | mSlidingMenu.setWhichSideCanShow(false, false);
60 | }
61 | }
62 | });
63 | }
64 |
65 | public void showLeftViewToogle() {
66 | mSlidingMenu.showLeftViewToogle();
67 | }
68 |
69 | public void showRightViewToogle() {
70 | mSlidingMenu.showRightViewToogle();
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/src/com/charon/slidingmenudemo/fragment/CenterFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.slidingmenudemo.fragment;
2 |
3 | import java.util.ArrayList;
4 |
5 | import android.os.Bundle;
6 | import android.support.v4.app.Fragment;
7 | import android.support.v4.app.FragmentManager;
8 | import android.support.v4.app.FragmentStatePagerAdapter;
9 | import android.support.v4.view.ViewPager;
10 | import android.support.v4.view.ViewPager.OnPageChangeListener;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.View.OnClickListener;
14 | import android.view.ViewGroup;
15 | import android.widget.ImageView;
16 |
17 | import com.charon.slidingmenudemo.MainActivity;
18 | import com.charon.slidingmenudemo.R;
19 |
20 | public class CenterFragment extends Fragment implements OnClickListener {
21 | private ViewPager mViewPager;
22 | private ImageView mLeftToogle;
23 | private ImageView mRightToogle;
24 |
25 | private OnViewPagerChangeListener listener;
26 |
27 | private MyPagerAdapter adapter;
28 |
29 | private ArrayList pagerItemList = new ArrayList();
30 |
31 | @Override
32 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
33 | Bundle savedInstanceState) {
34 | View view = inflater.inflate(R.layout.fragment_center, null);
35 | findView(view);
36 | initView(view);
37 | return view;
38 | }
39 |
40 | private void findView(View view) {
41 | mViewPager = (ViewPager) view.findViewById(R.id.vp);
42 | mLeftToogle = (ImageView) view.findViewById(R.id.iv_center_left);
43 | mRightToogle = (ImageView) view.findViewById(R.id.iv_center_right);
44 | }
45 |
46 | private void initView(View view) {
47 | mLeftToogle.setOnClickListener(this);
48 | mRightToogle.setOnClickListener(this);
49 |
50 | pagerItemList.add(PagerFragment.getInstance(1));
51 | pagerItemList.add(PagerFragment.getInstance(2));
52 | pagerItemList.add(PagerFragment.getInstance(3));
53 | pagerItemList.add(PagerFragment.getInstance(4));
54 |
55 | adapter = new MyPagerAdapter(getFragmentManager());
56 |
57 | mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
58 |
59 | @Override
60 | public void onPageSelected(int position) {
61 | if (listener != null) {
62 | listener.onPageChage(position);
63 | }
64 | }
65 |
66 | @Override
67 | public void onPageScrolled(int arg0, float arg1, int arg2) {
68 |
69 | }
70 |
71 | @Override
72 | public void onPageScrollStateChanged(int arg0) {
73 |
74 | }
75 | });
76 |
77 | mViewPager.setAdapter(adapter);
78 | }
79 |
80 | @Override
81 | public void onClick(View v) {
82 | int id = v.getId();
83 | switch (id) {
84 | case R.id.iv_center_left:
85 | ((MainActivity) this.getActivity()).showLeftViewToogle();
86 | break;
87 | case R.id.iv_center_right:
88 | ((MainActivity) this.getActivity()).showRightViewToogle();
89 | break;
90 | default:
91 | break;
92 | }
93 | }
94 |
95 | public void setOnViewPagerChangeListener(OnViewPagerChangeListener listener) {
96 | this.listener = listener;
97 | }
98 |
99 | public boolean isFirst() {
100 | return mViewPager.getCurrentItem() == 0;
101 | }
102 |
103 | public boolean isLast() {
104 | return mViewPager.getCurrentItem() == pagerItemList.size() - 1;
105 | }
106 |
107 | private class MyPagerAdapter extends FragmentStatePagerAdapter {
108 |
109 | public MyPagerAdapter(FragmentManager fm) {
110 | super(fm);
111 | }
112 |
113 | @Override
114 | public Fragment getItem(int arg0) {
115 | return pagerItemList.get(arg0);
116 | }
117 |
118 | @Override
119 | public int getCount() {
120 | return 4;
121 | }
122 |
123 | }
124 |
125 | /**
126 | * Interface when the page have changed.
127 | */
128 | public interface OnViewPagerChangeListener {
129 | void onPageChage(int position);
130 | }
131 |
132 | }
133 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/src/com/charon/slidingmenudemo/fragment/LeftFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.slidingmenudemo.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.charon.slidingmenudemo.R;
10 |
11 | public class LeftFragment extends Fragment {
12 | @Override
13 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
14 | Bundle savedInstanceState) {
15 | return inflater.inflate(R.layout.fragment_left, null);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/src/com/charon/slidingmenudemo/fragment/PagerFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.slidingmenudemo.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.view.ViewGroup.LayoutParams;
9 | import android.widget.Button;
10 |
11 | public class PagerFragment extends Fragment {
12 | private int index;
13 |
14 | public PagerFragment() {
15 | super();
16 | }
17 |
18 | public static PagerFragment getInstance(int index) {
19 | PagerFragment fragment = new PagerFragment();
20 | fragment.setIndex(index);
21 | return fragment;
22 | }
23 |
24 | private void setIndex(int index) {
25 | this.index = index;
26 | }
27 |
28 | @Override
29 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
30 | Bundle savedInstanceState) {
31 | Button view = new Button(this.getActivity());
32 | view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
33 | LayoutParams.MATCH_PARENT));
34 | view.setText("ViewPager:::" + index);
35 | return view;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/SlidingMenuDemo/src/com/charon/slidingmenudemo/fragment/RightFragment.java:
--------------------------------------------------------------------------------
1 | package com.charon.slidingmenudemo.fragment;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 |
9 | import com.charon.slidingmenudemo.R;
10 |
11 | public class RightFragment extends Fragment {
12 | @Override
13 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
14 | Bundle savedInstanceState) {
15 | return inflater.inflate(R.layout.fragment_right, null);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------