Update Android-PullToRefresh to v2.1.1
@ -9,7 +9,14 @@ This project aims to provide a reusable Pull to Refresh widget for Android. It w
|
|||||||
* Supports both Pulling Down from the top, and Pulling Up from the bottom (or even both).
|
* Supports both Pulling Down from the top, and Pulling Up from the bottom (or even both).
|
||||||
* Animated Scrolling for all devices.
|
* Animated Scrolling for all devices.
|
||||||
* Over Scroll supports for devices on Android v2.3+.
|
* Over Scroll supports for devices on Android v2.3+.
|
||||||
* Currently works with **ListView**, **ExpandableListView** & **GridView**, **WebView** and **ScrollView**!
|
* Currently works with:
|
||||||
|
* **ListView**
|
||||||
|
* **ExpandableListView**
|
||||||
|
* **GridView**
|
||||||
|
* **WebView**
|
||||||
|
* **ScrollView**
|
||||||
|
* **HorizontalScrollView**
|
||||||
|
* **ViewPager**
|
||||||
* Integrated End of List Listener for use of detecting when the user has scrolled to the bottom.
|
* Integrated End of List Listener for use of detecting when the user has scrolled to the bottom.
|
||||||
* Maven Support.
|
* Maven Support.
|
||||||
* Indicators to show the user when a Pull-to-Refresh is available.
|
* Indicators to show the user when a Pull-to-Refresh is available.
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.handmark.pulltorefresh.extras.listfragment"
|
package="com.handmark.pulltorefresh.extras.listfragment"
|
||||||
android:versionCode="1420"
|
android:versionCode="2110"
|
||||||
android:versionName="1.4.2" >
|
android:versionName="2.1.1" >
|
||||||
|
|
||||||
<application />
|
<application />
|
||||||
|
|
||||||
|
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@ -10,7 +10,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
||||||
<artifactId>extras</artifactId>
|
<artifactId>extras</artifactId>
|
||||||
<version>1.4.2</version>
|
<version>2.1.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -0,0 +1,68 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011, 2012 Chris Banes.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.handmark.pulltorefresh.extras.listfragment;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.ListFragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AbsListView;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||||
|
|
||||||
|
abstract class PullToRefreshBaseListFragment<T extends PullToRefreshBase<? extends AbsListView>> extends ListFragment {
|
||||||
|
|
||||||
|
private T mPullToRefreshListView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
View layout = super.onCreateView(inflater, container, savedInstanceState);
|
||||||
|
|
||||||
|
ListView lv = (ListView) layout.findViewById(android.R.id.list);
|
||||||
|
ViewGroup parent = (ViewGroup) lv.getParent();
|
||||||
|
|
||||||
|
// Remove ListView and add PullToRefreshListView in its place
|
||||||
|
int lvIndex = parent.indexOfChild(lv);
|
||||||
|
parent.removeViewAt(lvIndex);
|
||||||
|
mPullToRefreshListView = onCreatePullToRefreshListView(inflater, savedInstanceState);
|
||||||
|
parent.addView(mPullToRefreshListView, lvIndex, lv.getLayoutParams());
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The {@link PullToRefreshBase} attached to this ListFragment.
|
||||||
|
*/
|
||||||
|
public final T getPullToRefreshListView() {
|
||||||
|
return mPullToRefreshListView;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@link PullToRefreshBase} which will replace the ListView
|
||||||
|
* created from ListFragment. You should override this method if you wish to
|
||||||
|
* customise the {@link PullToRefreshBase} from the default.
|
||||||
|
*
|
||||||
|
* @param inflater - LayoutInflater which can be used to inflate from XML.
|
||||||
|
* @param savedInstanceState - Bundle passed through from
|
||||||
|
* {@link ListFragment#onCreateView(LayoutInflater, ViewGroup, Bundle)
|
||||||
|
* onCreateView(...)}
|
||||||
|
* @return The {@link PullToRefreshBase} which will replace the ListView.
|
||||||
|
*/
|
||||||
|
protected abstract T onCreatePullToRefreshListView(LayoutInflater inflater, Bundle savedInstanceState);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011, 2012 Chris Banes.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.handmark.pulltorefresh.extras.listfragment;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.ListFragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshExpandableListView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sample implementation of how to use {@link PullToRefreshExpandableListView}
|
||||||
|
* with {@link ListFragment}. This implementation simply replaces the ListView
|
||||||
|
* that {@code ListFragment} creates with a new
|
||||||
|
* {@code PullToRefreshExpandableListView}. This means that ListFragment still
|
||||||
|
* works 100% (e.g. <code>setListShown(...)</code> ).
|
||||||
|
* <p/>
|
||||||
|
* The new PullToRefreshListView is created in the method
|
||||||
|
* {@link #onCreatePullToRefreshListView(LayoutInflater, Bundle)}. If you wish
|
||||||
|
* to customise the {@code PullToRefreshExpandableListView} then override this
|
||||||
|
* method and return your customised instance.
|
||||||
|
*
|
||||||
|
* @author Chris Banes
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PullToRefreshExpandableListFragment extends PullToRefreshBaseListFragment<PullToRefreshExpandableListView> {
|
||||||
|
|
||||||
|
protected PullToRefreshExpandableListView onCreatePullToRefreshListView(LayoutInflater inflater,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
return new PullToRefreshExpandableListView(getActivity());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -18,66 +18,25 @@ package com.handmark.pulltorefresh.extras.listfragment;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.ListFragment;
|
import android.support.v4.app.ListFragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import com.handmark.pulltorefresh.library.PullToRefreshListView;
|
import com.handmark.pulltorefresh.library.PullToRefreshListView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A sample implementation of how to the PullToRefreshListView with
|
* A sample implementation of how to use {@link PullToRefreshListView} with
|
||||||
* ListFragment. This implementation simply replaces the ListView that
|
* {@link ListFragment}. This implementation simply replaces the ListView that
|
||||||
* ListFragment creates with a new PullToRefreshListView. This means that
|
* {@code ListFragment} creates with a new PullToRefreshListView. This means
|
||||||
* ListFragment still works 100% (e.g. <code>setListShown(...)</code>).
|
* that ListFragment still works 100% (e.g. <code>setListShown(...)</code> ).
|
||||||
*
|
* <p/>
|
||||||
* The new PullToRefreshListView is created in the method
|
* The new PullToRefreshListView is created in the method
|
||||||
* <code>onCreatePullToRefreshListView()</code>. If you wish to customise the
|
* {@link #onCreatePullToRefreshListView(LayoutInflater, Bundle)}. If you wish
|
||||||
* PullToRefreshListView then override this method and return your customised
|
* to customise the {@code PullToRefreshListView} then override this method and
|
||||||
* instance.
|
* return your customised instance.
|
||||||
*
|
*
|
||||||
* @author Chris Banes
|
* @author Chris Banes
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class PullToRefreshListFragment extends ListFragment {
|
public class PullToRefreshListFragment extends PullToRefreshBaseListFragment<PullToRefreshListView> {
|
||||||
|
|
||||||
private PullToRefreshListView mPullToRefreshListView;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
||||||
View layout = super.onCreateView(inflater, container, savedInstanceState);
|
|
||||||
|
|
||||||
ListView lv = (ListView) layout.findViewById(android.R.id.list);
|
|
||||||
ViewGroup parent = (ViewGroup) lv.getParent();
|
|
||||||
|
|
||||||
//Remove ListView and add PullToRefreshListView in its place
|
|
||||||
int lvIndex = parent.indexOfChild(lv);
|
|
||||||
parent.removeViewAt(lvIndex);
|
|
||||||
mPullToRefreshListView = onCreatePullToRefreshListView(inflater, savedInstanceState);
|
|
||||||
parent.addView(mPullToRefreshListView, lvIndex, lv.getLayoutParams());
|
|
||||||
|
|
||||||
return layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The {@link PullToRefreshListView} attached to this ListFragment.
|
|
||||||
*/
|
|
||||||
public final PullToRefreshListView getPullToRefreshListView() {
|
|
||||||
return mPullToRefreshListView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the {@link PullToRefreshListView} which will replace the ListView
|
|
||||||
* created from ListFragment. You should override this method if you wish to
|
|
||||||
* customise the {@link PullToRefreshListView} from the default.
|
|
||||||
*
|
|
||||||
* @param inflater
|
|
||||||
* - LayoutInflater which can be used to inflate from XML.
|
|
||||||
* @param savedInstanceState
|
|
||||||
* - Bundle passed through from
|
|
||||||
* {@link ListFragment#onCreateView(LayoutInflater, ViewGroup, Bundle)
|
|
||||||
* onCreateView(...)}
|
|
||||||
* @return The {@link PullToRefreshListView} which will replace the
|
|
||||||
* ListView.
|
|
||||||
*/
|
|
||||||
protected PullToRefreshListView onCreatePullToRefreshListView(LayoutInflater inflater, Bundle savedInstanceState) {
|
protected PullToRefreshListView onCreatePullToRefreshListView(LayoutInflater inflater, Bundle savedInstanceState) {
|
||||||
return new PullToRefreshListView(getActivity());
|
return new PullToRefreshListView(getActivity());
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.handmark.pulltorefresh.extras.viewpager"
|
||||||
|
android:versionCode="2110"
|
||||||
|
android:versionName="2.1.1" >
|
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="4" />
|
||||||
|
|
||||||
|
<application />
|
||||||
|
|
||||||
|
</manifest>
|
@ -0,0 +1,17 @@
|
|||||||
|
# This file is used to override default values used by the Ant build system.
|
||||||
|
#
|
||||||
|
# This file must be checked into Version Control Systems, as it is
|
||||||
|
# integral to the build system of your project.
|
||||||
|
|
||||||
|
# This file is only used by the Ant script.
|
||||||
|
|
||||||
|
# You can use this to override default values such as
|
||||||
|
# 'source.dir' for the location of your java source folder and
|
||||||
|
# 'out.dir' for the location of your output folder.
|
||||||
|
|
||||||
|
# You can also use it define how the release builds are signed by declaring
|
||||||
|
# the following properties:
|
||||||
|
# 'key.store' for the location of your keystore and
|
||||||
|
# 'key.alias' for the name of the key to use.
|
||||||
|
# The password will be asked during the build when you use the 'release' target.
|
||||||
|
|
@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
||||||
|
<artifactId>extra-viewpager</artifactId>
|
||||||
|
<packaging>apklib</packaging>
|
||||||
|
<name>Android-PullToRefresh Extras: ViewPager</name>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
||||||
|
<artifactId>extras</artifactId>
|
||||||
|
<version>2.1.1</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.android</groupId>
|
||||||
|
<artifactId>android</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.android</groupId>
|
||||||
|
<artifactId>support-v4</artifactId>
|
||||||
|
<version>r7</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>library</artifactId>
|
||||||
|
<type>apklib</type>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||||
|
<artifactId>android-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-eclipse-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,16 @@
|
|||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must be checked in Version Control Systems.
|
||||||
|
#
|
||||||
|
# To customize properties used by the Ant build system edit
|
||||||
|
# "ant.properties", and override values to adapt the script to your
|
||||||
|
# project structure.
|
||||||
|
#
|
||||||
|
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
|
||||||
|
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
|
android.library=true
|
||||||
|
# Project target.
|
||||||
|
target=android-16
|
||||||
|
android.library.reference.1=../../library
|
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<!-- Need this for Maven, otherwise it doesn't build. I hate Maven. -->
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
|
||||||
|
<item type="id" name="viewpager" />
|
||||||
|
|
||||||
|
</resources>
|
@ -0,0 +1,70 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011, 2012 Chris Banes.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.handmark.pulltorefresh.extras.viewpager;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.v4.view.PagerAdapter;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||||
|
|
||||||
|
public class PullToRefreshViewPager extends PullToRefreshBase<ViewPager> {
|
||||||
|
|
||||||
|
public PullToRefreshViewPager(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PullToRefreshViewPager(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Orientation getPullToRefreshScrollDirection() {
|
||||||
|
return Orientation.HORIZONTAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ViewPager createRefreshableView(Context context, AttributeSet attrs) {
|
||||||
|
ViewPager viewPager = new ViewPager(context, attrs);
|
||||||
|
viewPager.setId(R.id.viewpager);
|
||||||
|
return viewPager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isReadyForPullStart() {
|
||||||
|
ViewPager refreshableView = getRefreshableView();
|
||||||
|
|
||||||
|
PagerAdapter adapter = refreshableView.getAdapter();
|
||||||
|
if (null != adapter) {
|
||||||
|
return refreshableView.getCurrentItem() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isReadyForPullEnd() {
|
||||||
|
ViewPager refreshableView = getRefreshableView();
|
||||||
|
|
||||||
|
PagerAdapter adapter = refreshableView.getAdapter();
|
||||||
|
if (null != adapter) {
|
||||||
|
return refreshableView.getCurrentItem() == adapter.getCount() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -10,10 +10,11 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<version>1.4.2</version>
|
<version>2.1.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>PullToRefreshListFragment</module>
|
<module>PullToRefreshListFragment</module>
|
||||||
|
<module>PullToRefreshViewPager</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.handmark.pulltorefresh.library"
|
package="com.handmark.pulltorefresh.library"
|
||||||
android:versionCode="1420"
|
android:versionCode="2110"
|
||||||
android:versionName="1.4.2" >
|
android:versionName="2.1.1" >
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="4" />
|
<uses-sdk android:minSdkVersion="4" />
|
||||||
|
|
||||||
|
202
plugins/Android-PullToRefresh/library/LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
@ -10,7 +10,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<version>1.4.2</version>
|
<version>2.1.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 667 B |
Before Width: | Height: | Size: 48 KiB |
After Width: | Height: | Size: 390 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 419 B |
After Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 477 B |
Before Width: | Height: | Size: 486 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 429 B |
@ -1,47 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginRight="@dimen/header_footer_internal_padding" >
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/pull_to_refresh_image"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content" />
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/pull_to_refresh_progress"
|
|
||||||
style="?android:attr/progressBarStyleSmall"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_gravity="center"
|
|
||||||
android:indeterminate="true"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="0px"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:orientation="vertical" >
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pull_to_refresh_text"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pull_to_refresh_sub_text"
|
|
||||||
android:layout_width="fill_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</merge>
|
|
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/fl_inner"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:paddingBottom="@dimen/header_footer_top_bottom_padding"
|
||||||
|
android:paddingLeft="@dimen/header_footer_left_right_padding"
|
||||||
|
android:paddingRight="@dimen/header_footer_left_right_padding"
|
||||||
|
android:paddingTop="@dimen/header_footer_top_bottom_padding" >
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/pull_to_refresh_image"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/pull_to_refresh_progress"
|
||||||
|
style="?android:attr/progressBarStyleSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</merge>
|
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/fl_inner"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingBottom="@dimen/header_footer_top_bottom_padding"
|
||||||
|
android:paddingLeft="@dimen/header_footer_left_right_padding"
|
||||||
|
android:paddingRight="@dimen/header_footer_left_right_padding"
|
||||||
|
android:paddingTop="@dimen/header_footer_top_bottom_padding" >
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="left|center_vertical" >
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/pull_to_refresh_image"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/pull_to_refresh_progress"
|
||||||
|
style="?android:attr/progressBarStyleSmall"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pull_to_refresh_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearance"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pull_to_refresh_sub_text"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</merge>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="pull_to_refresh_pull_label">اسحب للتحديث…</string>
|
||||||
|
<string name="pull_to_refresh_release_label">اترك للتحديث…</string>
|
||||||
|
<string name="pull_to_refresh_refreshing_label">تحميل…</string>
|
||||||
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Tažením aktualizujete…</string>
|
<string name="pull_to_refresh_pull_label">Tažením aktualizujete…</string>
|
||||||
<string name="pull_to_refresh_release_label">Uvolněním aktualizujete…</string>
|
<string name="pull_to_refresh_release_label">Uvolněním aktualizujete…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Načítání…</string>
|
<string name="pull_to_refresh_refreshing_label">Načítání…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Ziehen zum Aktualisieren…</string>
|
<string name="pull_to_refresh_pull_label">Ziehen zum Aktualisieren…</string>
|
||||||
<string name="pull_to_refresh_release_label">Loslassen zum Aktualisieren…</string>
|
<string name="pull_to_refresh_release_label">Loslassen zum Aktualisieren…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Laden…</string>
|
<string name="pull_to_refresh_refreshing_label">Laden…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Tire para actualizar…</string>
|
<string name="pull_to_refresh_pull_label">Tirar para actualizar…</string>
|
||||||
<string name="pull_to_refresh_release_label">Deslice para actualizar…</string>
|
<string name="pull_to_refresh_release_label">Soltar para actualizar…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Cargando…</string>
|
<string name="pull_to_refresh_refreshing_label">Cargando…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Tirez pour rafraîchir…</string>
|
<string name="pull_to_refresh_pull_label">Tirez pour rafraîchir…</string>
|
||||||
<string name="pull_to_refresh_release_label">Relâcher pour rafraîchir…</string>
|
<string name="pull_to_refresh_release_label">Relâcher pour rafraîchir…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Chargement…</string>
|
<string name="pull_to_refresh_refreshing_label">Chargement…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="pull_to_refresh_pull_label">משוך לרענון…</string>
|
||||||
|
<string name="pull_to_refresh_release_label">שחרר לרענון…</string>
|
||||||
|
<string name="pull_to_refresh_refreshing_label">טוען…</string>
|
||||||
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Tira per aggiornare…</string>
|
<string name="pull_to_refresh_pull_label">Tira per aggiornare…</string>
|
||||||
<string name="pull_to_refresh_release_label">Rilascia per aggionare…</string>
|
<string name="pull_to_refresh_release_label">Rilascia per aggionare…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Caricamento…</string>
|
<string name="pull_to_refresh_refreshing_label">Caricamento…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="pull_to_refresh_pull_label">משוך לרענון…</string>
|
||||||
|
<string name="pull_to_refresh_release_label">שחרר לרענון…</string>
|
||||||
|
<string name="pull_to_refresh_refreshing_label">טוען…</string>
|
||||||
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">画面を引っ張って…</string>
|
<string name="pull_to_refresh_pull_label">画面を引っ張って…</string>
|
||||||
<string name="pull_to_refresh_release_label">指を離すと更新…</string>
|
<string name="pull_to_refresh_release_label">指を離して更新…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">読み込み中…</string>
|
<string name="pull_to_refresh_refreshing_label">読み込み中…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">당겨서 새로 고침…</string>
|
<string name="pull_to_refresh_pull_label">당겨서 새로 고침…</string>
|
||||||
<string name="pull_to_refresh_release_label">놓아서 새로 고침…</string>
|
<string name="pull_to_refresh_release_label">놓아서 새로 고침…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">로딩 중…</string>
|
<string name="pull_to_refresh_refreshing_label">로드 중…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Sleep om te vernieuwen…</string>
|
<string name="pull_to_refresh_pull_label">Sleep om te vernieuwen…</string>
|
||||||
<string name="pull_to_refresh_release_label">Loslaten om te vernieuwen…</string>
|
<string name="pull_to_refresh_release_label">Loslaten om te vernieuwen…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Laden…</string>
|
<string name="pull_to_refresh_refreshing_label">Laden…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Pociągnij, aby odświeżyć…</string>
|
<string name="pull_to_refresh_pull_label">Pociągnij, aby odświeżyć…</string>
|
||||||
<string name="pull_to_refresh_release_label">Puść, aby odświeżyć…</string>
|
<string name="pull_to_refresh_release_label">Puść, aby odświeżyć…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Trwa ładowanie…</string>
|
<string name="pull_to_refresh_refreshing_label">Wczytywanie…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Puxe para atualizar…</string>
|
<string name="pull_to_refresh_pull_label">Puxe para atualizar…</string>
|
||||||
<string name="pull_to_refresh_release_label">Libere para atualizar…</string>
|
<string name="pull_to_refresh_release_label">Libere para atualizar…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Carregando…</string>
|
<string name="pull_to_refresh_refreshing_label">Carregando…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Puxe para atualizar…</string>
|
<string name="pull_to_refresh_pull_label">Puxe para atualizar…</string>
|
||||||
<string name="pull_to_refresh_release_label">Liberação para atualizar…</string>
|
<string name="pull_to_refresh_release_label">Liberação para atualizar…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">A carregar…</string>
|
<string name="pull_to_refresh_refreshing_label">A carregar…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="pull_to_refresh_pull_label">Trage pentru a reîmprospăta…</string>
|
||||||
|
<string name="pull_to_refresh_release_label">Eliberează pentru a reîmprospăta…</string>
|
||||||
|
<string name="pull_to_refresh_refreshing_label">Încărcare…</string>
|
||||||
|
</resources>
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">Потяните для обновления…</string>
|
<string name="pull_to_refresh_pull_label">Потяните для обновления…</string>
|
||||||
<string name="pull_to_refresh_release_label">Отпустите для обновления…</string>
|
<string name="pull_to_refresh_release_label">Отпустите для обновления…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Загрузка…</string>
|
<string name="pull_to_refresh_refreshing_label">Загрузка…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="pull_to_refresh_pull_label">下拉刷新…</string>
|
<string name="pull_to_refresh_pull_label">下拉刷新…</string>
|
||||||
<string name="pull_to_refresh_release_label">松手刷新…</string>
|
<string name="pull_to_refresh_release_label">放开以刷新…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">载入中…</string>
|
<string name="pull_to_refresh_refreshing_label">正在载入…</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -2,27 +2,79 @@
|
|||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<declare-styleable name="PullToRefresh">
|
<declare-styleable name="PullToRefresh">
|
||||||
<attr name="ptrAdapterViewBackground" format="reference|color" />
|
|
||||||
|
<!-- A drawable to use as the background of the Refreshable View -->
|
||||||
|
<attr name="ptrRefreshableViewBackground" format="reference|color" />
|
||||||
|
|
||||||
|
<!-- A drawable to use as the background of the Header and Footer Loading Views -->
|
||||||
<attr name="ptrHeaderBackground" format="reference|color" />
|
<attr name="ptrHeaderBackground" format="reference|color" />
|
||||||
|
|
||||||
|
<!-- Text Color of the Header and Footer Loading Views -->
|
||||||
<attr name="ptrHeaderTextColor" format="reference|color" />
|
<attr name="ptrHeaderTextColor" format="reference|color" />
|
||||||
|
|
||||||
|
<!-- Text Color of the Header and Footer Loading Views Sub Header -->
|
||||||
<attr name="ptrHeaderSubTextColor" format="reference|color" />
|
<attr name="ptrHeaderSubTextColor" format="reference|color" />
|
||||||
|
|
||||||
|
<!-- Mode of Pull-to-Refresh that should be used -->
|
||||||
<attr name="ptrMode">
|
<attr name="ptrMode">
|
||||||
<flag name="disabled" value="0x0" />
|
<flag name="disabled" value="0x0" />
|
||||||
|
<flag name="pullFromStart" value="0x1" />
|
||||||
|
<flag name="pullFromEnd" value="0x2" />
|
||||||
|
<flag name="both" value="0x3" />
|
||||||
|
<flag name="manualOnly" value="0x4" />
|
||||||
|
|
||||||
|
<!-- These last two are depreacted -->
|
||||||
<flag name="pullDownFromTop" value="0x1" />
|
<flag name="pullDownFromTop" value="0x1" />
|
||||||
<flag name="pullUpFromBottom" value="0x2" />
|
<flag name="pullUpFromBottom" value="0x2" />
|
||||||
<flag name="both" value="0x3" />
|
|
||||||
</attr>
|
</attr>
|
||||||
|
|
||||||
|
<!-- Whether the Indicator overlay(s) should be used -->
|
||||||
<attr name="ptrShowIndicator" format="reference|boolean" />
|
<attr name="ptrShowIndicator" format="reference|boolean" />
|
||||||
|
|
||||||
|
<!-- Drawable to use as Loading Indicator. Changes both Header and Footer. -->
|
||||||
<attr name="ptrDrawable" format="reference" />
|
<attr name="ptrDrawable" format="reference" />
|
||||||
<attr name="ptrDrawableTop" format="reference" />
|
|
||||||
<attr name="ptrDrawableBottom" format="reference" />
|
<!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. -->
|
||||||
|
<attr name="ptrDrawableStart" format="reference" />
|
||||||
|
|
||||||
|
<!-- Drawable to use as Loading Indicator in the Footer View. Overrides value set in ptrDrawable. -->
|
||||||
|
<attr name="ptrDrawableEnd" format="reference" />
|
||||||
|
|
||||||
|
<!-- Whether Android's built-in Over Scroll should be utilised for Pull-to-Refresh. -->
|
||||||
<attr name="ptrOverScroll" format="reference|boolean" />
|
<attr name="ptrOverScroll" format="reference|boolean" />
|
||||||
|
|
||||||
|
<!-- Base text color, typeface, size, and style for Header and Footer Loading Views -->
|
||||||
<attr name="ptrHeaderTextAppearance" format="reference" />
|
<attr name="ptrHeaderTextAppearance" format="reference" />
|
||||||
|
|
||||||
|
<!-- Base text color, typeface, size, and style for Header and Footer Loading Views Sub Header -->
|
||||||
<attr name="ptrSubHeaderTextAppearance" format="reference" />
|
<attr name="ptrSubHeaderTextAppearance" format="reference" />
|
||||||
|
|
||||||
|
<!-- Style of Animation should be used displayed when pulling. -->
|
||||||
<attr name="ptrAnimationStyle">
|
<attr name="ptrAnimationStyle">
|
||||||
<flag name="rotate" value="0x0" />
|
<flag name="rotate" value="0x0" />
|
||||||
<flag name="flip" value="0x1" />
|
<flag name="flip" value="0x1" />
|
||||||
</attr>
|
</attr>
|
||||||
|
|
||||||
|
<!-- Whether the user can scroll while the View is Refreshing -->
|
||||||
|
<attr name="ptrScrollingWhileRefreshingEnabled" format="reference|boolean" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Whether PullToRefreshListView has it's extras enabled. This allows the user to be
|
||||||
|
able to scroll while refreshing, and behaves better. It acheives this by adding
|
||||||
|
Header and/or Footer Views to the ListView.
|
||||||
|
-->
|
||||||
|
<attr name="ptrListViewExtrasEnabled" format="reference|boolean" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Whether the Drawable should be continually rotated as you pull. This only
|
||||||
|
takes effect when using the 'Rotate' Animation Style.
|
||||||
|
-->
|
||||||
|
<attr name="ptrRotateDrawableWhilePulling" format="reference|boolean" />
|
||||||
|
|
||||||
|
<!-- BELOW HERE ARE DEPRECEATED. DO NOT USE. -->
|
||||||
|
<attr name="ptrAdapterViewBackground" format="reference|color" />
|
||||||
|
<attr name="ptrDrawableTop" format="reference" />
|
||||||
|
<attr name="ptrDrawableBottom" format="reference" />
|
||||||
</declare-styleable>
|
</declare-styleable>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -4,8 +4,7 @@
|
|||||||
<dimen name="indicator_right_padding">10dp</dimen>
|
<dimen name="indicator_right_padding">10dp</dimen>
|
||||||
<dimen name="indicator_corner_radius">12dp</dimen>
|
<dimen name="indicator_corner_radius">12dp</dimen>
|
||||||
<dimen name="indicator_internal_padding">4dp</dimen>
|
<dimen name="indicator_internal_padding">4dp</dimen>
|
||||||
<dimen name="header_footer_left_right_padding">25dp</dimen>
|
<dimen name="header_footer_left_right_padding">24dp</dimen>
|
||||||
<dimen name="header_footer_top_bottom_padding">10dp</dimen>
|
<dimen name="header_footer_top_bottom_padding">12dp</dimen>
|
||||||
<dimen name="header_footer_internal_padding">20dp</dimen>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
|
|
||||||
<string name="pull_to_refresh_pull_label">Pull to refresh…</string>
|
<string name="pull_to_refresh_pull_label">Pull to refresh…</string>
|
||||||
<string name="pull_to_refresh_release_label">Release to refresh…</string>
|
<string name="pull_to_refresh_release_label">Release to refresh…</string>
|
||||||
<string name="pull_to_refresh_refreshing_label">Loading…</string>
|
<string name="pull_to_refresh_refreshing_label">Loading…</string>
|
||||||
|
|
||||||
<!-- Just use standard Pull Down String when pulling up. These can be set for languages which require it -->
|
<!-- Just use standard Pull Down String when pulling up. These can be set for languages which require it -->
|
||||||
<string name="pull_to_refresh_from_bottom_pull_label">@string/pull_to_refresh_pull_label</string>
|
<string name="pull_to_refresh_from_bottom_pull_label">@string/pull_to_refresh_pull_label</string>
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.handmark.pulltorefresh.library;
|
||||||
|
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
public interface ILoadingLayout {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Last Updated Text. This displayed under the main label when
|
||||||
|
* Pulling
|
||||||
|
*
|
||||||
|
* @param label - Label to set
|
||||||
|
*/
|
||||||
|
public void setLastUpdatedLabel(CharSequence label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the drawable used in the loading layout. This is the same as calling
|
||||||
|
* <code>setLoadingDrawable(drawable, Mode.BOTH)</code>
|
||||||
|
*
|
||||||
|
* @param drawable - Drawable to display
|
||||||
|
*/
|
||||||
|
public void setLoadingDrawable(Drawable drawable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Text to show when the Widget is being Pulled
|
||||||
|
* <code>setPullLabel(releaseLabel, Mode.BOTH)</code>
|
||||||
|
*
|
||||||
|
* @param pullLabel - CharSequence to display
|
||||||
|
*/
|
||||||
|
public void setPullLabel(CharSequence pullLabel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Text to show when the Widget is refreshing
|
||||||
|
* <code>setRefreshingLabel(releaseLabel, Mode.BOTH)</code>
|
||||||
|
*
|
||||||
|
* @param refreshingLabel - CharSequence to display
|
||||||
|
*/
|
||||||
|
public void setRefreshingLabel(CharSequence refreshingLabel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set Text to show when the Widget is being pulled, and will refresh when
|
||||||
|
* released. This is the same as calling
|
||||||
|
* <code>setReleaseLabel(releaseLabel, Mode.BOTH)</code>
|
||||||
|
*
|
||||||
|
* @param releaseLabel - CharSequence to display
|
||||||
|
*/
|
||||||
|
public void setReleaseLabel(CharSequence releaseLabel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set's the Sets the typeface and style in which the text should be
|
||||||
|
* displayed. Please see
|
||||||
|
* {@link android.widget.TextView#setTypeface(Typeface)
|
||||||
|
* TextView#setTypeface(Typeface)}.
|
||||||
|
*/
|
||||||
|
public void setTextTypeface(Typeface tf);
|
||||||
|
|
||||||
|
}
|
@ -15,7 +15,6 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.handmark.pulltorefresh.library;
|
package com.handmark.pulltorefresh.library;
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
|
|
||||||
@ -27,6 +26,17 @@ import com.handmark.pulltorefresh.library.PullToRefreshBase.State;
|
|||||||
|
|
||||||
public interface IPullToRefresh<T extends View> {
|
public interface IPullToRefresh<T extends View> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demos the Pull-to-Refresh functionality to the user so that they are
|
||||||
|
* aware it is there. This could be useful when the user first opens your
|
||||||
|
* app, etc. The animation will only happen if the Refresh View (ListView,
|
||||||
|
* ScrollView, etc) is in a state where a Pull-to-Refresh could occur by a
|
||||||
|
* user's touch gesture (i.e. scrolled to the top/bottom).
|
||||||
|
*
|
||||||
|
* @return true - if the Demo has been started, false if not.
|
||||||
|
*/
|
||||||
|
public boolean demo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the mode that this view is currently in. This is only really useful
|
* Get the mode that this view is currently in. This is only really useful
|
||||||
* when using <code>Mode.BOTH</code>.
|
* when using <code>Mode.BOTH</code>.
|
||||||
@ -46,6 +56,34 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
*/
|
*/
|
||||||
public boolean getFilterTouchEvents();
|
public boolean getFilterTouchEvents();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a proxy object which allows you to call methods on all of the
|
||||||
|
* LoadingLayouts (the Views which show when Pulling/Refreshing).
|
||||||
|
* <p />
|
||||||
|
* You should not keep the result of this method any longer than you need
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
* @return Object which will proxy any calls you make on it, to all of the
|
||||||
|
* LoadingLayouts.
|
||||||
|
*/
|
||||||
|
public ILoadingLayout getLoadingLayoutProxy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a proxy object which allows you to call methods on the
|
||||||
|
* LoadingLayouts (the Views which show when Pulling/Refreshing). The actual
|
||||||
|
* LoadingLayout(s) which will be affected, are chosen by the parameters you
|
||||||
|
* give.
|
||||||
|
* <p />
|
||||||
|
* You should not keep the result of this method any longer than you need
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
* @param includeStart - Whether to include the Start/Header Views
|
||||||
|
* @param includeEnd - Whether to include the End/Footer Views
|
||||||
|
* @return Object which will proxy any calls you make on it, to the
|
||||||
|
* LoadingLayouts included.
|
||||||
|
*/
|
||||||
|
public ILoadingLayout getLoadingLayoutProxy(boolean includeStart, boolean includeEnd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the mode that this view has been set to. If this returns
|
* Get the mode that this view has been set to. If this returns
|
||||||
* <code>Mode.BOTH</code>, you can use <code>getCurrentMode()</code> to
|
* <code>Mode.BOTH</code>, you can use <code>getCurrentMode()</code> to
|
||||||
@ -77,12 +115,11 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
public State getState();
|
public State getState();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the widget has disabled scrolling on the Refreshable View
|
* Whether Pull-to-Refresh is enabled
|
||||||
* while refreshing.
|
|
||||||
*
|
*
|
||||||
* @return true if the widget has disabled scrolling while refreshing
|
* @return enabled
|
||||||
*/
|
*/
|
||||||
public boolean isDisableScrollingWhileRefreshing();
|
public boolean isPullToRefreshEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether Overscroll support is enabled. This is different to
|
* Gets whether Overscroll support is enabled. This is different to
|
||||||
@ -94,13 +131,6 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
*/
|
*/
|
||||||
public boolean isPullToRefreshOverScrollEnabled();
|
public boolean isPullToRefreshOverScrollEnabled();
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether Pull-to-Refresh is enabled
|
|
||||||
*
|
|
||||||
* @return enabled
|
|
||||||
*/
|
|
||||||
public boolean isPullToRefreshEnabled();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the Widget is currently in the Refreshing mState
|
* Returns whether the Widget is currently in the Refreshing mState
|
||||||
*
|
*
|
||||||
@ -108,21 +138,20 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
*/
|
*/
|
||||||
public boolean isRefreshing();
|
public boolean isRefreshing();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the widget has enabled scrolling on the Refreshable View
|
||||||
|
* while refreshing.
|
||||||
|
*
|
||||||
|
* @return true if the widget has enabled scrolling while refreshing
|
||||||
|
*/
|
||||||
|
public boolean isScrollingWhileRefreshingEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the current Refresh as complete. Will Reset the UI and hide the
|
* Mark the current Refresh as complete. Will Reset the UI and hide the
|
||||||
* Refreshing View
|
* Refreshing View
|
||||||
*/
|
*/
|
||||||
public void onRefreshComplete();
|
public void onRefreshComplete();
|
||||||
|
|
||||||
/**
|
|
||||||
* By default the Widget disabled scrolling on the Refreshable View while
|
|
||||||
* refreshing. This method can change this behaviour.
|
|
||||||
*
|
|
||||||
* @param disableScrollingWhileRefreshing
|
|
||||||
* - true if you want to disable scrolling while refreshing
|
|
||||||
*/
|
|
||||||
public void setDisableScrollingWhileRefreshing(boolean disableScrollingWhileRefreshing);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the Touch Events to be filtered or not. If set to true, then the View
|
* Set the Touch Events to be filtered or not. If set to true, then the View
|
||||||
* will only use touch events where the difference in the Y-axis is greater
|
* will only use touch events where the difference in the Y-axis is greater
|
||||||
@ -131,54 +160,22 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
* ViewPager), but will restrict which types of finger scrolls will trigger
|
* ViewPager), but will restrict which types of finger scrolls will trigger
|
||||||
* the View.
|
* the View.
|
||||||
*
|
*
|
||||||
* @param filterEvents
|
* @param filterEvents - true if you want to filter Touch Events. Default is
|
||||||
* - true if you want to filter Touch Events. Default is true.
|
* true.
|
||||||
*/
|
*/
|
||||||
public void setFilterTouchEvents(boolean filterEvents);
|
public void setFilterTouchEvents(boolean filterEvents);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the Last Updated Text. This displayed under the main label when
|
|
||||||
* Pulling
|
|
||||||
*
|
|
||||||
* @param label
|
|
||||||
* - Label to set
|
|
||||||
*/
|
|
||||||
public void setLastUpdatedLabel(CharSequence label);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the drawable used in the loading layout. This is the same as calling
|
|
||||||
* <code>setLoadingDrawable(drawable, Mode.BOTH)</code>
|
|
||||||
*
|
|
||||||
* @param drawable
|
|
||||||
* - Drawable to display
|
|
||||||
*/
|
|
||||||
public void setLoadingDrawable(Drawable drawable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the drawable used in the loading layout.
|
|
||||||
*
|
|
||||||
* @param drawable
|
|
||||||
* - Drawable to display
|
|
||||||
* @param mode
|
|
||||||
* - Controls which Header/Footer Views will be updated.
|
|
||||||
* <code>Mode.BOTH</code> will update all available, other values
|
|
||||||
* will update the relevant View.
|
|
||||||
*/
|
|
||||||
public void setLoadingDrawable(Drawable drawable, Mode mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the mode of Pull-to-Refresh that this view will use.
|
* Set the mode of Pull-to-Refresh that this view will use.
|
||||||
*
|
*
|
||||||
* @param mode
|
* @param mode - Mode to set the View to
|
||||||
* - Mode to set the View to
|
|
||||||
*/
|
*/
|
||||||
public void setMode(Mode mode);
|
public void setMode(Mode mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set OnPullEventListener for the Widget
|
* Set OnPullEventListener for the Widget
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener - Listener to be used when the Widget has a pull event to
|
||||||
* - Listener to be used when the Widget has a pull event to
|
|
||||||
* propogate.
|
* propogate.
|
||||||
*/
|
*/
|
||||||
public void setOnPullEventListener(OnPullEventListener<T> listener);
|
public void setOnPullEventListener(OnPullEventListener<T> listener);
|
||||||
@ -186,16 +183,14 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
/**
|
/**
|
||||||
* Set OnRefreshListener for the Widget
|
* Set OnRefreshListener for the Widget
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener - Listener to be used when the Widget is set to Refresh
|
||||||
* - Listener to be used when the Widget is set to Refresh
|
|
||||||
*/
|
*/
|
||||||
public void setOnRefreshListener(OnRefreshListener<T> listener);
|
public void setOnRefreshListener(OnRefreshListener<T> listener);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set OnRefreshListener for the Widget
|
* Set OnRefreshListener for the Widget
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener - Listener to be used when the Widget is set to Refresh
|
||||||
* - Listener to be used when the Widget is set to Refresh
|
|
||||||
*/
|
*/
|
||||||
public void setOnRefreshListener(OnRefreshListener2<T> listener);
|
public void setOnRefreshListener(OnRefreshListener2<T> listener);
|
||||||
|
|
||||||
@ -204,32 +199,10 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
* Android's standard Overscroll support (the edge-glow). This setting only
|
* Android's standard Overscroll support (the edge-glow). This setting only
|
||||||
* takes effect when running on device with Android v2.3 or greater.
|
* takes effect when running on device with Android v2.3 or greater.
|
||||||
*
|
*
|
||||||
* @param enabled
|
* @param enabled - true if you want Overscroll enabled
|
||||||
* - true if you want Overscroll enabled
|
|
||||||
*/
|
*/
|
||||||
public void setPullToRefreshOverScrollEnabled(boolean enabled);
|
public void setPullToRefreshOverScrollEnabled(boolean enabled);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Text to show when the Widget is being Pulled
|
|
||||||
* <code>setPullLabel(releaseLabel, Mode.BOTH)</code>
|
|
||||||
*
|
|
||||||
* @param releaseLabel
|
|
||||||
* - CharSequence to display
|
|
||||||
*/
|
|
||||||
public void setPullLabel(CharSequence pullLabel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Text to show when the Widget is being Pulled
|
|
||||||
*
|
|
||||||
* @param pullLabel
|
|
||||||
* - CharSequence to display
|
|
||||||
* @param mode
|
|
||||||
* - Controls which Header/Footer Views will be updated.
|
|
||||||
* <code>Mode.BOTH</code> will update all available, other values
|
|
||||||
* will update the relevant View.
|
|
||||||
*/
|
|
||||||
public void setPullLabel(CharSequence pullLabel, Mode mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Widget to be in the refresh state. The UI will be updated to
|
* Sets the Widget to be in the refresh state. The UI will be updated to
|
||||||
* show the 'Refreshing' view, and be scrolled to show such.
|
* show the 'Refreshing' view, and be scrolled to show such.
|
||||||
@ -240,64 +213,28 @@ public interface IPullToRefresh<T extends View> {
|
|||||||
* Sets the Widget to be in the refresh state. The UI will be updated to
|
* Sets the Widget to be in the refresh state. The UI will be updated to
|
||||||
* show the 'Refreshing' view.
|
* show the 'Refreshing' view.
|
||||||
*
|
*
|
||||||
* @param doScroll
|
* @param doScroll - true if you want to force a scroll to the Refreshing
|
||||||
* - true if you want to force a scroll to the Refreshing view.
|
* view.
|
||||||
*/
|
*/
|
||||||
public void setRefreshing(boolean doScroll);
|
public void setRefreshing(boolean doScroll);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Text to show when the Widget is refreshing
|
|
||||||
* <code>setRefreshingLabel(releaseLabel, Mode.BOTH)</code>
|
|
||||||
*
|
|
||||||
* @param releaseLabel
|
|
||||||
* - CharSequence to display
|
|
||||||
*/
|
|
||||||
public void setRefreshingLabel(CharSequence refreshingLabel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Text to show when the Widget is refreshing
|
|
||||||
*
|
|
||||||
* @param refreshingLabel
|
|
||||||
* - CharSequence to display
|
|
||||||
* @param mode
|
|
||||||
* - Controls which Header/Footer Views will be updated.
|
|
||||||
* <code>Mode.BOTH</code> will update all available, other values
|
|
||||||
* will update the relevant View.
|
|
||||||
*/
|
|
||||||
public void setRefreshingLabel(CharSequence refreshingLabel, Mode mode);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Text to show when the Widget is being pulled, and will refresh when
|
|
||||||
* released. This is the same as calling
|
|
||||||
* <code>setReleaseLabel(releaseLabel, Mode.BOTH)</code>
|
|
||||||
*
|
|
||||||
* @param releaseLabel
|
|
||||||
* - CharSequence to display
|
|
||||||
*/
|
|
||||||
public void setReleaseLabel(CharSequence releaseLabel);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set Text to show when the Widget is being pulled, and will refresh when
|
|
||||||
* released
|
|
||||||
*
|
|
||||||
* @param releaseLabel
|
|
||||||
* - CharSequence to display
|
|
||||||
* @param mode
|
|
||||||
* - Controls which Header/Footer Views will be updated.
|
|
||||||
* <code>Mode.BOTH</code> will update all available, other values
|
|
||||||
* will update the relevant View.
|
|
||||||
*/
|
|
||||||
public void setReleaseLabel(CharSequence releaseLabel, Mode mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Animation Interpolator that is used for animated scrolling.
|
* Sets the Animation Interpolator that is used for animated scrolling.
|
||||||
* Defaults to a DecelerateInterpolator
|
* Defaults to a DecelerateInterpolator
|
||||||
*
|
*
|
||||||
* @param interpolator
|
* @param interpolator - Interpolator to use
|
||||||
* - Interpolator to use
|
|
||||||
*/
|
*/
|
||||||
public void setScrollAnimationInterpolator(Interpolator interpolator);
|
public void setScrollAnimationInterpolator(Interpolator interpolator);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default the Widget disables scrolling on the Refreshable View while
|
||||||
|
* refreshing. This method can change this behaviour.
|
||||||
|
*
|
||||||
|
* @param scrollingWhileRefreshingEnabled - true if you want to enable
|
||||||
|
* scrolling while refreshing
|
||||||
|
*/
|
||||||
|
public void setScrollingWhileRefreshingEnabled(boolean scrollingWhileRefreshingEnabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A mutator to enable/disable whether the 'Refreshing' View should be
|
* A mutator to enable/disable whether the 'Refreshing' View should be
|
||||||
* automatically shown when refreshing.
|
* automatically shown when refreshing.
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.handmark.pulltorefresh.library;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import android.graphics.Typeface;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.internal.LoadingLayout;
|
||||||
|
|
||||||
|
public class LoadingLayoutProxy implements ILoadingLayout {
|
||||||
|
|
||||||
|
private final HashSet<LoadingLayout> mLoadingLayouts;
|
||||||
|
|
||||||
|
LoadingLayoutProxy() {
|
||||||
|
mLoadingLayouts = new HashSet<LoadingLayout>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This allows you to add extra LoadingLayout instances to this proxy. This
|
||||||
|
* is only necessary if you keep your own instances, and want to have them
|
||||||
|
* included in any
|
||||||
|
* {@link PullToRefreshBase#createLoadingLayoutProxy(boolean, boolean)
|
||||||
|
* createLoadingLayoutProxy(...)} calls.
|
||||||
|
*
|
||||||
|
* @param layout - LoadingLayout to have included.
|
||||||
|
*/
|
||||||
|
public void addLayout(LoadingLayout layout) {
|
||||||
|
if (null != layout) {
|
||||||
|
mLoadingLayouts.add(layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLastUpdatedLabel(CharSequence label) {
|
||||||
|
for (LoadingLayout layout : mLoadingLayouts) {
|
||||||
|
layout.setLastUpdatedLabel(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLoadingDrawable(Drawable drawable) {
|
||||||
|
for (LoadingLayout layout : mLoadingLayouts) {
|
||||||
|
layout.setLoadingDrawable(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setRefreshingLabel(CharSequence refreshingLabel) {
|
||||||
|
for (LoadingLayout layout : mLoadingLayouts) {
|
||||||
|
layout.setRefreshingLabel(refreshingLabel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPullLabel(CharSequence label) {
|
||||||
|
for (LoadingLayout layout : mLoadingLayouts) {
|
||||||
|
layout.setPullLabel(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setReleaseLabel(CharSequence label) {
|
||||||
|
for (LoadingLayout layout : mLoadingLayouts) {
|
||||||
|
layout.setReleaseLabel(label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTextTypeface(Typeface tf) {
|
||||||
|
for (LoadingLayout layout : mLoadingLayouts) {
|
||||||
|
layout.setTextTypeface(tf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,9 +20,10 @@ import android.util.Log;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.State;
|
||||||
|
|
||||||
@TargetApi(9)
|
@TargetApi(9)
|
||||||
final class OverscrollHelper {
|
public final class OverscrollHelper {
|
||||||
|
|
||||||
static final String LOG_TAG = "OverscrollHelper";
|
static final String LOG_TAG = "OverscrollHelper";
|
||||||
static final float DEFAULT_OVERSCROLL_SCALE = 1f;
|
static final float DEFAULT_OVERSCROLL_SCALE = 1f;
|
||||||
@ -30,26 +31,26 @@ final class OverscrollHelper {
|
|||||||
/**
|
/**
|
||||||
* Helper method for Overscrolling that encapsulates all of the necessary
|
* Helper method for Overscrolling that encapsulates all of the necessary
|
||||||
* function.
|
* function.
|
||||||
*
|
* <p/>
|
||||||
* This should only be used on AdapterView's such as ListView as it just
|
* This should only be used on AdapterView's such as ListView as it just
|
||||||
* calls through to overScrollBy() with the scrollRange = 0. AdapterView's
|
* calls through to overScrollBy() with the scrollRange = 0. AdapterView's
|
||||||
* do not have a scroll range (i.e. getScrollY() doesn't work).
|
* do not have a scroll range (i.e. getScrollY() doesn't work).
|
||||||
*
|
*
|
||||||
* @param view
|
* @param view - PullToRefreshView that is calling this.
|
||||||
* - PullToRefreshView that is calling this.
|
* @param deltaX - Change in X in pixels, passed through from from
|
||||||
* @param deltaY
|
* overScrollBy call
|
||||||
* - Change in Y in pixels, passed through from from overScrollBy
|
* @param scrollX - Current X scroll value in pixels before applying deltaY,
|
||||||
* call
|
|
||||||
* @param scrollY
|
|
||||||
* - Current Y scroll value in pixels before applying deltaY,
|
|
||||||
* passed through from from overScrollBy call
|
* passed through from from overScrollBy call
|
||||||
* @param isTouchEvent
|
* @param deltaY - Change in Y in pixels, passed through from from
|
||||||
* - true if this scroll operation is the result of a touch
|
* overScrollBy call
|
||||||
* event, passed through from from overScrollBy call
|
* @param scrollY - Current Y scroll value in pixels before applying deltaY,
|
||||||
|
* passed through from from overScrollBy call
|
||||||
|
* @param isTouchEvent - true if this scroll operation is the result of a
|
||||||
|
* touch event, passed through from from overScrollBy call
|
||||||
*/
|
*/
|
||||||
static void overScrollBy(final PullToRefreshBase<?> view, final int deltaY, final int scrollY,
|
public static void overScrollBy(final PullToRefreshBase<?> view, final int deltaX, final int scrollX,
|
||||||
final boolean isTouchEvent) {
|
final int deltaY, final int scrollY, final boolean isTouchEvent) {
|
||||||
overScrollBy(view, deltaY, scrollY, 0, isTouchEvent);
|
overScrollBy(view, deltaX, scrollX, deltaY, scrollY, 0, isTouchEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,81 +58,116 @@ final class OverscrollHelper {
|
|||||||
* function. This version of the call is used for Views that need to specify
|
* function. This version of the call is used for Views that need to specify
|
||||||
* a Scroll Range but scroll back to it's edge correctly.
|
* a Scroll Range but scroll back to it's edge correctly.
|
||||||
*
|
*
|
||||||
* @param view
|
* @param view - PullToRefreshView that is calling this.
|
||||||
* - PullToRefreshView that is calling this.
|
* @param deltaX - Change in X in pixels, passed through from from
|
||||||
* @param deltaY
|
* overScrollBy call
|
||||||
* - Change in Y in pixels, passed through from from overScrollBy
|
* @param scrollX - Current X scroll value in pixels before applying deltaY,
|
||||||
* call
|
|
||||||
* @param scrollY
|
|
||||||
* - Current Y scroll value in pixels before applying deltaY,
|
|
||||||
* passed through from from overScrollBy call
|
* passed through from from overScrollBy call
|
||||||
* @param scrollRange
|
* @param deltaY - Change in Y in pixels, passed through from from
|
||||||
* - Scroll Range of the View, specifically needed for ScrollView
|
* overScrollBy call
|
||||||
* @param isTouchEvent
|
* @param scrollY - Current Y scroll value in pixels before applying deltaY,
|
||||||
* - true if this scroll operation is the result of a touch
|
* passed through from from overScrollBy call
|
||||||
* event, passed through from from overScrollBy call
|
* @param scrollRange - Scroll Range of the View, specifically needed for
|
||||||
|
* ScrollView
|
||||||
|
* @param isTouchEvent - true if this scroll operation is the result of a
|
||||||
|
* touch event, passed through from from overScrollBy call
|
||||||
*/
|
*/
|
||||||
static void overScrollBy(final PullToRefreshBase<?> view, final int deltaY, final int scrollY,
|
public static void overScrollBy(final PullToRefreshBase<?> view, final int deltaX, final int scrollX,
|
||||||
final int scrollRange, final boolean isTouchEvent) {
|
final int deltaY, final int scrollY, final int scrollRange, final boolean isTouchEvent) {
|
||||||
overScrollBy(view, deltaY, scrollY, scrollRange, 0, DEFAULT_OVERSCROLL_SCALE, isTouchEvent);
|
overScrollBy(view, deltaX, scrollX, deltaY, scrollY, scrollRange, 0, DEFAULT_OVERSCROLL_SCALE, isTouchEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for Overscrolling that encapsulates all of the necessary
|
* Helper method for Overscrolling that encapsulates all of the necessary
|
||||||
* function. This is the advanced version of the call.
|
* function. This is the advanced version of the call.
|
||||||
*
|
*
|
||||||
* @param view
|
* @param view - PullToRefreshView that is calling this.
|
||||||
* - PullToRefreshView that is calling this.
|
* @param deltaX - Change in X in pixels, passed through from from
|
||||||
* @param deltaY
|
* overScrollBy call
|
||||||
* - Change in Y in pixels, passed through from from overScrollBy
|
* @param scrollX - Current X scroll value in pixels before applying deltaY,
|
||||||
* call
|
|
||||||
* @param scrollY
|
|
||||||
* - Current Y scroll value in pixels before applying deltaY,
|
|
||||||
* passed through from from overScrollBy call
|
* passed through from from overScrollBy call
|
||||||
* @param scrollRange
|
* @param deltaY - Change in Y in pixels, passed through from from
|
||||||
* - Scroll Range of the View, specifically needed for ScrollView
|
* overScrollBy call
|
||||||
* @param fuzzyThreshold
|
* @param scrollY - Current Y scroll value in pixels before applying deltaY,
|
||||||
* - Threshold for which the values how fuzzy we should treat the
|
* passed through from from overScrollBy call
|
||||||
* other values. Needed for WebView as it doesn't always scroll
|
* @param scrollRange - Scroll Range of the View, specifically needed for
|
||||||
* back to it's edge. 0 = no fuzziness.
|
* ScrollView
|
||||||
* @param scaleFactor
|
* @param fuzzyThreshold - Threshold for which the values how fuzzy we
|
||||||
* - Scale Factor for overscroll amount
|
* should treat the other values. Needed for WebView as it
|
||||||
* @param isTouchEvent
|
* doesn't always scroll back to it's edge. 0 = no fuzziness.
|
||||||
* - true if this scroll operation is the result of a touch
|
* @param scaleFactor - Scale Factor for overscroll amount
|
||||||
* event, passed through from from overScrollBy call
|
* @param isTouchEvent - true if this scroll operation is the result of a
|
||||||
|
* touch event, passed through from from overScrollBy call
|
||||||
*/
|
*/
|
||||||
static void overScrollBy(final PullToRefreshBase<?> view, final int deltaY, final int scrollY,
|
public static void overScrollBy(final PullToRefreshBase<?> view, final int deltaX, final int scrollX,
|
||||||
final int scrollRange, final int fuzzyThreshold, final float scaleFactor, final boolean isTouchEvent) {
|
final int deltaY, final int scrollY, final int scrollRange, final int fuzzyThreshold,
|
||||||
|
final float scaleFactor, final boolean isTouchEvent) {
|
||||||
|
|
||||||
// Check that OverScroll is enabled
|
final int deltaValue, currentScrollValue, scrollValue;
|
||||||
if (view.isPullToRefreshOverScrollEnabled()) {
|
switch (view.getPullToRefreshScrollDirection()) {
|
||||||
|
case HORIZONTAL:
|
||||||
|
deltaValue = deltaX;
|
||||||
|
scrollValue = scrollX;
|
||||||
|
currentScrollValue = view.getScrollX();
|
||||||
|
break;
|
||||||
|
case VERTICAL:
|
||||||
|
default:
|
||||||
|
deltaValue = deltaY;
|
||||||
|
scrollValue = scrollY;
|
||||||
|
currentScrollValue = view.getScrollY();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that OverScroll is enabled and that we're not currently
|
||||||
|
// refreshing.
|
||||||
|
if (view.isPullToRefreshOverScrollEnabled() && !view.isRefreshing()) {
|
||||||
final Mode mode = view.getMode();
|
final Mode mode = view.getMode();
|
||||||
|
|
||||||
// Check that we're not disabled, and the event isn't from touch
|
// Check that Pull-to-Refresh is enabled, and the event isn't from
|
||||||
if (mode != Mode.DISABLED && !isTouchEvent && deltaY != 0) {
|
// touch
|
||||||
final int newY = (deltaY + scrollY);
|
if (mode.permitsPullToRefresh() && !isTouchEvent && deltaValue != 0) {
|
||||||
|
final int newScrollValue = (deltaValue + scrollValue);
|
||||||
|
|
||||||
if (PullToRefreshBase.DEBUG) {
|
if (PullToRefreshBase.DEBUG) {
|
||||||
Log.d(LOG_TAG, "OverScroll. DeltaY: " + deltaY + ", ScrollY: " + scrollY + ", NewY: " + newY
|
Log.d(LOG_TAG, "OverScroll. DeltaX: " + deltaX + ", ScrollX: " + scrollX + ", DeltaY: " + deltaY
|
||||||
+ ", ScrollRange: " + scrollRange);
|
+ ", ScrollY: " + scrollY + ", NewY: " + newScrollValue + ", ScrollRange: " + scrollRange
|
||||||
|
+ ", CurrentScroll: " + currentScrollValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newY < (0 - fuzzyThreshold)) {
|
if (newScrollValue < (0 - fuzzyThreshold)) {
|
||||||
// Check the mode supports the overscroll direction, and
|
// Check the mode supports the overscroll direction, and
|
||||||
// then move scroll
|
// then move scroll
|
||||||
if (mode.canPullDown()) {
|
if (mode.showHeaderLoadingLayout()) {
|
||||||
view.setHeaderScroll((int) (scaleFactor * (view.getScrollY() + newY)));
|
// If we're currently at zero, we're about to start
|
||||||
|
// overscrolling, so change the state
|
||||||
|
if (currentScrollValue == 0) {
|
||||||
|
view.setState(State.OVERSCROLLING);
|
||||||
|
}
|
||||||
|
|
||||||
|
view.setHeaderScroll((int) (scaleFactor * (currentScrollValue + newScrollValue)));
|
||||||
}
|
}
|
||||||
} else if (newY > (scrollRange + fuzzyThreshold)) {
|
} else if (newScrollValue > (scrollRange + fuzzyThreshold)) {
|
||||||
// Check the mode supports the overscroll direction, and
|
// Check the mode supports the overscroll direction, and
|
||||||
// then move scroll
|
// then move scroll
|
||||||
if (mode.canPullUp()) {
|
if (mode.showFooterLoadingLayout()) {
|
||||||
view.setHeaderScroll((int) (scaleFactor * (view.getScrollY() + newY - scrollRange)));
|
// If we're currently at zero, we're about to start
|
||||||
|
// overscrolling, so change the state
|
||||||
|
if (currentScrollValue == 0) {
|
||||||
|
view.setState(State.OVERSCROLLING);
|
||||||
|
}
|
||||||
|
|
||||||
|
view.setHeaderScroll((int) (scaleFactor * (currentScrollValue + newScrollValue - scrollRange)));
|
||||||
}
|
}
|
||||||
} else if (Math.abs(newY) <= fuzzyThreshold || Math.abs(newY - scrollRange) <= fuzzyThreshold) {
|
} else if (Math.abs(newScrollValue) <= fuzzyThreshold
|
||||||
|
|| Math.abs(newScrollValue - scrollRange) <= fuzzyThreshold) {
|
||||||
// Means we've stopped overscrolling, so scroll back to 0
|
// Means we've stopped overscrolling, so scroll back to 0
|
||||||
view.smoothScrollToLonger(0);
|
view.setState(State.RESET);
|
||||||
}
|
}
|
||||||
|
} else if (isTouchEvent && State.OVERSCROLLING == view.getState()) {
|
||||||
|
// This condition means that we were overscrolling from a fling,
|
||||||
|
// but the user has touched the View and is now overscrolling
|
||||||
|
// from touch instead. We need to just reset.
|
||||||
|
view.setState(State.RESET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import android.content.Context;
|
|||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@ -30,6 +29,7 @@ import android.widget.Adapter;
|
|||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
import android.widget.AdapterView.OnItemClickListener;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
|
|
||||||
import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor;
|
import com.handmark.pulltorefresh.library.internal.EmptyViewMethodAccessor;
|
||||||
@ -38,7 +38,23 @@ import com.handmark.pulltorefresh.library.internal.IndicatorLayout;
|
|||||||
public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extends PullToRefreshBase<T> implements
|
public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extends PullToRefreshBase<T> implements
|
||||||
OnScrollListener {
|
OnScrollListener {
|
||||||
|
|
||||||
private int mSavedLastVisibleIndex = -1;
|
private static FrameLayout.LayoutParams convertEmptyViewLayoutParams(ViewGroup.LayoutParams lp) {
|
||||||
|
FrameLayout.LayoutParams newLp = null;
|
||||||
|
|
||||||
|
if (null != lp) {
|
||||||
|
newLp = new FrameLayout.LayoutParams(lp);
|
||||||
|
|
||||||
|
if (lp instanceof LinearLayout.LayoutParams) {
|
||||||
|
newLp.gravity = ((LinearLayout.LayoutParams) lp).gravity;
|
||||||
|
} else {
|
||||||
|
newLp.gravity = Gravity.CENTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newLp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean mLastItemVisible;
|
||||||
private OnScrollListener mOnScrollListener;
|
private OnScrollListener mOnScrollListener;
|
||||||
private OnLastItemVisibleListener mOnLastItemVisibleListener;
|
private OnLastItemVisibleListener mOnLastItemVisibleListener;
|
||||||
private View mEmptyView;
|
private View mEmptyView;
|
||||||
@ -64,14 +80,17 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
mRefreshableView.setOnScrollListener(this);
|
mRefreshableView.setOnScrollListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract public ContextMenuInfo getContextMenuInfo();
|
public PullToRefreshAdapterViewBase(Context context, Mode mode, AnimationStyle animStyle) {
|
||||||
|
super(context, mode, animStyle);
|
||||||
|
mRefreshableView.setOnScrollListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets whether an indicator graphic should be displayed when the View is in
|
* Gets whether an indicator graphic should be displayed when the View is in
|
||||||
* a state where a Pull-to-Refresh can happen. An example of this state is
|
* a state where a Pull-to-Refresh can happen. An example of this state is
|
||||||
* when the Adapter View is scrolled to the top and the mode is set to
|
* when the Adapter View is scrolled to the top and the mode is set to
|
||||||
* {@link Mode#PULL_DOWN_TO_REFRESH}. The default value is <var>true</var>
|
* {@link Mode#PULL_FROM_START}. The default value is <var>true</var> if
|
||||||
* if {@link PullToRefreshBase#isPullToRefreshOverScrollEnabled()
|
* {@link PullToRefreshBase#isPullToRefreshOverScrollEnabled()
|
||||||
* isPullToRefreshOverScrollEnabled()} returns false.
|
* isPullToRefreshOverScrollEnabled()} returns false.
|
||||||
*
|
*
|
||||||
* @return true if the indicators will be shown
|
* @return true if the indicators will be shown
|
||||||
@ -85,26 +104,15 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(LOG_TAG, "First Visible: " + firstVisibleItem + ". Visible Count: " + visibleItemCount
|
Log.d(LOG_TAG, "First Visible: " + firstVisibleItem + ". Visible Count: " + visibleItemCount
|
||||||
+ ". Total Items: " + totalItemCount);
|
+ ". Total Items:" + totalItemCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a OnItemVisibleListener, do check...
|
/**
|
||||||
|
* Set whether the Last Item is Visible. lastVisibleItemIndex is a
|
||||||
|
* zero-based index, so we minus one totalItemCount to check
|
||||||
|
*/
|
||||||
if (null != mOnLastItemVisibleListener) {
|
if (null != mOnLastItemVisibleListener) {
|
||||||
|
mLastItemVisible = (totalItemCount > 0) && (firstVisibleItem + visibleItemCount >= totalItemCount - 1);
|
||||||
// Detect whether the last visible item has changed
|
|
||||||
final int lastVisibleItemIndex = firstVisibleItem + visibleItemCount;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check that the last item has changed, we have any items, and that
|
|
||||||
* the last item is visible. lastVisibleItemIndex is a zero-based
|
|
||||||
* index, so we add one to it to check against totalItemCount.
|
|
||||||
*/
|
|
||||||
if (visibleItemCount > 0 && (lastVisibleItemIndex + 1) == totalItemCount) {
|
|
||||||
if (lastVisibleItemIndex != mSavedLastVisibleIndex) {
|
|
||||||
mSavedLastVisibleIndex = lastVisibleItemIndex;
|
|
||||||
mOnLastItemVisibleListener.onLastItemVisible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're showing the indicator, check positions...
|
// If we're showing the indicator, check positions...
|
||||||
@ -118,19 +126,27 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void onScrollStateChanged(final AbsListView view, final int scrollState) {
|
public final void onScrollStateChanged(final AbsListView view, final int state) {
|
||||||
|
/**
|
||||||
|
* Check that the scrolling has stopped, and that the last item is
|
||||||
|
* visible.
|
||||||
|
*/
|
||||||
|
if (state == OnScrollListener.SCROLL_STATE_IDLE && null != mOnLastItemVisibleListener && mLastItemVisible) {
|
||||||
|
mOnLastItemVisibleListener.onLastItemVisible();
|
||||||
|
}
|
||||||
|
|
||||||
if (null != mOnScrollListener) {
|
if (null != mOnScrollListener) {
|
||||||
mOnScrollListener.onScrollStateChanged(view, scrollState);
|
mOnScrollListener.onScrollStateChanged(view, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pass-through method for {@link PullToRefreshBase#getRefreshableView()
|
* Pass-through method for {@link PullToRefreshBase#getRefreshableView()
|
||||||
* getRefreshableView()}.{@link AdapterView#setAdapter(ListAdapter)
|
* getRefreshableView()}.
|
||||||
|
* {@link AdapterView#setAdapter(android.widget.Adapter)}
|
||||||
* setAdapter(adapter)}. This is just for convenience!
|
* setAdapter(adapter)}. This is just for convenience!
|
||||||
*
|
*
|
||||||
* @param adapter
|
* @param adapter - Adapter to set
|
||||||
* - Adapter to set
|
|
||||||
*/
|
*/
|
||||||
public void setAdapter(ListAdapter adapter) {
|
public void setAdapter(ListAdapter adapter) {
|
||||||
((AdapterView<ListAdapter>) mRefreshableView).setAdapter(adapter);
|
((AdapterView<ListAdapter>) mRefreshableView).setAdapter(adapter);
|
||||||
@ -138,17 +154,16 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the Empty View to be used by the Adapter View.
|
* Sets the Empty View to be used by the Adapter View.
|
||||||
*
|
* <p/>
|
||||||
* We need it handle it ourselves so that we can Pull-to-Refresh when the
|
* We need it handle it ourselves so that we can Pull-to-Refresh when the
|
||||||
* Empty View is shown.
|
* Empty View is shown.
|
||||||
*
|
* <p/>
|
||||||
* Please note, you do <strong>not</strong> usually need to call this method
|
* Please note, you do <strong>not</strong> usually need to call this method
|
||||||
* yourself. Calling setEmptyView on the AdapterView will automatically call
|
* yourself. Calling setEmptyView on the AdapterView will automatically call
|
||||||
* this method and set everything up. This includes when the Android
|
* this method and set everything up. This includes when the Android
|
||||||
* Framework automatically sets the Empty View based on it's ID.
|
* Framework automatically sets the Empty View based on it's ID.
|
||||||
*
|
*
|
||||||
* @param newEmptyView
|
* @param newEmptyView - Empty View to be used
|
||||||
* - Empty View to be used
|
|
||||||
*/
|
*/
|
||||||
public final void setEmptyView(View newEmptyView) {
|
public final void setEmptyView(View newEmptyView) {
|
||||||
FrameLayout refreshableViewWrapper = getRefreshableViewWrapper();
|
FrameLayout refreshableViewWrapper = getRefreshableViewWrapper();
|
||||||
@ -168,8 +183,14 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
((ViewGroup) newEmptyViewParent).removeView(newEmptyView);
|
((ViewGroup) newEmptyViewParent).removeView(newEmptyView);
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshableViewWrapper.addView(newEmptyView, ViewGroup.LayoutParams.MATCH_PARENT,
|
// We need to convert any LayoutParams so that it works in our
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT);
|
// FrameLayout
|
||||||
|
FrameLayout.LayoutParams lp = convertEmptyViewLayoutParams(newEmptyView.getLayoutParams());
|
||||||
|
if (null != lp) {
|
||||||
|
refreshableViewWrapper.addView(newEmptyView, lp);
|
||||||
|
} else {
|
||||||
|
refreshableViewWrapper.addView(newEmptyView);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mRefreshableView instanceof EmptyViewMethodAccessor) {
|
if (mRefreshableView instanceof EmptyViewMethodAccessor) {
|
||||||
@ -186,8 +207,7 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
* {@link AdapterView#setOnItemClickListener(OnItemClickListener)
|
* {@link AdapterView#setOnItemClickListener(OnItemClickListener)
|
||||||
* setOnItemClickListener(listener)}. This is just for convenience!
|
* setOnItemClickListener(listener)}. This is just for convenience!
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener - OnItemClickListener to use
|
||||||
* - OnItemClickListener to use
|
|
||||||
*/
|
*/
|
||||||
public void setOnItemClickListener(OnItemClickListener listener) {
|
public void setOnItemClickListener(OnItemClickListener listener) {
|
||||||
mRefreshableView.setOnItemClickListener(listener);
|
mRefreshableView.setOnItemClickListener(listener);
|
||||||
@ -209,10 +229,9 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
* Sets whether an indicator graphic should be displayed when the View is in
|
* Sets whether an indicator graphic should be displayed when the View is in
|
||||||
* a state where a Pull-to-Refresh can happen. An example of this state is
|
* a state where a Pull-to-Refresh can happen. An example of this state is
|
||||||
* when the Adapter View is scrolled to the top and the mode is set to
|
* when the Adapter View is scrolled to the top and the mode is set to
|
||||||
* {@link Mode#PULL_DOWN_TO_REFRESH}
|
* {@link Mode#PULL_FROM_START}
|
||||||
*
|
*
|
||||||
* @param showIndicator
|
* @param showIndicator - true if the indicators should be shown.
|
||||||
* - true if the indicators should be shown.
|
|
||||||
*/
|
*/
|
||||||
public void setShowIndicator(boolean showIndicator) {
|
public void setShowIndicator(boolean showIndicator) {
|
||||||
mShowIndicator = showIndicator;
|
mShowIndicator = showIndicator;
|
||||||
@ -224,25 +243,30 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
// If not, then remove then
|
// If not, then remove then
|
||||||
removeIndicatorViews();
|
removeIndicatorViews();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onPullToRefresh() {
|
protected void onPullToRefresh() {
|
||||||
super.onPullToRefresh();
|
super.onPullToRefresh();
|
||||||
|
|
||||||
if (getShowIndicatorInternal()) {
|
if (getShowIndicatorInternal()) {
|
||||||
switch (getCurrentMode()) {
|
switch (getCurrentMode()) {
|
||||||
case PULL_UP_TO_REFRESH:
|
case PULL_FROM_END:
|
||||||
mIndicatorIvBottom.pullToRefresh();
|
mIndicatorIvBottom.pullToRefresh();
|
||||||
break;
|
break;
|
||||||
case PULL_DOWN_TO_REFRESH:
|
case PULL_FROM_START:
|
||||||
mIndicatorIvTop.pullToRefresh();
|
mIndicatorIvTop.pullToRefresh();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// NO-OP
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onRefreshing(boolean doScroll) {
|
protected void onRefreshing(boolean doScroll) {
|
||||||
super.onRefreshing(doScroll);
|
super.onRefreshing(doScroll);
|
||||||
|
|
||||||
if (getShowIndicatorInternal()) {
|
if (getShowIndicatorInternal()) {
|
||||||
@ -251,23 +275,26 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onReleaseToRefresh() {
|
protected void onReleaseToRefresh() {
|
||||||
super.onReleaseToRefresh();
|
super.onReleaseToRefresh();
|
||||||
|
|
||||||
if (getShowIndicatorInternal()) {
|
if (getShowIndicatorInternal()) {
|
||||||
switch (getCurrentMode()) {
|
switch (getCurrentMode()) {
|
||||||
case PULL_UP_TO_REFRESH:
|
case PULL_FROM_END:
|
||||||
mIndicatorIvBottom.releaseToRefresh();
|
mIndicatorIvBottom.releaseToRefresh();
|
||||||
break;
|
break;
|
||||||
case PULL_DOWN_TO_REFRESH:
|
case PULL_FROM_START:
|
||||||
mIndicatorIvTop.releaseToRefresh();
|
mIndicatorIvTop.releaseToRefresh();
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// NO-OP
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onReset() {
|
protected void onReset() {
|
||||||
super.onReset();
|
super.onReset();
|
||||||
|
|
||||||
if (getShowIndicatorInternal()) {
|
if (getShowIndicatorInternal()) {
|
||||||
@ -281,11 +308,11 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
mShowIndicator = a.getBoolean(R.styleable.PullToRefresh_ptrShowIndicator, !isPullToRefreshOverScrollEnabled());
|
mShowIndicator = a.getBoolean(R.styleable.PullToRefresh_ptrShowIndicator, !isPullToRefreshOverScrollEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isReadyForPullDown() {
|
protected boolean isReadyForPullStart() {
|
||||||
return isFirstItemVisible();
|
return isFirstItemVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isReadyForPullUp() {
|
protected boolean isReadyForPullEnd() {
|
||||||
return isLastItemVisible();
|
return isLastItemVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,31 +340,31 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
Mode mode = getMode();
|
Mode mode = getMode();
|
||||||
FrameLayout refreshableViewWrapper = getRefreshableViewWrapper();
|
FrameLayout refreshableViewWrapper = getRefreshableViewWrapper();
|
||||||
|
|
||||||
if (mode.canPullDown() && null == mIndicatorIvTop) {
|
if (mode.showHeaderLoadingLayout() && null == mIndicatorIvTop) {
|
||||||
// If the mode can pull down, and we don't have one set already
|
// If the mode can pull down, and we don't have one set already
|
||||||
mIndicatorIvTop = new IndicatorLayout(getContext(), Mode.PULL_DOWN_TO_REFRESH);
|
mIndicatorIvTop = new IndicatorLayout(getContext(), Mode.PULL_FROM_START);
|
||||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding);
|
params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding);
|
||||||
params.gravity = Gravity.TOP | Gravity.RIGHT;
|
params.gravity = Gravity.TOP | Gravity.RIGHT;
|
||||||
refreshableViewWrapper.addView(mIndicatorIvTop, params);
|
refreshableViewWrapper.addView(mIndicatorIvTop, params);
|
||||||
|
|
||||||
} else if (!mode.canPullDown() && null != mIndicatorIvTop) {
|
} else if (!mode.showHeaderLoadingLayout() && null != mIndicatorIvTop) {
|
||||||
// If we can't pull down, but have a View then remove it
|
// If we can't pull down, but have a View then remove it
|
||||||
refreshableViewWrapper.removeView(mIndicatorIvTop);
|
refreshableViewWrapper.removeView(mIndicatorIvTop);
|
||||||
mIndicatorIvTop = null;
|
mIndicatorIvTop = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode.canPullUp() && null == mIndicatorIvBottom) {
|
if (mode.showFooterLoadingLayout() && null == mIndicatorIvBottom) {
|
||||||
// If the mode can pull down, and we don't have one set already
|
// If the mode can pull down, and we don't have one set already
|
||||||
mIndicatorIvBottom = new IndicatorLayout(getContext(), Mode.PULL_UP_TO_REFRESH);
|
mIndicatorIvBottom = new IndicatorLayout(getContext(), Mode.PULL_FROM_END);
|
||||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding);
|
params.rightMargin = getResources().getDimensionPixelSize(R.dimen.indicator_right_padding);
|
||||||
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
|
params.gravity = Gravity.BOTTOM | Gravity.RIGHT;
|
||||||
refreshableViewWrapper.addView(mIndicatorIvBottom, params);
|
refreshableViewWrapper.addView(mIndicatorIvBottom, params);
|
||||||
|
|
||||||
} else if (!mode.canPullUp() && null != mIndicatorIvBottom) {
|
} else if (!mode.showFooterLoadingLayout() && null != mIndicatorIvBottom) {
|
||||||
// If we can't pull down, but have a View then remove it
|
// If we can't pull down, but have a View then remove it
|
||||||
refreshableViewWrapper.removeView(mIndicatorIvBottom);
|
refreshableViewWrapper.removeView(mIndicatorIvBottom);
|
||||||
mIndicatorIvBottom = null;
|
mIndicatorIvBottom = null;
|
||||||
@ -427,7 +454,7 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
|
|
||||||
private void updateIndicatorViewsVisibility() {
|
private void updateIndicatorViewsVisibility() {
|
||||||
if (null != mIndicatorIvTop) {
|
if (null != mIndicatorIvTop) {
|
||||||
if (!isRefreshing() && isReadyForPullDown()) {
|
if (!isRefreshing() && isReadyForPullStart()) {
|
||||||
if (!mIndicatorIvTop.isVisible()) {
|
if (!mIndicatorIvTop.isVisible()) {
|
||||||
mIndicatorIvTop.show();
|
mIndicatorIvTop.show();
|
||||||
}
|
}
|
||||||
@ -439,7 +466,7 @@ public abstract class PullToRefreshAdapterViewBase<T extends AbsListView> extend
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null != mIndicatorIvBottom) {
|
if (null != mIndicatorIvBottom) {
|
||||||
if (!isRefreshing() && isReadyForPullUp()) {
|
if (!isRefreshing() && isReadyForPullEnd()) {
|
||||||
if (!mIndicatorIvBottom.isVisible()) {
|
if (!mIndicatorIvBottom.isVisible()) {
|
||||||
mIndicatorIvBottom.show();
|
mIndicatorIvBottom.show();
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import android.content.Context;
|
|||||||
import android.os.Build.VERSION;
|
import android.os.Build.VERSION;
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ExpandableListView;
|
import android.widget.ExpandableListView;
|
||||||
|
|
||||||
@ -40,13 +39,17 @@ public class PullToRefreshExpandableListView extends PullToRefreshAdapterViewBas
|
|||||||
super(context, mode);
|
super(context, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public PullToRefreshExpandableListView(Context context, Mode mode, AnimationStyle style) {
|
||||||
public ContextMenuInfo getContextMenuInfo() {
|
super(context, mode, style);
|
||||||
return ((InternalExpandableListView) getRefreshableView()).getContextMenuInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final ExpandableListView createRefreshableView(Context context, AttributeSet attrs) {
|
public final Orientation getPullToRefreshScrollDirection() {
|
||||||
|
return Orientation.VERTICAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ExpandableListView createRefreshableView(Context context, AttributeSet attrs) {
|
||||||
final ExpandableListView lv;
|
final ExpandableListView lv;
|
||||||
if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
|
if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
|
||||||
lv = new InternalExpandableListViewSDK9(context, attrs);
|
lv = new InternalExpandableListViewSDK9(context, attrs);
|
||||||
@ -65,10 +68,6 @@ public class PullToRefreshExpandableListView extends PullToRefreshAdapterViewBas
|
|||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContextMenuInfo getContextMenuInfo() {
|
|
||||||
return super.getContextMenuInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEmptyView(View emptyView) {
|
public void setEmptyView(View emptyView) {
|
||||||
PullToRefreshExpandableListView.this.setEmptyView(emptyView);
|
PullToRefreshExpandableListView.this.setEmptyView(emptyView);
|
||||||
@ -95,7 +94,8 @@ public class PullToRefreshExpandableListView extends PullToRefreshAdapterViewBas
|
|||||||
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
||||||
|
|
||||||
// Does all of the hard work...
|
// Does all of the hard work...
|
||||||
OverscrollHelper.overScrollBy(PullToRefreshExpandableListView.this, deltaY, scrollY, isTouchEvent);
|
OverscrollHelper.overScrollBy(PullToRefreshExpandableListView.this, deltaX, scrollX, deltaY, scrollY,
|
||||||
|
isTouchEvent);
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import android.content.Context;
|
|||||||
import android.os.Build.VERSION;
|
import android.os.Build.VERSION;
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.GridView;
|
import android.widget.GridView;
|
||||||
|
|
||||||
@ -40,9 +39,13 @@ public class PullToRefreshGridView extends PullToRefreshAdapterViewBase<GridView
|
|||||||
super(context, mode);
|
super(context, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PullToRefreshGridView(Context context, Mode mode, AnimationStyle style) {
|
||||||
|
super(context, mode, style);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContextMenuInfo getContextMenuInfo() {
|
public final Orientation getPullToRefreshScrollDirection() {
|
||||||
return ((InternalGridView) getRefreshableView()).getContextMenuInfo();
|
return Orientation.VERTICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -65,11 +68,6 @@ public class PullToRefreshGridView extends PullToRefreshAdapterViewBase<GridView
|
|||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ContextMenuInfo getContextMenuInfo() {
|
|
||||||
return super.getContextMenuInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEmptyView(View emptyView) {
|
public void setEmptyView(View emptyView) {
|
||||||
PullToRefreshGridView.this.setEmptyView(emptyView);
|
PullToRefreshGridView.this.setEmptyView(emptyView);
|
||||||
@ -96,7 +94,7 @@ public class PullToRefreshGridView extends PullToRefreshAdapterViewBase<GridView
|
|||||||
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
||||||
|
|
||||||
// Does all of the hard work...
|
// Does all of the hard work...
|
||||||
OverscrollHelper.overScrollBy(PullToRefreshGridView.this, deltaY, scrollY, isTouchEvent);
|
OverscrollHelper.overScrollBy(PullToRefreshGridView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent);
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011, 2012 Chris Banes.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.handmark.pulltorefresh.library;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build.VERSION;
|
||||||
|
import android.os.Build.VERSION_CODES;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
|
||||||
|
public class PullToRefreshHorizontalScrollView extends PullToRefreshBase<HorizontalScrollView> {
|
||||||
|
|
||||||
|
public PullToRefreshHorizontalScrollView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PullToRefreshHorizontalScrollView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PullToRefreshHorizontalScrollView(Context context, Mode mode) {
|
||||||
|
super(context, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PullToRefreshHorizontalScrollView(Context context, Mode mode, AnimationStyle style) {
|
||||||
|
super(context, mode, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Orientation getPullToRefreshScrollDirection() {
|
||||||
|
return Orientation.HORIZONTAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected HorizontalScrollView createRefreshableView(Context context, AttributeSet attrs) {
|
||||||
|
HorizontalScrollView scrollView;
|
||||||
|
|
||||||
|
if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
|
||||||
|
scrollView = new InternalHorizontalScrollViewSDK9(context, attrs);
|
||||||
|
} else {
|
||||||
|
scrollView = new HorizontalScrollView(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollView.setId(R.id.scrollview);
|
||||||
|
return scrollView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isReadyForPullStart() {
|
||||||
|
return mRefreshableView.getScrollX() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isReadyForPullEnd() {
|
||||||
|
View scrollViewChild = mRefreshableView.getChildAt(0);
|
||||||
|
if (null != scrollViewChild) {
|
||||||
|
return mRefreshableView.getScrollX() >= (scrollViewChild.getWidth() - getWidth());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(9)
|
||||||
|
final class InternalHorizontalScrollViewSDK9 extends HorizontalScrollView {
|
||||||
|
|
||||||
|
public InternalHorizontalScrollViewSDK9(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX,
|
||||||
|
int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
|
||||||
|
|
||||||
|
final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,
|
||||||
|
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
||||||
|
|
||||||
|
// Does all of the hard work...
|
||||||
|
OverscrollHelper.overScrollBy(PullToRefreshHorizontalScrollView.this, deltaX, scrollX, deltaY, scrollY,
|
||||||
|
getScrollRange(), isTouchEvent);
|
||||||
|
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Taken from the AOSP ScrollView source
|
||||||
|
*/
|
||||||
|
private int getScrollRange() {
|
||||||
|
int scrollRange = 0;
|
||||||
|
if (getChildCount() > 0) {
|
||||||
|
View child = getChildAt(0);
|
||||||
|
scrollRange = Math.max(0, child.getWidth() - (getWidth() - getPaddingLeft() - getPaddingRight()));
|
||||||
|
}
|
||||||
|
return scrollRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,11 +19,11 @@ import android.annotation.TargetApi;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Build.VERSION;
|
import android.os.Build.VERSION;
|
||||||
import android.os.Build.VERSION_CODES;
|
import android.os.Build.VERSION_CODES;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.Gravity;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ListAdapter;
|
import android.widget.ListAdapter;
|
||||||
@ -39,124 +39,80 @@ public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView
|
|||||||
|
|
||||||
private FrameLayout mLvFooterLoadingFrame;
|
private FrameLayout mLvFooterLoadingFrame;
|
||||||
|
|
||||||
|
private boolean mListViewExtrasEnabled;
|
||||||
|
|
||||||
public PullToRefreshListView(Context context) {
|
public PullToRefreshListView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
setDisableScrollingWhileRefreshing(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PullToRefreshListView(Context context, AttributeSet attrs) {
|
public PullToRefreshListView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setDisableScrollingWhileRefreshing(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PullToRefreshListView(Context context, Mode mode) {
|
public PullToRefreshListView(Context context, Mode mode) {
|
||||||
super(context, mode);
|
super(context, mode);
|
||||||
setDisableScrollingWhileRefreshing(false);
|
}
|
||||||
|
|
||||||
|
public PullToRefreshListView(Context context, Mode mode, AnimationStyle style) {
|
||||||
|
super(context, mode, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ContextMenuInfo getContextMenuInfo() {
|
public final Orientation getPullToRefreshScrollDirection() {
|
||||||
return ((InternalListView) getRefreshableView()).getContextMenuInfo();
|
return Orientation.VERTICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLastUpdatedLabel(CharSequence label) {
|
protected void onRefreshing(final boolean doScroll) {
|
||||||
super.setLastUpdatedLabel(label);
|
/**
|
||||||
|
* If we're not showing the Refreshing view, or the list is empty, the
|
||||||
if (null != mHeaderLoadingView) {
|
* the header/footer views won't show so we use the normal method.
|
||||||
mHeaderLoadingView.setSubHeaderText(label);
|
*/
|
||||||
}
|
|
||||||
if (null != mFooterLoadingView) {
|
|
||||||
mFooterLoadingView.setSubHeaderText(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLoadingDrawable(Drawable drawable, Mode mode) {
|
|
||||||
super.setLoadingDrawable(drawable, mode);
|
|
||||||
|
|
||||||
if (null != mHeaderLoadingView && mode.canPullDown()) {
|
|
||||||
mHeaderLoadingView.setLoadingDrawable(drawable);
|
|
||||||
}
|
|
||||||
if (null != mFooterLoadingView && mode.canPullUp()) {
|
|
||||||
mFooterLoadingView.setLoadingDrawable(drawable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPullLabel(CharSequence pullLabel, Mode mode) {
|
|
||||||
super.setPullLabel(pullLabel, mode);
|
|
||||||
|
|
||||||
if (null != mHeaderLoadingView && mode.canPullDown()) {
|
|
||||||
mHeaderLoadingView.setPullLabel(pullLabel);
|
|
||||||
}
|
|
||||||
if (null != mFooterLoadingView && mode.canPullUp()) {
|
|
||||||
mFooterLoadingView.setPullLabel(pullLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRefreshingLabel(CharSequence refreshingLabel, Mode mode) {
|
|
||||||
super.setRefreshingLabel(refreshingLabel, mode);
|
|
||||||
|
|
||||||
if (null != mHeaderLoadingView && mode.canPullDown()) {
|
|
||||||
mHeaderLoadingView.setRefreshingLabel(refreshingLabel);
|
|
||||||
}
|
|
||||||
if (null != mFooterLoadingView && mode.canPullUp()) {
|
|
||||||
mFooterLoadingView.setRefreshingLabel(refreshingLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setReleaseLabel(CharSequence releaseLabel, Mode mode) {
|
|
||||||
super.setReleaseLabel(releaseLabel, mode);
|
|
||||||
|
|
||||||
if (null != mHeaderLoadingView && mode.canPullDown()) {
|
|
||||||
mHeaderLoadingView.setReleaseLabel(releaseLabel);
|
|
||||||
}
|
|
||||||
if (null != mFooterLoadingView && mode.canPullUp()) {
|
|
||||||
mFooterLoadingView.setReleaseLabel(releaseLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void onRefreshing(final boolean doScroll) {
|
|
||||||
|
|
||||||
// If we're not showing the Refreshing view, or the list is empty, then
|
|
||||||
// the header/footer views won't show so we use the
|
|
||||||
// normal method
|
|
||||||
ListAdapter adapter = mRefreshableView.getAdapter();
|
ListAdapter adapter = mRefreshableView.getAdapter();
|
||||||
if (!getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
|
if (!mListViewExtrasEnabled || !getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
|
||||||
super.onRefreshing(doScroll);
|
super.onRefreshing(doScroll);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
super.onRefreshing(false);
|
super.onRefreshing(false);
|
||||||
|
|
||||||
final LoadingLayout originalLoadingLayout, listViewLoadingLayout;
|
final LoadingLayout origLoadingView, listViewLoadingView, oppositeListViewLoadingView;
|
||||||
final int selection, scrollToY;
|
final int selection, scrollToY;
|
||||||
|
|
||||||
switch (getCurrentMode()) {
|
switch (getCurrentMode()) {
|
||||||
case PULL_UP_TO_REFRESH:
|
case MANUAL_REFRESH_ONLY:
|
||||||
originalLoadingLayout = getFooterLayout();
|
case PULL_FROM_END:
|
||||||
listViewLoadingLayout = mFooterLoadingView;
|
origLoadingView = getFooterLayout();
|
||||||
|
listViewLoadingView = mFooterLoadingView;
|
||||||
|
oppositeListViewLoadingView = mHeaderLoadingView;
|
||||||
selection = mRefreshableView.getCount() - 1;
|
selection = mRefreshableView.getCount() - 1;
|
||||||
scrollToY = getScrollY() - getFooterHeight();
|
scrollToY = getScrollY() - getFooterSize();
|
||||||
break;
|
break;
|
||||||
case PULL_DOWN_TO_REFRESH:
|
case PULL_FROM_START:
|
||||||
default:
|
default:
|
||||||
originalLoadingLayout = getHeaderLayout();
|
origLoadingView = getHeaderLayout();
|
||||||
listViewLoadingLayout = mHeaderLoadingView;
|
listViewLoadingView = mHeaderLoadingView;
|
||||||
|
oppositeListViewLoadingView = mFooterLoadingView;
|
||||||
selection = 0;
|
selection = 0;
|
||||||
scrollToY = getScrollY() + getHeaderHeight();
|
scrollToY = getScrollY() + getHeaderSize();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide our original Loading View
|
// Hide our original Loading View
|
||||||
originalLoadingLayout.setVisibility(View.INVISIBLE);
|
origLoadingView.reset();
|
||||||
|
origLoadingView.hideAllViews();
|
||||||
|
|
||||||
// Show the ListView Loading View and set it to refresh
|
// Make sure the opposite end is hidden too
|
||||||
listViewLoadingLayout.setVisibility(View.VISIBLE);
|
oppositeListViewLoadingView.setVisibility(View.GONE);
|
||||||
listViewLoadingLayout.refreshing();
|
|
||||||
|
// Show the ListView Loading View and set it to refresh.
|
||||||
|
listViewLoadingView.setVisibility(View.VISIBLE);
|
||||||
|
listViewLoadingView.refreshing();
|
||||||
|
|
||||||
if (doScroll) {
|
if (doScroll) {
|
||||||
|
// We need to disable the automatic visibility changes for now
|
||||||
|
disableLoadingLayoutVisibilityChanges();
|
||||||
|
|
||||||
// We scroll slightly so that the ListView's header/footer is at the
|
// We scroll slightly so that the ListView's header/footer is at the
|
||||||
// same Y position as our normal header/footer
|
// same Y position as our normal header/footer
|
||||||
setHeaderScroll(scrollToY);
|
setHeaderScroll(scrollToY);
|
||||||
@ -171,59 +127,81 @@ public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onReset() {
|
protected void onReset() {
|
||||||
|
/**
|
||||||
// If we're not showing the Refreshing view, or the list is empty, then
|
* If the extras are not enabled, just call up to super and return.
|
||||||
// the header/footer views won't show so we use the
|
*/
|
||||||
// normal method
|
if (!mListViewExtrasEnabled) {
|
||||||
ListAdapter adapter = mRefreshableView.getAdapter();
|
|
||||||
if (!getShowViewWhileRefreshing() || null == adapter || adapter.isEmpty()) {
|
|
||||||
super.onReset();
|
super.onReset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadingLayout originalLoadingLayout, listViewLoadingLayout;
|
final LoadingLayout originalLoadingLayout, listViewLoadingLayout;
|
||||||
int scrollToHeight, selection;
|
final int scrollToHeight, selection;
|
||||||
boolean scrollLvToEdge;
|
final boolean scrollLvToEdge;
|
||||||
|
|
||||||
switch (getCurrentMode()) {
|
switch (getCurrentMode()) {
|
||||||
case PULL_UP_TO_REFRESH:
|
case MANUAL_REFRESH_ONLY:
|
||||||
|
case PULL_FROM_END:
|
||||||
originalLoadingLayout = getFooterLayout();
|
originalLoadingLayout = getFooterLayout();
|
||||||
listViewLoadingLayout = mFooterLoadingView;
|
listViewLoadingLayout = mFooterLoadingView;
|
||||||
selection = mRefreshableView.getCount() - 1;
|
selection = mRefreshableView.getCount() - 1;
|
||||||
scrollToHeight = getFooterHeight();
|
scrollToHeight = getFooterSize();
|
||||||
scrollLvToEdge = Math.abs(mRefreshableView.getLastVisiblePosition() - selection) <= 1;
|
scrollLvToEdge = Math.abs(mRefreshableView.getLastVisiblePosition() - selection) <= 1;
|
||||||
break;
|
break;
|
||||||
case PULL_DOWN_TO_REFRESH:
|
case PULL_FROM_START:
|
||||||
default:
|
default:
|
||||||
originalLoadingLayout = getHeaderLayout();
|
originalLoadingLayout = getHeaderLayout();
|
||||||
listViewLoadingLayout = mHeaderLoadingView;
|
listViewLoadingLayout = mHeaderLoadingView;
|
||||||
scrollToHeight = -getHeaderHeight();
|
scrollToHeight = -getHeaderSize();
|
||||||
selection = 0;
|
selection = 0;
|
||||||
scrollLvToEdge = Math.abs(mRefreshableView.getFirstVisiblePosition() - selection) <= 1;
|
scrollLvToEdge = Math.abs(mRefreshableView.getFirstVisiblePosition() - selection) <= 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set our Original View to Visible
|
// If the ListView header loading layout is showing, then we need to
|
||||||
originalLoadingLayout.setVisibility(View.VISIBLE);
|
// flip so that the original one is showing instead
|
||||||
|
if (listViewLoadingLayout.getVisibility() == View.VISIBLE) {
|
||||||
|
|
||||||
/**
|
// Set our Original View to Visible
|
||||||
* Scroll so the View is at the same Y as the ListView header/footer,
|
originalLoadingLayout.showInvisibleViews();
|
||||||
* but only scroll if: we've pulled to refresh, it's positioned
|
|
||||||
* correctly, and we're currently showing the ListViewLoadingLayout
|
// Hide the ListView Header/Footer
|
||||||
*/
|
listViewLoadingLayout.setVisibility(View.GONE);
|
||||||
if (scrollLvToEdge && getState() != State.MANUAL_REFRESHING
|
|
||||||
&& listViewLoadingLayout.getVisibility() == View.VISIBLE) {
|
/**
|
||||||
mRefreshableView.setSelection(selection);
|
* Scroll so the View is at the same Y as the ListView
|
||||||
setHeaderScroll(scrollToHeight);
|
* header/footer, but only scroll if: we've pulled to refresh, it's
|
||||||
|
* positioned correctly
|
||||||
|
*/
|
||||||
|
if (scrollLvToEdge && getState() != State.MANUAL_REFRESHING) {
|
||||||
|
mRefreshableView.setSelection(selection);
|
||||||
|
setHeaderScroll(scrollToHeight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide the ListView Header/Footer
|
// Finally, call up to super
|
||||||
listViewLoadingLayout.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
super.onReset();
|
super.onReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LoadingLayoutProxy createLoadingLayoutProxy(final boolean includeStart, final boolean includeEnd) {
|
||||||
|
LoadingLayoutProxy proxy = super.createLoadingLayoutProxy(includeStart, includeEnd);
|
||||||
|
|
||||||
|
if (mListViewExtrasEnabled) {
|
||||||
|
final Mode mode = getMode();
|
||||||
|
|
||||||
|
if (includeStart && mode.showHeaderLoadingLayout()) {
|
||||||
|
proxy.addLayout(mHeaderLoadingView);
|
||||||
|
}
|
||||||
|
if (includeEnd && mode.showFooterLoadingLayout()) {
|
||||||
|
proxy.addLayout(mFooterLoadingView);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return proxy;
|
||||||
|
}
|
||||||
|
|
||||||
protected ListView createListView(Context context, AttributeSet attrs) {
|
protected ListView createListView(Context context, AttributeSet attrs) {
|
||||||
final ListView lv;
|
final ListView lv;
|
||||||
if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
|
if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) {
|
||||||
@ -235,32 +213,46 @@ public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final ListView createRefreshableView(Context context, AttributeSet attrs) {
|
protected ListView createRefreshableView(Context context, AttributeSet attrs) {
|
||||||
ListView lv = createListView(context, attrs);
|
ListView lv = createListView(context, attrs);
|
||||||
|
|
||||||
// Get Styles from attrs
|
|
||||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PullToRefresh);
|
|
||||||
|
|
||||||
// Create Loading Views ready for use later
|
|
||||||
FrameLayout frame = new FrameLayout(context);
|
|
||||||
mHeaderLoadingView = createLoadingLayout(context, Mode.PULL_DOWN_TO_REFRESH, a);
|
|
||||||
frame.addView(mHeaderLoadingView, FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
|
|
||||||
mHeaderLoadingView.setVisibility(View.GONE);
|
|
||||||
lv.addHeaderView(frame, null, false);
|
|
||||||
|
|
||||||
mLvFooterLoadingFrame = new FrameLayout(context);
|
|
||||||
mFooterLoadingView = createLoadingLayout(context, Mode.PULL_UP_TO_REFRESH, a);
|
|
||||||
mLvFooterLoadingFrame.addView(mFooterLoadingView, FrameLayout.LayoutParams.MATCH_PARENT,
|
|
||||||
FrameLayout.LayoutParams.WRAP_CONTENT);
|
|
||||||
mFooterLoadingView.setVisibility(View.GONE);
|
|
||||||
|
|
||||||
a.recycle();
|
|
||||||
|
|
||||||
// Set it to this so it can be used in ListActivity/ListFragment
|
// Set it to this so it can be used in ListActivity/ListFragment
|
||||||
lv.setId(android.R.id.list);
|
lv.setId(android.R.id.list);
|
||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleStyledAttributes(TypedArray a) {
|
||||||
|
super.handleStyledAttributes(a);
|
||||||
|
|
||||||
|
mListViewExtrasEnabled = a.getBoolean(R.styleable.PullToRefresh_ptrListViewExtrasEnabled, true);
|
||||||
|
|
||||||
|
if (mListViewExtrasEnabled) {
|
||||||
|
final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL);
|
||||||
|
|
||||||
|
// Create Loading Views ready for use later
|
||||||
|
FrameLayout frame = new FrameLayout(getContext());
|
||||||
|
mHeaderLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_START, a);
|
||||||
|
mHeaderLoadingView.setVisibility(View.GONE);
|
||||||
|
frame.addView(mHeaderLoadingView, lp);
|
||||||
|
mRefreshableView.addHeaderView(frame, null, false);
|
||||||
|
|
||||||
|
mLvFooterLoadingFrame = new FrameLayout(getContext());
|
||||||
|
mFooterLoadingView = createLoadingLayout(getContext(), Mode.PULL_FROM_END, a);
|
||||||
|
mFooterLoadingView.setVisibility(View.GONE);
|
||||||
|
mLvFooterLoadingFrame.addView(mFooterLoadingView, lp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the value for Scrolling While Refreshing hasn't been
|
||||||
|
* explicitly set via XML, enable Scrolling While Refreshing.
|
||||||
|
*/
|
||||||
|
if (!a.hasValue(R.styleable.PullToRefresh_ptrScrollingWhileRefreshingEnabled)) {
|
||||||
|
setScrollingWhileRefreshingEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TargetApi(9)
|
@TargetApi(9)
|
||||||
final class InternalListViewSDK9 extends InternalListView {
|
final class InternalListViewSDK9 extends InternalListView {
|
||||||
|
|
||||||
@ -276,7 +268,7 @@ public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView
|
|||||||
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
||||||
|
|
||||||
// Does all of the hard work...
|
// Does all of the hard work...
|
||||||
OverscrollHelper.overScrollBy(PullToRefreshListView.this, deltaY, scrollY, isTouchEvent);
|
OverscrollHelper.overScrollBy(PullToRefreshListView.this, deltaX, scrollX, deltaY, scrollY, isTouchEvent);
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
@ -291,27 +283,38 @@ public class PullToRefreshListView extends PullToRefreshAdapterViewBase<ListView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(Canvas canvas) {
|
protected void dispatchDraw(Canvas canvas) {
|
||||||
/**
|
/**
|
||||||
* This is a bit hacky, but ListView has got a bug in it when using
|
* This is a bit hacky, but Samsung's ListView has got a bug in it
|
||||||
* Header/Footer Views and the list is empty. This masks the issue
|
* when using Header/Footer Views and the list is empty. This masks
|
||||||
* so that it doesn't cause an FC. See Issue #66.
|
* the issue so that it doesn't cause an FC. See Issue #66.
|
||||||
*/
|
*/
|
||||||
try {
|
try {
|
||||||
super.draw(canvas);
|
super.dispatchDraw(canvas);
|
||||||
} catch (Exception e) {
|
} catch (IndexOutOfBoundsException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContextMenuInfo getContextMenuInfo() {
|
@Override
|
||||||
return super.getContextMenuInfo();
|
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||||
|
/**
|
||||||
|
* This is a bit hacky, but Samsung's ListView has got a bug in it
|
||||||
|
* when using Header/Footer Views and the list is empty. This masks
|
||||||
|
* the issue so that it doesn't cause an FC. See Issue #66.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
return super.dispatchTouchEvent(ev);
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setAdapter(ListAdapter adapter) {
|
public void setAdapter(ListAdapter adapter) {
|
||||||
// Add the Footer View at the last possible moment
|
// Add the Footer View at the last possible moment
|
||||||
if (!mAddedLvFooter) {
|
if (null != mLvFooterLoadingFrame && !mAddedLvFooter) {
|
||||||
addFooterView(mLvFooterLoadingFrame, null, false);
|
addFooterView(mLvFooterLoadingFrame, null, false);
|
||||||
mAddedLvFooter = true;
|
mAddedLvFooter = true;
|
||||||
}
|
}
|
||||||
|
@ -25,10 +25,27 @@ import android.widget.ScrollView;
|
|||||||
|
|
||||||
public class PullToRefreshScrollView extends PullToRefreshBase<ScrollView> {
|
public class PullToRefreshScrollView extends PullToRefreshBase<ScrollView> {
|
||||||
|
|
||||||
|
public PullToRefreshScrollView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
public PullToRefreshScrollView(Context context, AttributeSet attrs) {
|
public PullToRefreshScrollView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PullToRefreshScrollView(Context context, Mode mode) {
|
||||||
|
super(context, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PullToRefreshScrollView(Context context, Mode mode, AnimationStyle style) {
|
||||||
|
super(context, mode, style);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Orientation getPullToRefreshScrollDirection() {
|
||||||
|
return Orientation.VERTICAL;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ScrollView createRefreshableView(Context context, AttributeSet attrs) {
|
protected ScrollView createRefreshableView(Context context, AttributeSet attrs) {
|
||||||
ScrollView scrollView;
|
ScrollView scrollView;
|
||||||
@ -43,12 +60,12 @@ public class PullToRefreshScrollView extends PullToRefreshBase<ScrollView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReadyForPullDown() {
|
protected boolean isReadyForPullStart() {
|
||||||
return mRefreshableView.getScrollY() == 0;
|
return mRefreshableView.getScrollY() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReadyForPullUp() {
|
protected boolean isReadyForPullEnd() {
|
||||||
View scrollViewChild = mRefreshableView.getChildAt(0);
|
View scrollViewChild = mRefreshableView.getChildAt(0);
|
||||||
if (null != scrollViewChild) {
|
if (null != scrollViewChild) {
|
||||||
return mRefreshableView.getScrollY() >= (scrollViewChild.getHeight() - getHeight());
|
return mRefreshableView.getScrollY() >= (scrollViewChild.getHeight() - getHeight());
|
||||||
@ -71,8 +88,8 @@ public class PullToRefreshScrollView extends PullToRefreshBase<ScrollView> {
|
|||||||
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
||||||
|
|
||||||
// Does all of the hard work...
|
// Does all of the hard work...
|
||||||
OverscrollHelper
|
OverscrollHelper.overScrollBy(PullToRefreshScrollView.this, deltaX, scrollX, deltaY, scrollY,
|
||||||
.overScrollBy(PullToRefreshScrollView.this, deltaY, scrollY, getScrollRange(), isTouchEvent);
|
getScrollRange(), isTouchEvent);
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,21 @@ public class PullToRefreshWebView extends PullToRefreshBase<WebView> {
|
|||||||
mRefreshableView.setWebChromeClient(defaultWebChromeClient);
|
mRefreshableView.setWebChromeClient(defaultWebChromeClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PullToRefreshWebView(Context context, Mode mode, AnimationStyle style) {
|
||||||
|
super(context, mode, style);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Added so that by default, Pull-to-Refresh refreshes the page
|
||||||
|
*/
|
||||||
|
setOnRefreshListener(defaultOnRefreshListener);
|
||||||
|
mRefreshableView.setWebChromeClient(defaultWebChromeClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Orientation getPullToRefreshScrollDirection() {
|
||||||
|
return Orientation.VERTICAL;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WebView createRefreshableView(Context context, AttributeSet attrs) {
|
protected WebView createRefreshableView(Context context, AttributeSet attrs) {
|
||||||
WebView webView;
|
WebView webView;
|
||||||
@ -91,12 +106,12 @@ public class PullToRefreshWebView extends PullToRefreshBase<WebView> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReadyForPullDown() {
|
protected boolean isReadyForPullStart() {
|
||||||
return mRefreshableView.getScrollY() == 0;
|
return mRefreshableView.getScrollY() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReadyForPullUp() {
|
protected boolean isReadyForPullEnd() {
|
||||||
float exactContentHeight = FloatMath.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale());
|
float exactContentHeight = FloatMath.floor(mRefreshableView.getContentHeight() * mRefreshableView.getScale());
|
||||||
return mRefreshableView.getScrollY() >= (exactContentHeight - mRefreshableView.getHeight());
|
return mRefreshableView.getScrollY() >= (exactContentHeight - mRefreshableView.getHeight());
|
||||||
}
|
}
|
||||||
@ -136,8 +151,8 @@ public class PullToRefreshWebView extends PullToRefreshBase<WebView> {
|
|||||||
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
|
||||||
|
|
||||||
// Does all of the hard work...
|
// Does all of the hard work...
|
||||||
OverscrollHelper.overScrollBy(PullToRefreshWebView.this, deltaY, scrollY, getScrollRange(),
|
OverscrollHelper.overScrollBy(PullToRefreshWebView.this, deltaX, scrollX, deltaY, scrollY,
|
||||||
OVERSCROLL_FUZZY_THRESHOLD, OVERSCROLL_SCALE_FACTOR, isTouchEvent);
|
getScrollRange(), OVERSCROLL_FUZZY_THRESHOLD, OVERSCROLL_SCALE_FACTOR, isTouchEvent);
|
||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ import com.handmark.pulltorefresh.library.PullToRefreshWebView;
|
|||||||
* An advanced version of {@link PullToRefreshWebView} which delegates the
|
* An advanced version of {@link PullToRefreshWebView} which delegates the
|
||||||
* triggering of the PullToRefresh gesture to the Javascript running within the
|
* triggering of the PullToRefresh gesture to the Javascript running within the
|
||||||
* WebView. This means that you should only use this class if:
|
* WebView. This means that you should only use this class if:
|
||||||
*
|
* <p/>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link PullToRefreshWebView} doesn't work correctly because you're using
|
* <li>{@link PullToRefreshWebView} doesn't work correctly because you're using
|
||||||
* <code>overflow:scroll</code> or something else which means
|
* <code>overflow:scroll</code> or something else which means
|
||||||
@ -35,14 +35,15 @@ import com.handmark.pulltorefresh.library.PullToRefreshWebView;
|
|||||||
* <li>You control the web content being displayed, as you need to write some
|
* <li>You control the web content being displayed, as you need to write some
|
||||||
* Javascript callbacks.</li>
|
* Javascript callbacks.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p />
|
* <p/>
|
||||||
*
|
* <p/>
|
||||||
* The way this call works is that when a PullToRefresh gesture is in action,
|
* The way this call works is that when a PullToRefresh gesture is in action,
|
||||||
* the following Javascript methods will be called:
|
* the following Javascript methods will be called:
|
||||||
* <code>isReadyForPullDown()</code> and <code>isReadyForPullUp()</code>, it is
|
* <code>isReadyForPullDown()</code> and <code>isReadyForPullUp()</code>, it is
|
||||||
* your job to calculate whether the view is in a state where a PullToRefresh
|
* your job to calculate whether the view is in a state where a PullToRefresh
|
||||||
* can happen, and return the result via the callback mechanism. An example can
|
* can happen, and return the result via the callback mechanism. An example can
|
||||||
* be seen below:
|
* be seen below:
|
||||||
|
* <p/>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* function isReadyForPullDown() {
|
* function isReadyForPullDown() {
|
||||||
@ -92,7 +93,7 @@ public class PullToRefreshWebView2 extends PullToRefreshWebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReadyForPullDown() {
|
protected boolean isReadyForPullStart() {
|
||||||
// Call Javascript...
|
// Call Javascript...
|
||||||
getRefreshableView().loadUrl(DEF_JS_READY_PULL_DOWN_CALL);
|
getRefreshableView().loadUrl(DEF_JS_READY_PULL_DOWN_CALL);
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ public class PullToRefreshWebView2 extends PullToRefreshWebView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReadyForPullUp() {
|
protected boolean isReadyForPullEnd() {
|
||||||
// Call Javascript...
|
// Call Javascript...
|
||||||
getRefreshableView().loadUrl(DEF_JS_READY_PULL_UP_CALL);
|
getRefreshableView().loadUrl(DEF_JS_READY_PULL_UP_CALL);
|
||||||
|
|
||||||
|
@ -35,8 +35,7 @@ public class SoundPullEventListener<V extends View> implements PullToRefreshBase
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param context
|
* @param context - Context
|
||||||
* - Context
|
|
||||||
*/
|
*/
|
||||||
public SoundPullEventListener(Context context) {
|
public SoundPullEventListener(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
@ -55,14 +54,12 @@ public class SoundPullEventListener<V extends View> implements PullToRefreshBase
|
|||||||
* Set the Sounds to be played when a Pull Event happens. You specify which
|
* Set the Sounds to be played when a Pull Event happens. You specify which
|
||||||
* sound plays for which events by calling this method multiple times for
|
* sound plays for which events by calling this method multiple times for
|
||||||
* each event.
|
* each event.
|
||||||
*
|
* <p/>
|
||||||
* If you've already set a sound for a certain event, and add another sound
|
* If you've already set a sound for a certain event, and add another sound
|
||||||
* for that event, only the new sound will be played.
|
* for that event, only the new sound will be played.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event - The event for which the sound will be played.
|
||||||
* - The event for which the sound will be played.
|
* @param resId - Resource Id of the sound file to be played (e.g.
|
||||||
* @param resId
|
|
||||||
* - Resource Id of the sound file to be played (e.g.
|
|
||||||
* <var>R.raw.pull_sound</var>)
|
* <var>R.raw.pull_sound</var>)
|
||||||
*/
|
*/
|
||||||
public void addSoundEvent(State event, int resId) {
|
public void addSoundEvent(State event, int resId) {
|
||||||
|
@ -28,8 +28,7 @@ public interface EmptyViewMethodAccessor {
|
|||||||
/**
|
/**
|
||||||
* Calls upto AdapterView.setEmptyView()
|
* Calls upto AdapterView.setEmptyView()
|
||||||
*
|
*
|
||||||
* @param View
|
* @param emptyView - to set as Empty View
|
||||||
* to set as Empty View
|
|
||||||
*/
|
*/
|
||||||
public void setEmptyViewInternal(View emptyView);
|
public void setEmptyViewInternal(View emptyView);
|
||||||
|
|
||||||
@ -37,8 +36,7 @@ public interface EmptyViewMethodAccessor {
|
|||||||
* Should call PullToRefreshBase.setEmptyView() which will then
|
* Should call PullToRefreshBase.setEmptyView() which will then
|
||||||
* automatically call through to setEmptyViewInternal()
|
* automatically call through to setEmptyViewInternal()
|
||||||
*
|
*
|
||||||
* @param View
|
* @param emptyView - to set as Empty View
|
||||||
* to set as Empty View
|
|
||||||
*/
|
*/
|
||||||
public void setEmptyView(View emptyView);
|
public void setEmptyView(View emptyView);
|
||||||
|
|
||||||
|
@ -15,30 +15,35 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.handmark.pulltorefresh.library.internal;
|
package com.handmark.pulltorefresh.library.internal;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Matrix;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.RotateAnimation;
|
import android.view.animation.RotateAnimation;
|
||||||
|
import android.widget.ImageView.ScaleType;
|
||||||
|
|
||||||
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
|
||||||
import com.handmark.pulltorefresh.library.R;
|
import com.handmark.pulltorefresh.library.R;
|
||||||
|
|
||||||
|
@SuppressLint("ViewConstructor")
|
||||||
public class FlipLoadingLayout extends LoadingLayout {
|
public class FlipLoadingLayout extends LoadingLayout {
|
||||||
|
|
||||||
static final int FLIP_ANIMATION_DURATION = 150;
|
static final int FLIP_ANIMATION_DURATION = 150;
|
||||||
|
|
||||||
private final Animation mRotateAnimation, mResetRotateAnimation;
|
private final Animation mRotateAnimation, mResetRotateAnimation;
|
||||||
|
|
||||||
public FlipLoadingLayout(Context context, Mode mode, TypedArray attrs) {
|
public FlipLoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) {
|
||||||
super(context, mode, attrs);
|
super(context, mode, scrollDirection, attrs);
|
||||||
|
|
||||||
final int rotateAngle = mode == Mode.PULL_DOWN_TO_REFRESH ? 180 : -180;
|
final int rotateAngle = mode == Mode.PULL_FROM_START ? -180 : 180;
|
||||||
|
|
||||||
mRotateAnimation = new RotateAnimation(0, rotateAngle, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
|
mRotateAnimation = new RotateAnimation(0, rotateAngle, Animation.RELATIVE_TO_SELF, 0.5f,
|
||||||
0.5f);
|
Animation.RELATIVE_TO_SELF, 0.5f);
|
||||||
mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
|
mRotateAnimation.setInterpolator(ANIMATION_INTERPOLATOR);
|
||||||
mRotateAnimation.setDuration(FLIP_ANIMATION_DURATION);
|
mRotateAnimation.setDuration(FLIP_ANIMATION_DURATION);
|
||||||
mRotateAnimation.setFillAfter(true);
|
mRotateAnimation.setFillAfter(true);
|
||||||
@ -52,20 +57,33 @@ public class FlipLoadingLayout extends LoadingLayout {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onLoadingDrawableSet(Drawable imageDrawable) {
|
protected void onLoadingDrawableSet(Drawable imageDrawable) {
|
||||||
/**
|
|
||||||
* We need to set the width/height of the ImageView so that it is square
|
|
||||||
* with each side the size of the largest drawable dimension. This is so
|
|
||||||
* that it doesn't clip when rotated.
|
|
||||||
*/
|
|
||||||
if (null != imageDrawable) {
|
if (null != imageDrawable) {
|
||||||
|
final int dHeight = imageDrawable.getIntrinsicHeight();
|
||||||
|
final int dWidth = imageDrawable.getIntrinsicWidth();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need to set the width/height of the ImageView so that it is
|
||||||
|
* square with each side the size of the largest drawable dimension.
|
||||||
|
* This is so that it doesn't clip when rotated.
|
||||||
|
*/
|
||||||
ViewGroup.LayoutParams lp = mHeaderImage.getLayoutParams();
|
ViewGroup.LayoutParams lp = mHeaderImage.getLayoutParams();
|
||||||
lp.width = lp.height = Math.max(imageDrawable.getIntrinsicWidth(), imageDrawable.getIntrinsicHeight());
|
lp.width = lp.height = Math.max(dHeight, dWidth);
|
||||||
mHeaderImage.requestLayout();
|
mHeaderImage.requestLayout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We now rotate the Drawable so that is at the correct rotation,
|
||||||
|
* and is centered.
|
||||||
|
*/
|
||||||
|
mHeaderImage.setScaleType(ScaleType.MATRIX);
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.postTranslate((lp.width - dWidth) / 2f, (lp.height - dHeight) / 2f);
|
||||||
|
matrix.postRotate(getDrawableRotationAngle(), lp.width / 2f, lp.height / 2f);
|
||||||
|
mHeaderImage.setImageMatrix(matrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPullYImpl(float scaleOfHeight) {
|
protected void onPullImpl(float scaleOfLayout) {
|
||||||
// NO-OP
|
// NO-OP
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,13 +115,32 @@ public class FlipLoadingLayout extends LoadingLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getDefaultTopDrawableResId() {
|
protected int getDefaultDrawableResId() {
|
||||||
return R.drawable.default_ptr_flip_top;
|
return R.drawable.default_ptr_flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private float getDrawableRotationAngle() {
|
||||||
protected int getDefaultBottomDrawableResId() {
|
float angle = 0f;
|
||||||
return R.drawable.default_ptr_flip_bottom;
|
switch (mMode) {
|
||||||
|
case PULL_FROM_END:
|
||||||
|
if (mScrollDirection == Orientation.HORIZONTAL) {
|
||||||
|
angle = 90f;
|
||||||
|
} else {
|
||||||
|
angle = 180f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PULL_FROM_START:
|
||||||
|
if (mScrollDirection == Orientation.HORIZONTAL) {
|
||||||
|
angle = 270f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,10 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.handmark.pulltorefresh.library.internal;
|
package com.handmark.pulltorefresh.library.internal;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.view.animation.Animation.AnimationListener;
|
import android.view.animation.Animation.AnimationListener;
|
||||||
@ -25,10 +28,12 @@ import android.view.animation.LinearInterpolator;
|
|||||||
import android.view.animation.RotateAnimation;
|
import android.view.animation.RotateAnimation;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.ImageView.ScaleType;
|
||||||
|
|
||||||
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||||
import com.handmark.pulltorefresh.library.R;
|
import com.handmark.pulltorefresh.library.R;
|
||||||
|
|
||||||
|
@SuppressLint("ViewConstructor")
|
||||||
public class IndicatorLayout extends FrameLayout implements AnimationListener {
|
public class IndicatorLayout extends FrameLayout implements AnimationListener {
|
||||||
|
|
||||||
static final int DEFAULT_ROTATION_ANIMATION_DURATION = 150;
|
static final int DEFAULT_ROTATION_ANIMATION_DURATION = 150;
|
||||||
@ -40,26 +45,33 @@ public class IndicatorLayout extends FrameLayout implements AnimationListener {
|
|||||||
|
|
||||||
public IndicatorLayout(Context context, PullToRefreshBase.Mode mode) {
|
public IndicatorLayout(Context context, PullToRefreshBase.Mode mode) {
|
||||||
super(context);
|
super(context);
|
||||||
|
|
||||||
mArrowImageView = new ImageView(context);
|
mArrowImageView = new ImageView(context);
|
||||||
|
|
||||||
|
Drawable arrowD = getResources().getDrawable(R.drawable.indicator_arrow);
|
||||||
|
mArrowImageView.setImageDrawable(arrowD);
|
||||||
|
|
||||||
final int padding = getResources().getDimensionPixelSize(R.dimen.indicator_internal_padding);
|
final int padding = getResources().getDimensionPixelSize(R.dimen.indicator_internal_padding);
|
||||||
mArrowImageView.setPadding(padding, padding, padding, padding);
|
mArrowImageView.setPadding(padding, padding, padding, padding);
|
||||||
addView(mArrowImageView);
|
addView(mArrowImageView);
|
||||||
|
|
||||||
int inAnimResId, outAnimResId;
|
int inAnimResId, outAnimResId;
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PULL_UP_TO_REFRESH:
|
case PULL_FROM_END:
|
||||||
inAnimResId = R.anim.slide_in_from_bottom;
|
inAnimResId = R.anim.slide_in_from_bottom;
|
||||||
outAnimResId = R.anim.slide_out_to_bottom;
|
outAnimResId = R.anim.slide_out_to_bottom;
|
||||||
setBackgroundResource(R.drawable.indicator_bg_bottom);
|
setBackgroundResource(R.drawable.indicator_bg_bottom);
|
||||||
mArrowImageView.setImageResource(R.drawable.arrow_up);
|
|
||||||
|
// Rotate Arrow so it's pointing the correct way
|
||||||
|
mArrowImageView.setScaleType(ScaleType.MATRIX);
|
||||||
|
Matrix matrix = new Matrix();
|
||||||
|
matrix.setRotate(180f, arrowD.getIntrinsicWidth() / 2f, arrowD.getIntrinsicHeight() / 2f);
|
||||||
|
mArrowImageView.setImageMatrix(matrix);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
case PULL_DOWN_TO_REFRESH:
|
case PULL_FROM_START:
|
||||||
inAnimResId = R.anim.slide_in_from_top;
|
inAnimResId = R.anim.slide_in_from_top;
|
||||||
outAnimResId = R.anim.slide_out_to_top;
|
outAnimResId = R.anim.slide_out_to_top;
|
||||||
setBackgroundResource(R.drawable.indicator_bg_top);
|
setBackgroundResource(R.drawable.indicator_bg_top);
|
||||||
mArrowImageView.setImageResource(R.drawable.arrow_down);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,10 +15,11 @@
|
|||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package com.handmark.pulltorefresh.library.internal;
|
package com.handmark.pulltorefresh.library.internal;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.graphics.Color;
|
import android.graphics.Typeface;
|
||||||
import android.graphics.drawable.AnimationDrawable;
|
import android.graphics.drawable.AnimationDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -26,57 +27,80 @@ import android.util.TypedValue;
|
|||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.Interpolator;
|
import android.view.animation.Interpolator;
|
||||||
import android.view.animation.LinearInterpolator;
|
import android.view.animation.LinearInterpolator;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.ILoadingLayout;
|
||||||
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
|
||||||
import com.handmark.pulltorefresh.library.R;
|
import com.handmark.pulltorefresh.library.R;
|
||||||
|
|
||||||
public abstract class LoadingLayout extends LinearLayout {
|
@SuppressLint("ViewConstructor")
|
||||||
|
public abstract class LoadingLayout extends FrameLayout implements ILoadingLayout {
|
||||||
|
|
||||||
|
static final String LOG_TAG = "PullToRefresh-LoadingLayout";
|
||||||
|
|
||||||
static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator();
|
static final Interpolator ANIMATION_INTERPOLATOR = new LinearInterpolator();
|
||||||
|
|
||||||
|
private FrameLayout mInnerLayout;
|
||||||
|
|
||||||
protected final ImageView mHeaderImage;
|
protected final ImageView mHeaderImage;
|
||||||
protected final ProgressBar mHeaderProgress;
|
protected final ProgressBar mHeaderProgress;
|
||||||
|
|
||||||
private boolean mUseIntrinisicAnimation;
|
private boolean mUseIntrinsicAnimation;
|
||||||
|
|
||||||
private final TextView mHeaderText;
|
private final TextView mHeaderText;
|
||||||
private final TextView mSubHeaderText;
|
private final TextView mSubHeaderText;
|
||||||
|
|
||||||
|
protected final Mode mMode;
|
||||||
|
protected final Orientation mScrollDirection;
|
||||||
|
|
||||||
private CharSequence mPullLabel;
|
private CharSequence mPullLabel;
|
||||||
private CharSequence mRefreshingLabel;
|
private CharSequence mRefreshingLabel;
|
||||||
private CharSequence mReleaseLabel;
|
private CharSequence mReleaseLabel;
|
||||||
|
|
||||||
public LoadingLayout(Context context, final Mode mode, TypedArray attrs) {
|
public LoadingLayout(Context context, final Mode mode, final Orientation scrollDirection, TypedArray attrs) {
|
||||||
super(context);
|
super(context);
|
||||||
|
mMode = mode;
|
||||||
|
mScrollDirection = scrollDirection;
|
||||||
|
|
||||||
setGravity(Gravity.CENTER_VERTICAL);
|
switch (scrollDirection) {
|
||||||
|
case HORIZONTAL:
|
||||||
|
LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_horizontal, this);
|
||||||
|
break;
|
||||||
|
case VERTICAL:
|
||||||
|
default:
|
||||||
|
LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header_vertical, this);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
final int tbPadding = getResources().getDimensionPixelSize(R.dimen.header_footer_top_bottom_padding);
|
mInnerLayout = (FrameLayout) findViewById(R.id.fl_inner);
|
||||||
final int lrPadding = getResources().getDimensionPixelSize(R.dimen.header_footer_left_right_padding);
|
mHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_text);
|
||||||
setPadding(lrPadding, tbPadding, lrPadding, tbPadding);
|
mHeaderProgress = (ProgressBar) mInnerLayout.findViewById(R.id.pull_to_refresh_progress);
|
||||||
|
mSubHeaderText = (TextView) mInnerLayout.findViewById(R.id.pull_to_refresh_sub_text);
|
||||||
|
mHeaderImage = (ImageView) mInnerLayout.findViewById(R.id.pull_to_refresh_image);
|
||||||
|
|
||||||
LayoutInflater.from(context).inflate(R.layout.pull_to_refresh_header, this);
|
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mInnerLayout.getLayoutParams();
|
||||||
mHeaderText = (TextView) findViewById(R.id.pull_to_refresh_text);
|
|
||||||
mHeaderProgress = (ProgressBar) findViewById(R.id.pull_to_refresh_progress);
|
|
||||||
mSubHeaderText = (TextView) findViewById(R.id.pull_to_refresh_sub_text);
|
|
||||||
mHeaderImage = (ImageView) findViewById(R.id.pull_to_refresh_image);
|
|
||||||
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PULL_UP_TO_REFRESH:
|
case PULL_FROM_END:
|
||||||
|
lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.TOP : Gravity.LEFT;
|
||||||
|
|
||||||
// Load in labels
|
// Load in labels
|
||||||
mPullLabel = context.getString(R.string.pull_to_refresh_from_bottom_pull_label);
|
mPullLabel = context.getString(R.string.pull_to_refresh_from_bottom_pull_label);
|
||||||
mRefreshingLabel = context.getString(R.string.pull_to_refresh_from_bottom_refreshing_label);
|
mRefreshingLabel = context.getString(R.string.pull_to_refresh_from_bottom_refreshing_label);
|
||||||
mReleaseLabel = context.getString(R.string.pull_to_refresh_from_bottom_release_label);
|
mReleaseLabel = context.getString(R.string.pull_to_refresh_from_bottom_release_label);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PULL_DOWN_TO_REFRESH:
|
case PULL_FROM_START:
|
||||||
default:
|
default:
|
||||||
|
lp.gravity = scrollDirection == Orientation.VERTICAL ? Gravity.BOTTOM : Gravity.RIGHT;
|
||||||
|
|
||||||
// Load in labels
|
// Load in labels
|
||||||
mPullLabel = context.getString(R.string.pull_to_refresh_pull_label);
|
mPullLabel = context.getString(R.string.pull_to_refresh_pull_label);
|
||||||
mRefreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label);
|
mRefreshingLabel = context.getString(R.string.pull_to_refresh_refreshing_label);
|
||||||
@ -84,18 +108,10 @@ public abstract class LoadingLayout extends LinearLayout {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextColor)) {
|
|
||||||
ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderTextColor);
|
|
||||||
setTextColor(null != colors ? colors : ColorStateList.valueOf(Color.BLACK));
|
|
||||||
}
|
|
||||||
if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderSubTextColor)) {
|
|
||||||
ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderSubTextColor);
|
|
||||||
setSubTextColor(null != colors ? colors : ColorStateList.valueOf(Color.BLACK));
|
|
||||||
}
|
|
||||||
if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderBackground)) {
|
if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderBackground)) {
|
||||||
Drawable background = attrs.getDrawable(R.styleable.PullToRefresh_ptrHeaderBackground);
|
Drawable background = attrs.getDrawable(R.styleable.PullToRefresh_ptrHeaderBackground);
|
||||||
if (null != background) {
|
if (null != background) {
|
||||||
setBackgroundDrawable(background);
|
ViewCompat.setBackground(this, background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +126,20 @@ public abstract class LoadingLayout extends LinearLayout {
|
|||||||
setSubTextAppearance(styleID.data);
|
setSubTextAppearance(styleID.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Text Color attrs need to be set after TextAppearance attrs
|
||||||
|
if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderTextColor)) {
|
||||||
|
ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderTextColor);
|
||||||
|
if (null != colors) {
|
||||||
|
setTextColor(colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (attrs.hasValue(R.styleable.PullToRefresh_ptrHeaderSubTextColor)) {
|
||||||
|
ColorStateList colors = attrs.getColorStateList(R.styleable.PullToRefresh_ptrHeaderSubTextColor);
|
||||||
|
if (null != colors) {
|
||||||
|
setSubTextColor(colors);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try and get defined drawable from Attrs
|
// Try and get defined drawable from Attrs
|
||||||
Drawable imageDrawable = null;
|
Drawable imageDrawable = null;
|
||||||
if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawable)) {
|
if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawable)) {
|
||||||
@ -118,19 +148,30 @@ public abstract class LoadingLayout extends LinearLayout {
|
|||||||
|
|
||||||
// Check Specific Drawable from Attrs, these overrite the generic
|
// Check Specific Drawable from Attrs, these overrite the generic
|
||||||
// drawable attr above
|
// drawable attr above
|
||||||
if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableTop) && mode == Mode.PULL_DOWN_TO_REFRESH) {
|
switch (mode) {
|
||||||
imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableTop);
|
case PULL_FROM_START:
|
||||||
} else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableBottom) && mode == Mode.PULL_UP_TO_REFRESH) {
|
default:
|
||||||
imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableTop);
|
if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableStart)) {
|
||||||
|
imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableStart);
|
||||||
|
} else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableTop)) {
|
||||||
|
Utils.warnDeprecation("ptrDrawableTop", "ptrDrawableStart");
|
||||||
|
imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableTop);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PULL_FROM_END:
|
||||||
|
if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableEnd)) {
|
||||||
|
imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableEnd);
|
||||||
|
} else if (attrs.hasValue(R.styleable.PullToRefresh_ptrDrawableBottom)) {
|
||||||
|
Utils.warnDeprecation("ptrDrawableBottom", "ptrDrawableEnd");
|
||||||
|
imageDrawable = attrs.getDrawable(R.styleable.PullToRefresh_ptrDrawableBottom);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have a user defined drawable, load the default
|
// If we don't have a user defined drawable, load the default
|
||||||
if (null == imageDrawable) {
|
if (null == imageDrawable) {
|
||||||
if (mode == Mode.PULL_DOWN_TO_REFRESH) {
|
imageDrawable = context.getResources().getDrawable(getDefaultDrawableResId());
|
||||||
imageDrawable = context.getResources().getDrawable(getDefaultBottomDrawableResId());
|
|
||||||
} else {
|
|
||||||
imageDrawable = context.getResources().getDrawable(getDefaultTopDrawableResId());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Drawable, and save width/height
|
// Set Drawable, and save width/height
|
||||||
@ -139,61 +180,115 @@ public abstract class LoadingLayout extends LinearLayout {
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void onPullY(float scaleOfHeight) {
|
public final void setHeight(int height) {
|
||||||
if (!mUseIntrinisicAnimation) {
|
ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getLayoutParams();
|
||||||
onPullYImpl(scaleOfHeight);
|
lp.height = height;
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setWidth(int width) {
|
||||||
|
ViewGroup.LayoutParams lp = (ViewGroup.LayoutParams) getLayoutParams();
|
||||||
|
lp.width = width;
|
||||||
|
requestLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public final int getContentSize() {
|
||||||
|
switch (mScrollDirection) {
|
||||||
|
case HORIZONTAL:
|
||||||
|
return mInnerLayout.getWidth();
|
||||||
|
case VERTICAL:
|
||||||
|
default:
|
||||||
|
return mInnerLayout.getHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void hideAllViews() {
|
||||||
|
if (View.VISIBLE == mHeaderText.getVisibility()) {
|
||||||
|
mHeaderText.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
if (View.VISIBLE == mHeaderProgress.getVisibility()) {
|
||||||
|
mHeaderProgress.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
if (View.VISIBLE == mHeaderImage.getVisibility()) {
|
||||||
|
mHeaderImage.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
if (View.VISIBLE == mSubHeaderText.getVisibility()) {
|
||||||
|
mSubHeaderText.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void onPull(float scaleOfLayout) {
|
||||||
|
if (!mUseIntrinsicAnimation) {
|
||||||
|
onPullImpl(scaleOfLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void pullToRefresh() {
|
public final void pullToRefresh() {
|
||||||
mHeaderText.setText(mPullLabel);
|
if (null != mHeaderText) {
|
||||||
|
mHeaderText.setText(mPullLabel);
|
||||||
|
}
|
||||||
|
|
||||||
// Now call the callback
|
// Now call the callback
|
||||||
pullToRefreshImpl();
|
pullToRefreshImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void refreshing() {
|
public final void refreshing() {
|
||||||
mHeaderText.setText(mRefreshingLabel);
|
if (null != mHeaderText) {
|
||||||
|
mHeaderText.setText(mRefreshingLabel);
|
||||||
|
}
|
||||||
|
|
||||||
if (mUseIntrinisicAnimation) {
|
if (mUseIntrinsicAnimation) {
|
||||||
((AnimationDrawable) mHeaderImage.getDrawable()).start();
|
((AnimationDrawable) mHeaderImage.getDrawable()).start();
|
||||||
} else {
|
} else {
|
||||||
// Now call the callback
|
// Now call the callback
|
||||||
refreshingImpl();
|
refreshingImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
mSubHeaderText.setVisibility(View.GONE);
|
if (null != mSubHeaderText) {
|
||||||
|
mSubHeaderText.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void releaseToRefresh() {
|
public final void releaseToRefresh() {
|
||||||
mHeaderText.setText(mReleaseLabel);
|
if (null != mHeaderText) {
|
||||||
|
mHeaderText.setText(mReleaseLabel);
|
||||||
|
}
|
||||||
|
|
||||||
// Now call the callback
|
// Now call the callback
|
||||||
releaseToRefreshImpl();
|
releaseToRefreshImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void reset() {
|
public final void reset() {
|
||||||
mHeaderText.setText(mPullLabel);
|
if (null != mHeaderText) {
|
||||||
|
mHeaderText.setText(mPullLabel);
|
||||||
|
}
|
||||||
mHeaderImage.setVisibility(View.VISIBLE);
|
mHeaderImage.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
if (mUseIntrinisicAnimation) {
|
if (mUseIntrinsicAnimation) {
|
||||||
((AnimationDrawable) mHeaderImage.getDrawable()).stop();
|
((AnimationDrawable) mHeaderImage.getDrawable()).stop();
|
||||||
} else {
|
} else {
|
||||||
// Now call the callback
|
// Now call the callback
|
||||||
resetImpl();
|
resetImpl();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(mSubHeaderText.getText())) {
|
if (null != mSubHeaderText) {
|
||||||
mSubHeaderText.setVisibility(View.GONE);
|
if (TextUtils.isEmpty(mSubHeaderText.getText())) {
|
||||||
} else {
|
mSubHeaderText.setVisibility(View.GONE);
|
||||||
mSubHeaderText.setVisibility(View.VISIBLE);
|
} else {
|
||||||
|
mSubHeaderText.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLastUpdatedLabel(CharSequence label) {
|
||||||
|
setSubHeaderText(label);
|
||||||
|
}
|
||||||
|
|
||||||
public final void setLoadingDrawable(Drawable imageDrawable) {
|
public final void setLoadingDrawable(Drawable imageDrawable) {
|
||||||
// Set Drawable
|
// Set Drawable
|
||||||
mHeaderImage.setImageDrawable(imageDrawable);
|
mHeaderImage.setImageDrawable(imageDrawable);
|
||||||
mUseIntrinisicAnimation = (imageDrawable instanceof AnimationDrawable);
|
mUseIntrinsicAnimation = (imageDrawable instanceof AnimationDrawable);
|
||||||
|
|
||||||
// Now call the callback
|
// Now call the callback
|
||||||
onLoadingDrawableSet(imageDrawable);
|
onLoadingDrawableSet(imageDrawable);
|
||||||
@ -211,52 +306,35 @@ public abstract class LoadingLayout extends LinearLayout {
|
|||||||
mReleaseLabel = releaseLabel;
|
mReleaseLabel = releaseLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubHeaderText(CharSequence label) {
|
@Override
|
||||||
if (TextUtils.isEmpty(label)) {
|
public void setTextTypeface(Typeface tf) {
|
||||||
mSubHeaderText.setVisibility(View.GONE);
|
mHeaderText.setTypeface(tf);
|
||||||
} else {
|
}
|
||||||
mSubHeaderText.setText(label);
|
|
||||||
|
public final void showInvisibleViews() {
|
||||||
|
if (View.INVISIBLE == mHeaderText.getVisibility()) {
|
||||||
|
mHeaderText.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
if (View.INVISIBLE == mHeaderProgress.getVisibility()) {
|
||||||
|
mHeaderProgress.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
if (View.INVISIBLE == mHeaderImage.getVisibility()) {
|
||||||
|
mHeaderImage.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
if (View.INVISIBLE == mSubHeaderText.getVisibility()) {
|
||||||
mSubHeaderText.setVisibility(View.VISIBLE);
|
mSubHeaderText.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSubTextAppearance(int value) {
|
|
||||||
mSubHeaderText.setTextAppearance(getContext(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubTextColor(ColorStateList color) {
|
|
||||||
mSubHeaderText.setTextColor(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSubTextColor(int color) {
|
|
||||||
setSubTextColor(ColorStateList.valueOf(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTextAppearance(int value) {
|
|
||||||
mHeaderText.setTextAppearance(getContext(), value);
|
|
||||||
mSubHeaderText.setTextAppearance(getContext(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTextColor(ColorStateList color) {
|
|
||||||
mHeaderText.setTextColor(color);
|
|
||||||
mSubHeaderText.setTextColor(color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTextColor(int color) {
|
|
||||||
setTextColor(ColorStateList.valueOf(color));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callbacks for derivative Layouts
|
* Callbacks for derivative Layouts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected abstract int getDefaultBottomDrawableResId();
|
protected abstract int getDefaultDrawableResId();
|
||||||
|
|
||||||
protected abstract int getDefaultTopDrawableResId();
|
|
||||||
|
|
||||||
protected abstract void onLoadingDrawableSet(Drawable imageDrawable);
|
protected abstract void onLoadingDrawableSet(Drawable imageDrawable);
|
||||||
|
|
||||||
protected abstract void onPullYImpl(float scaleOfHeight);
|
protected abstract void onPullImpl(float scaleOfLayout);
|
||||||
|
|
||||||
protected abstract void pullToRefreshImpl();
|
protected abstract void pullToRefreshImpl();
|
||||||
|
|
||||||
@ -266,4 +344,45 @@ public abstract class LoadingLayout extends LinearLayout {
|
|||||||
|
|
||||||
protected abstract void resetImpl();
|
protected abstract void resetImpl();
|
||||||
|
|
||||||
|
private void setSubHeaderText(CharSequence label) {
|
||||||
|
if (null != mSubHeaderText) {
|
||||||
|
if (TextUtils.isEmpty(label)) {
|
||||||
|
mSubHeaderText.setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
mSubHeaderText.setText(label);
|
||||||
|
mSubHeaderText.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSubTextAppearance(int value) {
|
||||||
|
if (null != mSubHeaderText) {
|
||||||
|
mSubHeaderText.setTextAppearance(getContext(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSubTextColor(ColorStateList color) {
|
||||||
|
if (null != mSubHeaderText) {
|
||||||
|
mSubHeaderText.setTextColor(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTextAppearance(int value) {
|
||||||
|
if (null != mHeaderText) {
|
||||||
|
mHeaderText.setTextAppearance(getContext(), value);
|
||||||
|
}
|
||||||
|
if (null != mSubHeaderText) {
|
||||||
|
mSubHeaderText.setTextAppearance(getContext(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTextColor(ColorStateList color) {
|
||||||
|
if (null != mHeaderText) {
|
||||||
|
mHeaderText.setTextColor(color);
|
||||||
|
}
|
||||||
|
if (null != mSubHeaderText) {
|
||||||
|
mSubHeaderText.setTextColor(color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import android.view.animation.RotateAnimation;
|
|||||||
import android.widget.ImageView.ScaleType;
|
import android.widget.ImageView.ScaleType;
|
||||||
|
|
||||||
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Mode;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.Orientation;
|
||||||
import com.handmark.pulltorefresh.library.R;
|
import com.handmark.pulltorefresh.library.R;
|
||||||
|
|
||||||
public class RotateLoadingLayout extends LoadingLayout {
|
public class RotateLoadingLayout extends LoadingLayout {
|
||||||
@ -35,8 +36,12 @@ public class RotateLoadingLayout extends LoadingLayout {
|
|||||||
|
|
||||||
private float mRotationPivotX, mRotationPivotY;
|
private float mRotationPivotX, mRotationPivotY;
|
||||||
|
|
||||||
public RotateLoadingLayout(Context context, Mode mode, TypedArray attrs) {
|
private final boolean mRotateDrawableWhilePulling;
|
||||||
super(context, mode, attrs);
|
|
||||||
|
public RotateLoadingLayout(Context context, Mode mode, Orientation scrollDirection, TypedArray attrs) {
|
||||||
|
super(context, mode, scrollDirection, attrs);
|
||||||
|
|
||||||
|
mRotateDrawableWhilePulling = attrs.getBoolean(R.styleable.PullToRefresh_ptrRotateDrawableWhilePulling, true);
|
||||||
|
|
||||||
mHeaderImage.setScaleType(ScaleType.MATRIX);
|
mHeaderImage.setScaleType(ScaleType.MATRIX);
|
||||||
mHeaderImageMatrix = new Matrix();
|
mHeaderImageMatrix = new Matrix();
|
||||||
@ -57,8 +62,15 @@ public class RotateLoadingLayout extends LoadingLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void onPullYImpl(float scaleOfHeight) {
|
protected void onPullImpl(float scaleOfLayout) {
|
||||||
mHeaderImageMatrix.setRotate(scaleOfHeight * 90, mRotationPivotX, mRotationPivotY);
|
float angle;
|
||||||
|
if (mRotateDrawableWhilePulling) {
|
||||||
|
angle = scaleOfLayout * 90f;
|
||||||
|
} else {
|
||||||
|
angle = Math.max(0f, Math.min(180f, scaleOfLayout * 360f - 180f));
|
||||||
|
}
|
||||||
|
|
||||||
|
mHeaderImageMatrix.setRotate(angle, mRotationPivotX, mRotationPivotY);
|
||||||
mHeaderImage.setImageMatrix(mHeaderImageMatrix);
|
mHeaderImage.setImageMatrix(mHeaderImageMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,12 +103,7 @@ public class RotateLoadingLayout extends LoadingLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getDefaultTopDrawableResId() {
|
protected int getDefaultDrawableResId() {
|
||||||
return R.drawable.default_ptr_rotate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int getDefaultBottomDrawableResId() {
|
|
||||||
return R.drawable.default_ptr_rotate;
|
return R.drawable.default_ptr_rotate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright 2011, 2012 Chris Banes.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*******************************************************************************/
|
|
||||||
package com.handmark.pulltorefresh.library.internal;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
@TargetApi(16)
|
|
||||||
public class SDK16 {
|
|
||||||
|
|
||||||
public static void postOnAnimation(View view, Runnable runnable) {
|
|
||||||
view.postOnAnimation(runnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.handmark.pulltorefresh.library.internal;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
public class Utils {
|
||||||
|
|
||||||
|
static final String LOG_TAG = "PullToRefresh";
|
||||||
|
|
||||||
|
public static void warnDeprecation(String depreacted, String replacement) {
|
||||||
|
Log.w(LOG_TAG, "You're using the deprecated " + depreacted + " attr, please switch over to " + replacement);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011, 2012 Chris Banes.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.handmark.pulltorefresh.library.internal;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build.VERSION;
|
||||||
|
import android.os.Build.VERSION_CODES;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public class ViewCompat {
|
||||||
|
|
||||||
|
public static void postOnAnimation(View view, Runnable runnable) {
|
||||||
|
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
|
||||||
|
SDK16.postOnAnimation(view, runnable);
|
||||||
|
} else {
|
||||||
|
view.postDelayed(runnable, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBackground(View view, Drawable background) {
|
||||||
|
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) {
|
||||||
|
SDK16.setBackground(view, background);
|
||||||
|
} else {
|
||||||
|
view.setBackgroundDrawable(background);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLayerType(View view, int layerType) {
|
||||||
|
if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
|
||||||
|
SDK11.setLayerType(view, layerType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(11)
|
||||||
|
static class SDK11 {
|
||||||
|
|
||||||
|
public static void setLayerType(View view, int layerType) {
|
||||||
|
view.setLayerType(layerType, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(16)
|
||||||
|
static class SDK16 {
|
||||||
|
|
||||||
|
public static void postOnAnimation(View view, Runnable runnable) {
|
||||||
|
view.postOnAnimation(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setBackground(View view, Drawable background) {
|
||||||
|
view.setBackground(background);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,7 +4,7 @@
|
|||||||
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.4.2</version>
|
<version>2.1.1</version>
|
||||||
<name>Android-PullToRefresh Project</name>
|
<name>Android-PullToRefresh Project</name>
|
||||||
<description>Implementation of the Pull-to-Refresh UI Pattern for Android.</description>
|
<description>Implementation of the Pull-to-Refresh UI Pattern for Android.</description>
|
||||||
<url>https://github.com/chrisbanes/Android-PullToRefresh</url>
|
<url>https://github.com/chrisbanes/Android-PullToRefresh</url>
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<url>https://github.com/chrisbanes/Android-PullToRefresh</url>
|
<url>https://github.com/chrisbanes/Android-PullToRefresh</url>
|
||||||
<connection>scm:git:git://github.com/chrisbanes/Android-PullToRefresh.git</connection>
|
<connection>scm:git:git://github.com/chrisbanes/Android-PullToRefresh.git</connection>
|
||||||
<developerConnection>scm:git:git@github.com:chrisbanes/Android-PullToRefresh.git</developerConnection>
|
<developerConnection>scm:git:git@github.com:chrisbanes/Android-PullToRefresh.git</developerConnection>
|
||||||
<tag>v1.4.2</tag>
|
<tag>v2.1.1</tag>
|
||||||
</scm>
|
</scm>
|
||||||
<developers>
|
<developers>
|
||||||
<developer>
|
<developer>
|
||||||
@ -65,6 +65,10 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>2.3.2</version>
|
<version>2.3.2</version>
|
||||||
|
<configuration>
|
||||||
|
<source>${java.version}</source>
|
||||||
|
<target>${java.version}</target>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.handmark.pulltorefresh.samples"
|
package="com.handmark.pulltorefresh.samples"
|
||||||
android:versionCode="1420"
|
android:versionCode="2110"
|
||||||
android:versionName="1.4.2" >
|
android:versionName="2.1.1" >
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="4"
|
android:minSdkVersion="4"
|
||||||
android:targetSdkVersion="10" />
|
android:targetSdkVersion="15" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
android:icon="@drawable/icon"
|
android:icon="@drawable/icon"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name" >
|
||||||
android:theme="@android:style/Theme.Light" >
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".LauncherActivity"
|
android:name=".LauncherActivity"
|
||||||
android:label="PullToRefresh Samples" >
|
android:label="PullToRefresh Samples" >
|
||||||
@ -29,6 +29,10 @@
|
|||||||
android:name=".PullToRefreshListFragmentActivity"
|
android:name=".PullToRefreshListFragmentActivity"
|
||||||
android:label="PtR ListView Fragment" >
|
android:label="PtR ListView Fragment" >
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".PullToRefreshListInViewPagerActivity"
|
||||||
|
android:label="PtR ListView in ViewPager" >
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".PullToRefreshGridActivity"
|
android:name=".PullToRefreshGridActivity"
|
||||||
android:label="PtR GridView" >
|
android:label="PtR GridView" >
|
||||||
@ -45,6 +49,14 @@
|
|||||||
android:name=".PullToRefreshScrollViewActivity"
|
android:name=".PullToRefreshScrollViewActivity"
|
||||||
android:label="PtR ScrollView" >
|
android:label="PtR ScrollView" >
|
||||||
</activity>
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".PullToRefreshHorizontalScrollViewActivity"
|
||||||
|
android:label="PtR HorizontalScrollView" >
|
||||||
|
</activity>
|
||||||
|
<activity
|
||||||
|
android:name=".PullToRefreshViewPagerActivity"
|
||||||
|
android:label="PtR ViewPager" >
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".PullToRefreshWebView2Activity"
|
android:name=".PullToRefreshWebView2Activity"
|
||||||
android:label="PtR WebView Advanced" >
|
android:label="PtR WebView Advanced" >
|
||||||
|
202
plugins/Android-PullToRefresh/sample/LICENSE
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
BIN
plugins/Android-PullToRefresh/sample/libs/android-support-v4.jar
Normal file
@ -10,7 +10,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
<groupId>com.github.chrisbanes.pulltorefresh</groupId>
|
||||||
<artifactId>parent</artifactId>
|
<artifactId>parent</artifactId>
|
||||||
<version>1.4.2</version>
|
<version>2.1.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -30,6 +30,12 @@
|
|||||||
<type>apklib</type>
|
<type>apklib</type>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>extra-viewpager</artifactId>
|
||||||
|
<type>apklib</type>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -11,3 +11,4 @@
|
|||||||
target=android-15
|
target=android-15
|
||||||
android.library.reference.1=../library
|
android.library.reference.1=../library
|
||||||
android.library.reference.2=../extras/PullToRefreshListFragment
|
android.library.reference.2=../extras/PullToRefreshListFragment
|
||||||
|
android.library.reference.3=../extras/PullToRefreshViewPager
|
||||||
|
After Width: | Height: | Size: 92 KiB |
@ -1,17 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent" >
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<!-- The PullToRefreshExpandableListView replaces a standard ExpandableListView widget. -->
|
<!-- The PullToRefreshExpandableListView replaces a standard ExpandableListView widget. -->
|
||||||
|
|
||||||
<com.handmark.pulltorefresh.library.PullToRefreshExpandableListView
|
<com.handmark.pulltorefresh.library.PullToRefreshExpandableListView
|
||||||
xmlns:ptr="http://schemas.android.com/apk/res-auto"
|
xmlns:ptr="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/pull_refresh_expandable_list"
|
android:id="@+id/pull_refresh_expandable_list"
|
||||||
android:layout_height="fill_parent"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
ptr:ptrAdapterViewBackground="@android:color/white"
|
android:layout_height="fill_parent"
|
||||||
ptr:ptrHeaderBackground="@android:color/darker_gray"
|
ptr:ptrHeaderBackground="@android:color/darker_gray"
|
||||||
ptr:ptrHeaderTextColor="@android:color/white"
|
ptr:ptrHeaderTextColor="@android:color/white"
|
||||||
ptr:ptrMode="pullUpFromBottom" />
|
ptr:ptrMode="pullUpFromBottom" />
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<!-- The PullToRefreshScrollView replaces a standard PullToRefreshScrollView widget. -->
|
||||||
|
|
||||||
|
<com.handmark.pulltorefresh.library.PullToRefreshHorizontalScrollView
|
||||||
|
xmlns:ptr="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/pull_refresh_horizontalscrollview"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
ptr:ptrAnimationStyle="flip"
|
||||||
|
ptr:ptrMode="both" >
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/HorizScrollViewItem"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#ff99cc00" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/HorizScrollViewItem"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#ffff4444" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/HorizScrollViewItem"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#ff33b5e5" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/HorizScrollViewItem"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#ffcc0000" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/HorizScrollViewItem"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#ffffbb33" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/HorizScrollViewItem"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#ff00ddff" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/HorizScrollViewItem"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:background="#ff669900" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.handmark.pulltorefresh.library.PullToRefreshHorizontalScrollView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<!-- The PullToRefreshListView replaces a standard ListView widget. -->
|
||||||
|
|
||||||
|
<android.support.v4.view.ViewPager
|
||||||
|
android:id="@+id/vp_list"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent" >
|
||||||
|
|
||||||
|
<!-- The PullToRefreshScrollView replaces a standard PullToRefreshScrollView widget. -->
|
||||||
|
|
||||||
|
<com.handmark.pulltorefresh.extras.viewpager.PullToRefreshViewPager
|
||||||
|
xmlns:ptr="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/pull_refresh_viewpager"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
ptr:ptrAnimationStyle="flip"
|
||||||
|
ptr:ptrHeaderBackground="@android:color/darker_gray"
|
||||||
|
ptr:ptrMode="both" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.handmark.pulltorefresh.library.PullToRefreshListView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:ptr="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
ptr:ptrHeaderBackground="@android:color/darker_gray" />
|
12
plugins/Android-PullToRefresh/sample/res/values/styles.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<style name="HorizScrollViewItem">
|
||||||
|
<item name="android:paddingRight">50dp</item>
|
||||||
|
<item name="android:paddingLeft">50dp</item>
|
||||||
|
<item name="android:gravity">center</item>
|
||||||
|
<item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
|
||||||
|
<item name="android:text">Sample Item</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</resources>
|
@ -25,7 +25,7 @@ import android.widget.ListView;
|
|||||||
public class LauncherActivity extends ListActivity {
|
public class LauncherActivity extends ListActivity {
|
||||||
|
|
||||||
public static final String[] options = { "ListView", "ExpandableListView", "GridView", "WebView", "ScrollView",
|
public static final String[] options = { "ListView", "ExpandableListView", "GridView", "WebView", "ScrollView",
|
||||||
"ListView Fragment", "WebView Advanced" };
|
"Horizontal ScrollView", "ViewPager", "ListView Fragment", "WebView Advanced", "ListView in ViewPager" };
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -55,11 +55,20 @@ public class LauncherActivity extends ListActivity {
|
|||||||
intent = new Intent(this, PullToRefreshScrollViewActivity.class);
|
intent = new Intent(this, PullToRefreshScrollViewActivity.class);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
intent = new Intent(this, PullToRefreshListFragmentActivity.class);
|
intent = new Intent(this, PullToRefreshHorizontalScrollViewActivity.class);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
|
intent = new Intent(this, PullToRefreshViewPagerActivity.class);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
intent = new Intent(this, PullToRefreshListFragmentActivity.class);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
intent = new Intent(this, PullToRefreshWebView2Activity.class);
|
intent = new Intent(this, PullToRefreshWebView2Activity.class);
|
||||||
break;
|
break;
|
||||||
|
case 9:
|
||||||
|
intent = new Intent(this, PullToRefreshListInViewPagerActivity.class);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
|
@ -16,9 +16,7 @@
|
|||||||
package com.handmark.pulltorefresh.samples;
|
package com.handmark.pulltorefresh.samples;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -34,7 +32,10 @@ import com.handmark.pulltorefresh.library.PullToRefreshExpandableListView;
|
|||||||
|
|
||||||
public final class PullToRefreshExpandableListActivity extends ExpandableListActivity {
|
public final class PullToRefreshExpandableListActivity extends ExpandableListActivity {
|
||||||
private static final String KEY = "key";
|
private static final String KEY = "key";
|
||||||
private LinkedList<String> mListItems, mGroupItems;
|
|
||||||
|
private List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
|
||||||
|
private List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
|
||||||
|
|
||||||
private PullToRefreshExpandableListView mPullRefreshListView;
|
private PullToRefreshExpandableListView mPullRefreshListView;
|
||||||
private SimpleExpandableListAdapter mAdapter;
|
private SimpleExpandableListAdapter mAdapter;
|
||||||
|
|
||||||
@ -55,13 +56,6 @@ public final class PullToRefreshExpandableListActivity extends ExpandableListAct
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
mListItems = new LinkedList<String>();
|
|
||||||
mListItems.addAll(Arrays.asList(mChildStrings));
|
|
||||||
mGroupItems = new LinkedList<String>();
|
|
||||||
mGroupItems.addAll(Arrays.asList(mGroupStrings));
|
|
||||||
|
|
||||||
List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
|
|
||||||
List<List<Map<String, String>>> childData = new ArrayList<List<Map<String, String>>>();
|
|
||||||
for (String group : mGroupStrings) {
|
for (String group : mGroupStrings) {
|
||||||
Map<String, String> groupMap1 = new HashMap<String, String>();
|
Map<String, String> groupMap1 = new HashMap<String, String>();
|
||||||
groupData.add(groupMap1);
|
groupData.add(groupMap1);
|
||||||
@ -96,7 +90,18 @@ public final class PullToRefreshExpandableListActivity extends ExpandableListAct
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(String[] result) {
|
protected void onPostExecute(String[] result) {
|
||||||
mListItems.addFirst("Added after refresh...");
|
Map<String, String> newMap = new HashMap<String, String>();
|
||||||
|
newMap.put(KEY, "Added after refresh...");
|
||||||
|
groupData.add(newMap);
|
||||||
|
|
||||||
|
List<Map<String, String>> childList = new ArrayList<Map<String, String>>();
|
||||||
|
for (String string : mChildStrings) {
|
||||||
|
Map<String, String> childMap = new HashMap<String, String>();
|
||||||
|
childMap.put(KEY, string);
|
||||||
|
childList.add(childMap);
|
||||||
|
}
|
||||||
|
childData.add(childList);
|
||||||
|
|
||||||
mAdapter.notifyDataSetChanged();
|
mAdapter.notifyDataSetChanged();
|
||||||
|
|
||||||
// Call onRefreshComplete when the list has been refreshed.
|
// Call onRefreshComplete when the list has been refreshed.
|
||||||
@ -106,8 +111,7 @@ public final class PullToRefreshExpandableListActivity extends ExpandableListAct
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String[] mChildStrings = { "Child One", "Child Two", "Child Three", "Child Four", "Child Five",
|
private String[] mChildStrings = { "Child One", "Child Two", "Child Three", "Child Four", "Child Five", "Child Six" };
|
||||||
"Child Six" };
|
|
||||||
|
|
||||||
private final String[] mGroupStrings = { "Group One", "Group Two", "Group Three" };
|
private String[] mGroupStrings = { "Group One", "Group Two", "Group Three" };
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ public final class PullToRefreshGridActivity extends Activity {
|
|||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
MenuItem setModeItem = menu.findItem(MENU_SET_MODE);
|
MenuItem setModeItem = menu.findItem(MENU_SET_MODE);
|
||||||
setModeItem.setTitle(mPullRefreshGridView.getMode() == Mode.BOTH ? "Change to MODE_PULL_DOWN"
|
setModeItem.setTitle(mPullRefreshGridView.getMode() == Mode.BOTH ? "Change to MODE_PULL_FROM_START"
|
||||||
: "Change to MODE_PULL_BOTH");
|
: "Change to MODE_PULL_BOTH");
|
||||||
|
|
||||||
return super.onPrepareOptionsMenu(menu);
|
return super.onPrepareOptionsMenu(menu);
|
||||||
@ -127,7 +127,7 @@ public final class PullToRefreshGridActivity extends Activity {
|
|||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case MENU_SET_MODE:
|
case MENU_SET_MODE:
|
||||||
mPullRefreshGridView
|
mPullRefreshGridView
|
||||||
.setMode(mPullRefreshGridView.getMode() == Mode.BOTH ? Mode.PULL_DOWN_TO_REFRESH
|
.setMode(mPullRefreshGridView.getMode() == Mode.BOTH ? Mode.PULL_FROM_START
|
||||||
: Mode.BOTH);
|
: Mode.BOTH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,73 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011, 2012 Chris Banes.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.handmark.pulltorefresh.samples;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshHorizontalScrollView;
|
||||||
|
|
||||||
|
public final class PullToRefreshHorizontalScrollViewActivity extends Activity {
|
||||||
|
|
||||||
|
PullToRefreshHorizontalScrollView mPullRefreshScrollView;
|
||||||
|
HorizontalScrollView mScrollView;
|
||||||
|
|
||||||
|
/** Called when the activity is first created. */
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_ptr_horizontalscrollview);
|
||||||
|
|
||||||
|
mPullRefreshScrollView = (PullToRefreshHorizontalScrollView) findViewById(R.id.pull_refresh_horizontalscrollview);
|
||||||
|
mPullRefreshScrollView.setOnRefreshListener(new OnRefreshListener<HorizontalScrollView>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh(PullToRefreshBase<HorizontalScrollView> refreshView) {
|
||||||
|
new GetDataTask().execute();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mScrollView = mPullRefreshScrollView.getRefreshableView();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GetDataTask extends AsyncTask<Void, Void, String[]> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String[] doInBackground(Void... params) {
|
||||||
|
// Simulates a background job.
|
||||||
|
try {
|
||||||
|
Thread.sleep(4000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(String[] result) {
|
||||||
|
// Do some stuff here
|
||||||
|
|
||||||
|
// Call onRefreshComplete when the list has been refreshed.
|
||||||
|
mPullRefreshScrollView.onRefreshComplete();
|
||||||
|
|
||||||
|
super.onPostExecute(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,8 +22,12 @@ import android.app.ListActivity;
|
|||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.format.DateUtils;
|
import android.text.format.DateUtils;
|
||||||
|
import android.view.ContextMenu;
|
||||||
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -41,6 +45,7 @@ public final class PullToRefreshListActivity extends ListActivity {
|
|||||||
static final int MENU_MANUAL_REFRESH = 0;
|
static final int MENU_MANUAL_REFRESH = 0;
|
||||||
static final int MENU_DISABLE_SCROLL = 1;
|
static final int MENU_DISABLE_SCROLL = 1;
|
||||||
static final int MENU_SET_MODE = 2;
|
static final int MENU_SET_MODE = 2;
|
||||||
|
static final int MENU_DEMO = 3;
|
||||||
|
|
||||||
private LinkedList<String> mListItems;
|
private LinkedList<String> mListItems;
|
||||||
private PullToRefreshListView mPullRefreshListView;
|
private PullToRefreshListView mPullRefreshListView;
|
||||||
@ -58,9 +63,11 @@ public final class PullToRefreshListActivity extends ListActivity {
|
|||||||
mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
|
mPullRefreshListView.setOnRefreshListener(new OnRefreshListener<ListView>() {
|
||||||
@Override
|
@Override
|
||||||
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
|
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
|
||||||
mPullRefreshListView.setLastUpdatedLabel(DateUtils.formatDateTime(getApplicationContext(),
|
String label = DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),
|
||||||
System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE
|
DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL);
|
||||||
| DateUtils.FORMAT_ABBREV_ALL));
|
|
||||||
|
// Update the LastUpdatedLabel
|
||||||
|
refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label);
|
||||||
|
|
||||||
// Do work to refresh the list here.
|
// Do work to refresh the list here.
|
||||||
new GetDataTask().execute();
|
new GetDataTask().execute();
|
||||||
@ -78,6 +85,9 @@ public final class PullToRefreshListActivity extends ListActivity {
|
|||||||
|
|
||||||
ListView actualListView = mPullRefreshListView.getRefreshableView();
|
ListView actualListView = mPullRefreshListView.getRefreshableView();
|
||||||
|
|
||||||
|
// Need to use the Actual ListView when registering for Context Menu
|
||||||
|
registerForContextMenu(actualListView);
|
||||||
|
|
||||||
mListItems = new LinkedList<String>();
|
mListItems = new LinkedList<String>();
|
||||||
mListItems.addAll(Arrays.asList(mStrings));
|
mListItems.addAll(Arrays.asList(mStrings));
|
||||||
|
|
||||||
@ -125,22 +135,36 @@ public final class PullToRefreshListActivity extends ListActivity {
|
|||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
menu.add(0, MENU_MANUAL_REFRESH, 0, "Manual Refresh");
|
menu.add(0, MENU_MANUAL_REFRESH, 0, "Manual Refresh");
|
||||||
menu.add(0, MENU_DISABLE_SCROLL, 1,
|
menu.add(0, MENU_DISABLE_SCROLL, 1,
|
||||||
mPullRefreshListView.isDisableScrollingWhileRefreshing() ? "Enable Scrolling while Refreshing"
|
mPullRefreshListView.isScrollingWhileRefreshingEnabled() ? "Disable Scrolling while Refreshing"
|
||||||
: "Disable Scrolling while Refreshing");
|
: "Enable Scrolling while Refreshing");
|
||||||
menu.add(0, MENU_SET_MODE, 0, mPullRefreshListView.getMode() == Mode.BOTH ? "Change to MODE_PULL_DOWN"
|
menu.add(0, MENU_SET_MODE, 0, mPullRefreshListView.getMode() == Mode.BOTH ? "Change to MODE_PULL_DOWN"
|
||||||
: "Change to MODE_PULL_BOTH");
|
: "Change to MODE_PULL_BOTH");
|
||||||
|
menu.add(0, MENU_DEMO, 0, "Demo");
|
||||||
return super.onCreateOptionsMenu(menu);
|
return super.onCreateOptionsMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||||
|
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
||||||
|
|
||||||
|
menu.setHeaderTitle("Item: " + getListView().getItemAtPosition(info.position));
|
||||||
|
menu.add("Item 1");
|
||||||
|
menu.add("Item 2");
|
||||||
|
menu.add("Item 3");
|
||||||
|
menu.add("Item 4");
|
||||||
|
|
||||||
|
super.onCreateContextMenu(menu, v, menuInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||||
MenuItem disableItem = menu.findItem(MENU_DISABLE_SCROLL);
|
MenuItem disableItem = menu.findItem(MENU_DISABLE_SCROLL);
|
||||||
disableItem
|
disableItem
|
||||||
.setTitle(mPullRefreshListView.isDisableScrollingWhileRefreshing() ? "Enable Scrolling while Refreshing"
|
.setTitle(mPullRefreshListView.isScrollingWhileRefreshingEnabled() ? "Disable Scrolling while Refreshing"
|
||||||
: "Disable Scrolling while Refreshing");
|
: "Enable Scrolling while Refreshing");
|
||||||
|
|
||||||
MenuItem setModeItem = menu.findItem(MENU_SET_MODE);
|
MenuItem setModeItem = menu.findItem(MENU_SET_MODE);
|
||||||
setModeItem.setTitle(mPullRefreshListView.getMode() == Mode.BOTH ? "Change to MODE_PULL_DOWN"
|
setModeItem.setTitle(mPullRefreshListView.getMode() == Mode.BOTH ? "Change to MODE_FROM_START"
|
||||||
: "Change to MODE_PULL_BOTH");
|
: "Change to MODE_PULL_BOTH");
|
||||||
|
|
||||||
return super.onPrepareOptionsMenu(menu);
|
return super.onPrepareOptionsMenu(menu);
|
||||||
@ -155,13 +179,16 @@ public final class PullToRefreshListActivity extends ListActivity {
|
|||||||
mPullRefreshListView.setRefreshing(false);
|
mPullRefreshListView.setRefreshing(false);
|
||||||
break;
|
break;
|
||||||
case MENU_DISABLE_SCROLL:
|
case MENU_DISABLE_SCROLL:
|
||||||
mPullRefreshListView.setDisableScrollingWhileRefreshing(!mPullRefreshListView
|
mPullRefreshListView.setScrollingWhileRefreshingEnabled(!mPullRefreshListView
|
||||||
.isDisableScrollingWhileRefreshing());
|
.isScrollingWhileRefreshingEnabled());
|
||||||
break;
|
break;
|
||||||
case MENU_SET_MODE:
|
case MENU_SET_MODE:
|
||||||
mPullRefreshListView.setMode(mPullRefreshListView.getMode() == Mode.BOTH ? Mode.PULL_DOWN_TO_REFRESH
|
mPullRefreshListView.setMode(mPullRefreshListView.getMode() == Mode.BOTH ? Mode.PULL_FROM_START
|
||||||
: Mode.BOTH);
|
: Mode.BOTH);
|
||||||
break;
|
break;
|
||||||
|
case MENU_DEMO:
|
||||||
|
mPullRefreshListView.demo();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.handmark.pulltorefresh.samples;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.view.PagerAdapter;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewGroup.LayoutParams;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ListAdapter;
|
||||||
|
import android.widget.ListView;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshListView;
|
||||||
|
|
||||||
|
public class PullToRefreshListInViewPagerActivity extends Activity implements OnRefreshListener<ListView> {
|
||||||
|
|
||||||
|
private static final String[] STRINGS = { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance",
|
||||||
|
"Ackawi", "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
|
||||||
|
"Allgauer Emmentaler", "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
|
||||||
|
"Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre",
|
||||||
|
"Allgauer Emmentaler" };
|
||||||
|
|
||||||
|
private ViewPager mViewPager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_ptr_list_in_vp);
|
||||||
|
|
||||||
|
mViewPager = (ViewPager) findViewById(R.id.vp_list);
|
||||||
|
mViewPager.setAdapter(new ListViewPagerAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ListViewPagerAdapter extends PagerAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View instantiateItem(ViewGroup container, int position) {
|
||||||
|
Context context = container.getContext();
|
||||||
|
|
||||||
|
PullToRefreshListView plv = (PullToRefreshListView) LayoutInflater.from(context).inflate(
|
||||||
|
R.layout.layout_listview_in_viewpager, container, false);
|
||||||
|
|
||||||
|
ListAdapter adapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1,
|
||||||
|
Arrays.asList(STRINGS));
|
||||||
|
plv.setAdapter(adapter);
|
||||||
|
|
||||||
|
plv.setOnRefreshListener(PullToRefreshListInViewPagerActivity.this);
|
||||||
|
|
||||||
|
// Now just add ListView to ViewPager and return it
|
||||||
|
container.addView(plv, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
|
|
||||||
|
return plv;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||||
|
container.removeView((View) object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewFromObject(View view, Object object) {
|
||||||
|
return view == object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh(PullToRefreshBase<ListView> refreshView) {
|
||||||
|
new GetDataTask(refreshView).execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GetDataTask extends AsyncTask<Void, Void, Void> {
|
||||||
|
|
||||||
|
PullToRefreshBase<?> mRefreshedView;
|
||||||
|
|
||||||
|
public GetDataTask(PullToRefreshBase<?> refreshedView) {
|
||||||
|
mRefreshedView = refreshedView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... params) {
|
||||||
|
// Simulates a background job.
|
||||||
|
try {
|
||||||
|
Thread.sleep(4000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void result) {
|
||||||
|
mRefreshedView.onRefreshComplete();
|
||||||
|
super.onPostExecute(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright 2011, 2012 Chris Banes.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*******************************************************************************/
|
||||||
|
package com.handmark.pulltorefresh.samples;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.view.PagerAdapter;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.ViewGroup.LayoutParams;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.handmark.pulltorefresh.extras.viewpager.PullToRefreshViewPager;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase;
|
||||||
|
import com.handmark.pulltorefresh.library.PullToRefreshBase.OnRefreshListener;
|
||||||
|
|
||||||
|
public class PullToRefreshViewPagerActivity extends Activity implements OnRefreshListener<ViewPager> {
|
||||||
|
|
||||||
|
private PullToRefreshViewPager mPullToRefreshViewPager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.activity_ptr_viewpager);
|
||||||
|
|
||||||
|
mPullToRefreshViewPager = (PullToRefreshViewPager) findViewById(R.id.pull_refresh_viewpager);
|
||||||
|
mPullToRefreshViewPager.setOnRefreshListener(this);
|
||||||
|
|
||||||
|
ViewPager vp = mPullToRefreshViewPager.getRefreshableView();
|
||||||
|
vp.setAdapter(new SamplePagerAdapter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefresh(PullToRefreshBase<ViewPager> refreshView) {
|
||||||
|
new GetDataTask().execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class SamplePagerAdapter extends PagerAdapter {
|
||||||
|
|
||||||
|
private static int[] sDrawables = { R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper,
|
||||||
|
R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper };
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return sDrawables.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View instantiateItem(ViewGroup container, int position) {
|
||||||
|
ImageView imageView = new ImageView(container.getContext());
|
||||||
|
imageView.setImageResource(sDrawables[position]);
|
||||||
|
|
||||||
|
// Now just add ImageView to ViewPager and return it
|
||||||
|
container.addView(imageView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
|
||||||
|
|
||||||
|
return imageView;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||||
|
container.removeView((View) object);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isViewFromObject(View view, Object object) {
|
||||||
|
return view == object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GetDataTask extends AsyncTask<Void, Void, Void> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void doInBackground(Void... params) {
|
||||||
|
// Simulates a background job.
|
||||||
|
try {
|
||||||
|
Thread.sleep(4000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Void result) {
|
||||||
|
mPullToRefreshViewPager.onRefreshComplete();
|
||||||
|
super.onPostExecute(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|