@ -0,0 +1,17 @@ |
|||||||
|
package org.transdroid.core.gui.lists; |
||||||
|
|
||||||
|
import org.transdroid.core.R; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.view.View; |
||||||
|
import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.AbsDefaultHeaderTransformer; |
||||||
|
|
||||||
|
public class NoProgressHeaderTransformer extends AbsDefaultHeaderTransformer { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onViewCreated(Activity activity, View headerView) { |
||||||
|
super.onViewCreated(activity, headerView); |
||||||
|
setProgressBarColor(activity.getResources().getColor(R.color.green)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
package="uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock"> |
||||||
|
|
||||||
|
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="18" /> |
||||||
|
<application /> |
||||||
|
</manifest> |
@ -0,0 +1,25 @@ |
|||||||
|
apply plugin: 'android-library' |
||||||
|
|
||||||
|
dependencies { |
||||||
|
compile project(':library') |
||||||
|
compile "com.android.support:support-v4:[18.0,)" |
||||||
|
compile ("com.actionbarsherlock:actionbarsherlock:[4.4,)@aar") { |
||||||
|
// Need to specifically exclude this as it is specified in ActionBarSherlock pom |
||||||
|
exclude group: 'com.google.android', module: 'support-v4' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
android { |
||||||
|
compileSdkVersion 18 |
||||||
|
buildToolsVersion '17.0.0' |
||||||
|
|
||||||
|
sourceSets { |
||||||
|
main { |
||||||
|
manifest.srcFile 'AndroidManifest.xml' |
||||||
|
java.srcDirs = ['src'] |
||||||
|
res.srcDirs = ['res'] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
apply from: '../../maven_push.gradle' |
@ -0,0 +1,92 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project name="ActionBar-PullToRefresh-actionbarsherlock" default="help"> |
||||||
|
|
||||||
|
<!-- The local.properties file is created and updated by the 'android' tool. |
||||||
|
It contains the path to the SDK. It should *NOT* be checked into |
||||||
|
Version Control Systems. --> |
||||||
|
<property file="local.properties" /> |
||||||
|
|
||||||
|
<!-- The ant.properties file can be created by you. It is only edited by the |
||||||
|
'android' tool to add properties to it. |
||||||
|
This is the place to change some Ant specific build properties. |
||||||
|
Here are some properties you may want to change/update: |
||||||
|
|
||||||
|
source.dir |
||||||
|
The name of the source directory. Default is 'src'. |
||||||
|
out.dir |
||||||
|
The name of the output directory. Default is 'bin'. |
||||||
|
|
||||||
|
For other overridable properties, look at the beginning of the rules |
||||||
|
files in the SDK, at tools/ant/build.xml |
||||||
|
|
||||||
|
Properties related to the SDK location or the project target should |
||||||
|
be updated using the 'android' tool with the 'update' action. |
||||||
|
|
||||||
|
This file is an integral part of the build system for your |
||||||
|
application and should be checked into Version Control Systems. |
||||||
|
|
||||||
|
--> |
||||||
|
<property file="ant.properties" /> |
||||||
|
|
||||||
|
<!-- if sdk.dir was not set from one of the property file, then |
||||||
|
get it from the ANDROID_HOME env var. |
||||||
|
This must be done before we load project.properties since |
||||||
|
the proguard config can use sdk.dir --> |
||||||
|
<property environment="env" /> |
||||||
|
<condition property="sdk.dir" value="${env.ANDROID_HOME}"> |
||||||
|
<isset property="env.ANDROID_HOME" /> |
||||||
|
</condition> |
||||||
|
|
||||||
|
<!-- The project.properties file is created and updated by the 'android' |
||||||
|
tool, as well as ADT. |
||||||
|
|
||||||
|
This contains project specific properties such as project target, and library |
||||||
|
dependencies. Lower level build properties are stored in ant.properties |
||||||
|
(or in .classpath for Eclipse projects). |
||||||
|
|
||||||
|
This file is an integral part of the build system for your |
||||||
|
application and should be checked into Version Control Systems. --> |
||||||
|
<loadproperties srcFile="project.properties" /> |
||||||
|
|
||||||
|
<!-- quick check on sdk.dir --> |
||||||
|
<fail |
||||||
|
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." |
||||||
|
unless="sdk.dir" |
||||||
|
/> |
||||||
|
|
||||||
|
<!-- |
||||||
|
Import per project custom build rules if present at the root of the project. |
||||||
|
This is the place to put custom intermediary targets such as: |
||||||
|
-pre-build |
||||||
|
-pre-compile |
||||||
|
-post-compile (This is typically used for code obfuscation. |
||||||
|
Compiled code location: ${out.classes.absolute.dir} |
||||||
|
If this is not done in place, override ${out.dex.input.absolute.dir}) |
||||||
|
-post-package |
||||||
|
-post-build |
||||||
|
-pre-clean |
||||||
|
--> |
||||||
|
<import file="custom_rules.xml" optional="true" /> |
||||||
|
|
||||||
|
<!-- Import the actual build file. |
||||||
|
|
||||||
|
To customize existing targets, there are two options: |
||||||
|
- Customize only one target: |
||||||
|
- copy/paste the target into this file, *before* the |
||||||
|
<import> task. |
||||||
|
- customize it to your needs. |
||||||
|
- Customize the whole content of build.xml |
||||||
|
- copy/paste the content of the rules files (minus the top node) |
||||||
|
into this file, replacing the <import> task. |
||||||
|
- customize to your needs. |
||||||
|
|
||||||
|
*********************** |
||||||
|
****** IMPORTANT ****** |
||||||
|
*********************** |
||||||
|
In all cases you must update the value of version-tag below to read 'custom' instead of an integer, |
||||||
|
in order to avoid having your file be overridden by tools such as "android update project" |
||||||
|
--> |
||||||
|
<!-- version-tag: 1 --> |
||||||
|
<import file="${sdk.dir}/tools/ant/build.xml" /> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,3 @@ |
|||||||
|
POM_NAME=ActionBar-PullToRefresh Extras: ActionBarSherlock |
||||||
|
POM_ARTIFACT_ID=extra-abs |
||||||
|
POM_PACKAGING=aar |
@ -0,0 +1,20 @@ |
|||||||
|
# To enable ProGuard in your project, edit project.properties |
||||||
|
# to define the proguard.config property as described in that file. |
||||||
|
# |
||||||
|
# Add project specific ProGuard rules here. |
||||||
|
# By default, the flags in this file are appended to flags specified |
||||||
|
# in ${sdk.dir}/tools/proguard/proguard-android.txt |
||||||
|
# You can edit the include path and order by changing the ProGuard |
||||||
|
# include property in project.properties. |
||||||
|
# |
||||||
|
# For more details, see |
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html |
||||||
|
|
||||||
|
# Add any project specific keep options here: |
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following |
||||||
|
# and specify the fully qualified class name to the JavaScript interface |
||||||
|
# class: |
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
||||||
|
# public *; |
||||||
|
#} |
@ -0,0 +1,17 @@ |
|||||||
|
# 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 |
||||||
|
|
||||||
|
# Project target. |
||||||
|
target=android-18 |
||||||
|
android.library=true |
||||||
|
android.library.reference.1=../ActionBar-PullToRefresh |
||||||
|
android.library.reference.2=../JakeWharton-ActionBarSherlock/library |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
|
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<alpha xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:duration="@android:integer/config_shortAnimTime" |
||||||
|
android:fromAlpha="0.0" |
||||||
|
android:toAlpha="1.0" /> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
|
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<alpha xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:duration="@android:integer/config_shortAnimTime" |
||||||
|
android:fromAlpha="1.0" |
||||||
|
android:toAlpha="0.0" /> |
@ -0,0 +1,187 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.os.Build; |
||||||
|
import android.view.View; |
||||||
|
import android.view.animation.Animation; |
||||||
|
import android.view.animation.AnimationUtils; |
||||||
|
|
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.DefaultHeaderTransformer; |
||||||
|
|
||||||
|
public class AbsDefaultHeaderTransformer extends DefaultHeaderTransformer { |
||||||
|
|
||||||
|
private Animation mHeaderInAnimation, mHeaderOutAnimation; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onViewCreated(Activity activity, View headerView) { |
||||||
|
super.onViewCreated(activity, headerView); |
||||||
|
|
||||||
|
// Create animations for use later
|
||||||
|
mHeaderInAnimation = AnimationUtils.loadAnimation(activity, R.anim.fade_in); |
||||||
|
mHeaderOutAnimation = AnimationUtils.loadAnimation(activity, R.anim.fade_out); |
||||||
|
|
||||||
|
if (mHeaderOutAnimation != null || mHeaderInAnimation != null) { |
||||||
|
final AnimationCallback callback = new AnimationCallback(); |
||||||
|
if (mHeaderOutAnimation != null) { |
||||||
|
mHeaderOutAnimation.setAnimationListener(callback); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected Drawable getActionBarBackground(Context context) { |
||||||
|
// Super handles ICS+ anyway...
|
||||||
|
if (Build.VERSION.SDK_INT >= super.getMinimumApiLevel()) { |
||||||
|
return super.getActionBarBackground(context); |
||||||
|
} |
||||||
|
|
||||||
|
// Get action bar style values...
|
||||||
|
TypedArray abStyle = obtainStyledAttrsFromThemeAttr(context, R.attr.actionBarStyle, |
||||||
|
R.styleable.SherlockActionBar); |
||||||
|
try { |
||||||
|
return abStyle.getDrawable(R.styleable.SherlockActionBar_background); |
||||||
|
} finally { |
||||||
|
abStyle.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getActionBarSize(Context context) { |
||||||
|
// Super handles ICS+ anyway...
|
||||||
|
if (Build.VERSION.SDK_INT >= super.getMinimumApiLevel()) { |
||||||
|
return super.getActionBarSize(context); |
||||||
|
} |
||||||
|
|
||||||
|
TypedArray values = context.obtainStyledAttributes(R.styleable.SherlockTheme); |
||||||
|
try { |
||||||
|
return values.getDimensionPixelSize(R.styleable.SherlockTheme_actionBarSize, 0); |
||||||
|
} finally { |
||||||
|
values.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getActionBarTitleStyle(Context context) { |
||||||
|
// Super handles ICS+ anyway...
|
||||||
|
if (Build.VERSION.SDK_INT >= super.getMinimumApiLevel()) { |
||||||
|
return super.getActionBarTitleStyle(context); |
||||||
|
} |
||||||
|
|
||||||
|
// Get action bar style values...
|
||||||
|
TypedArray abStyle = obtainStyledAttrsFromThemeAttr(context, R.attr.actionBarStyle, |
||||||
|
R.styleable.SherlockActionBar); |
||||||
|
try { |
||||||
|
return abStyle.getResourceId(R.styleable.SherlockActionBar_titleTextStyle, 0); |
||||||
|
} finally { |
||||||
|
abStyle.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean showHeaderView() { |
||||||
|
// Super handles ICS+ anyway...
|
||||||
|
if (Build.VERSION.SDK_INT >= super.getMinimumApiLevel()) { |
||||||
|
return super.showHeaderView(); |
||||||
|
} |
||||||
|
|
||||||
|
final View headerView = getHeaderView(); |
||||||
|
final boolean changeVis = headerView != null && headerView.getVisibility() != View.VISIBLE; |
||||||
|
if (changeVis) { |
||||||
|
// Show Header
|
||||||
|
if (mHeaderInAnimation != null) { |
||||||
|
// AnimationListener will call HeaderViewListener
|
||||||
|
headerView.startAnimation(mHeaderInAnimation); |
||||||
|
} |
||||||
|
headerView.setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
return changeVis; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean hideHeaderView() { |
||||||
|
// Super handles ICS+ anyway...
|
||||||
|
if (Build.VERSION.SDK_INT >= super.getMinimumApiLevel()) { |
||||||
|
return super.hideHeaderView(); |
||||||
|
} |
||||||
|
|
||||||
|
final View headerView = getHeaderView(); |
||||||
|
final boolean changeVis = headerView != null && headerView.getVisibility() != View.GONE; |
||||||
|
if (changeVis) { |
||||||
|
// Hide Header
|
||||||
|
if (mHeaderOutAnimation != null) { |
||||||
|
// AnimationListener will call HeaderTransformer and
|
||||||
|
// HeaderViewListener
|
||||||
|
headerView.startAnimation(mHeaderOutAnimation); |
||||||
|
} else { |
||||||
|
// As we're not animating, hide the header + call the header
|
||||||
|
// transformer now
|
||||||
|
headerView.setVisibility(View.GONE); |
||||||
|
onReset(); |
||||||
|
} |
||||||
|
} |
||||||
|
return changeVis; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onRefreshMinimized() { |
||||||
|
// Super handles ICS+ anyway...
|
||||||
|
if (Build.VERSION.SDK_INT >= super.getMinimumApiLevel()) { |
||||||
|
super.onRefreshMinimized(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// Here we fade out most of the header, leaving just the progress bar
|
||||||
|
View contentLayout = getHeaderView().findViewById(R.id.ptr_content); |
||||||
|
if (contentLayout != null) { |
||||||
|
contentLayout.startAnimation(AnimationUtils |
||||||
|
.loadAnimation(contentLayout.getContext(), R.anim.fade_out)); |
||||||
|
contentLayout.setVisibility(View.INVISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected int getMinimumApiLevel() { |
||||||
|
return Build.VERSION_CODES.ECLAIR_MR1; |
||||||
|
} |
||||||
|
|
||||||
|
class AnimationCallback implements Animation.AnimationListener { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAnimationStart(Animation animation) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAnimationEnd(Animation animation) { |
||||||
|
if (animation == mHeaderOutAnimation) { |
||||||
|
View headerView = getHeaderView(); |
||||||
|
if (headerView != null) { |
||||||
|
headerView.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
onReset(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onAnimationRepeat(Animation animation) { |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock; |
||||||
|
|
||||||
|
import com.actionbarsherlock.app.SherlockActivity; |
||||||
|
import com.actionbarsherlock.app.SherlockExpandableListActivity; |
||||||
|
import com.actionbarsherlock.app.SherlockFragmentActivity; |
||||||
|
import com.actionbarsherlock.app.SherlockListActivity; |
||||||
|
import com.actionbarsherlock.app.SherlockPreferenceActivity; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
|
||||||
|
public class PullToRefreshAttacher extends |
||||||
|
uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher { |
||||||
|
|
||||||
|
public static PullToRefreshAttacher get(Activity activity) { |
||||||
|
return get(activity, new Options()); |
||||||
|
} |
||||||
|
|
||||||
|
public static PullToRefreshAttacher get(Activity activity, Options options) { |
||||||
|
return new PullToRefreshAttacher(activity, options); |
||||||
|
} |
||||||
|
|
||||||
|
protected PullToRefreshAttacher(Activity activity, Options options) { |
||||||
|
super(activity, options); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected EnvironmentDelegate createDefaultEnvironmentDelegate() { |
||||||
|
return new AbsEnvironmentDelegate(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected HeaderTransformer createDefaultHeaderTransformer() { |
||||||
|
return new AbsDefaultHeaderTransformer(); |
||||||
|
} |
||||||
|
|
||||||
|
public static class AbsEnvironmentDelegate extends EnvironmentDelegate { |
||||||
|
/** |
||||||
|
* @return Context which should be used for inflating the header layout |
||||||
|
*/ |
||||||
|
public Context getContextForInflater(Activity activity) { |
||||||
|
if (activity instanceof SherlockActivity) { |
||||||
|
return ((SherlockActivity) activity).getSupportActionBar().getThemedContext(); |
||||||
|
} else if (activity instanceof SherlockListActivity) { |
||||||
|
return ((SherlockListActivity) activity).getSupportActionBar().getThemedContext(); |
||||||
|
} else if (activity instanceof SherlockFragmentActivity) { |
||||||
|
return ((SherlockFragmentActivity) activity).getSupportActionBar() |
||||||
|
.getThemedContext(); |
||||||
|
} else if (activity instanceof SherlockExpandableListActivity) { |
||||||
|
return ((SherlockExpandableListActivity) activity).getSupportActionBar() |
||||||
|
.getThemedContext(); |
||||||
|
} else if (activity instanceof SherlockPreferenceActivity) { |
||||||
|
return ((SherlockPreferenceActivity) activity).getSupportActionBar() |
||||||
|
.getThemedContext(); |
||||||
|
} |
||||||
|
return super.getContextForInflater(activity); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
package="uk.co.senab.actionbarpulltorefresh.library"> |
||||||
|
|
||||||
|
<uses-sdk android:targetSdkVersion="18" /> |
||||||
|
<application /> |
||||||
|
</manifest> |
@ -0,0 +1,16 @@ |
|||||||
|
apply plugin: 'android-library' |
||||||
|
|
||||||
|
android { |
||||||
|
compileSdkVersion 18 |
||||||
|
buildToolsVersion '17.0.0' |
||||||
|
|
||||||
|
sourceSets { |
||||||
|
main { |
||||||
|
manifest.srcFile 'AndroidManifest.xml' |
||||||
|
java.srcDirs = ['src'] |
||||||
|
res.srcDirs = ['res'] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
apply from: '../maven_push.gradle' |
@ -0,0 +1,92 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project name="ActionBar-PullToRefresh" default="help"> |
||||||
|
|
||||||
|
<!-- The local.properties file is created and updated by the 'android' tool. |
||||||
|
It contains the path to the SDK. It should *NOT* be checked into |
||||||
|
Version Control Systems. --> |
||||||
|
<property file="local.properties" /> |
||||||
|
|
||||||
|
<!-- The ant.properties file can be created by you. It is only edited by the |
||||||
|
'android' tool to add properties to it. |
||||||
|
This is the place to change some Ant specific build properties. |
||||||
|
Here are some properties you may want to change/update: |
||||||
|
|
||||||
|
source.dir |
||||||
|
The name of the source directory. Default is 'src'. |
||||||
|
out.dir |
||||||
|
The name of the output directory. Default is 'bin'. |
||||||
|
|
||||||
|
For other overridable properties, look at the beginning of the rules |
||||||
|
files in the SDK, at tools/ant/build.xml |
||||||
|
|
||||||
|
Properties related to the SDK location or the project target should |
||||||
|
be updated using the 'android' tool with the 'update' action. |
||||||
|
|
||||||
|
This file is an integral part of the build system for your |
||||||
|
application and should be checked into Version Control Systems. |
||||||
|
|
||||||
|
--> |
||||||
|
<property file="ant.properties" /> |
||||||
|
|
||||||
|
<!-- if sdk.dir was not set from one of the property file, then |
||||||
|
get it from the ANDROID_HOME env var. |
||||||
|
This must be done before we load project.properties since |
||||||
|
the proguard config can use sdk.dir --> |
||||||
|
<property environment="env" /> |
||||||
|
<condition property="sdk.dir" value="${env.ANDROID_HOME}"> |
||||||
|
<isset property="env.ANDROID_HOME" /> |
||||||
|
</condition> |
||||||
|
|
||||||
|
<!-- The project.properties file is created and updated by the 'android' |
||||||
|
tool, as well as ADT. |
||||||
|
|
||||||
|
This contains project specific properties such as project target, and library |
||||||
|
dependencies. Lower level build properties are stored in ant.properties |
||||||
|
(or in .classpath for Eclipse projects). |
||||||
|
|
||||||
|
This file is an integral part of the build system for your |
||||||
|
application and should be checked into Version Control Systems. --> |
||||||
|
<loadproperties srcFile="project.properties" /> |
||||||
|
|
||||||
|
<!-- quick check on sdk.dir --> |
||||||
|
<fail |
||||||
|
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." |
||||||
|
unless="sdk.dir" |
||||||
|
/> |
||||||
|
|
||||||
|
<!-- |
||||||
|
Import per project custom build rules if present at the root of the project. |
||||||
|
This is the place to put custom intermediary targets such as: |
||||||
|
-pre-build |
||||||
|
-pre-compile |
||||||
|
-post-compile (This is typically used for code obfuscation. |
||||||
|
Compiled code location: ${out.classes.absolute.dir} |
||||||
|
If this is not done in place, override ${out.dex.input.absolute.dir}) |
||||||
|
-post-package |
||||||
|
-post-build |
||||||
|
-pre-clean |
||||||
|
--> |
||||||
|
<import file="custom_rules.xml" optional="true" /> |
||||||
|
|
||||||
|
<!-- Import the actual build file. |
||||||
|
|
||||||
|
To customize existing targets, there are two options: |
||||||
|
- Customize only one target: |
||||||
|
- copy/paste the target into this file, *before* the |
||||||
|
<import> task. |
||||||
|
- customize it to your needs. |
||||||
|
- Customize the whole content of build.xml |
||||||
|
- copy/paste the content of the rules files (minus the top node) |
||||||
|
into this file, replacing the <import> task. |
||||||
|
- customize to your needs. |
||||||
|
|
||||||
|
*********************** |
||||||
|
****** IMPORTANT ****** |
||||||
|
*********************** |
||||||
|
In all cases you must update the value of version-tag below to read 'custom' instead of an integer, |
||||||
|
in order to avoid having your file be overridden by tools such as "android update project" |
||||||
|
--> |
||||||
|
<!-- version-tag: 1 --> |
||||||
|
<import file="${sdk.dir}/tools/ant/build.xml" /> |
||||||
|
|
||||||
|
</project> |
@ -0,0 +1,3 @@ |
|||||||
|
POM_NAME=ActionBar-PullToRefresh Library |
||||||
|
POM_ARTIFACT_ID=library |
||||||
|
POM_PACKAGING=aar |
@ -0,0 +1,20 @@ |
|||||||
|
# To enable ProGuard in your project, edit project.properties |
||||||
|
# to define the proguard.config property as described in that file. |
||||||
|
# |
||||||
|
# Add project specific ProGuard rules here. |
||||||
|
# By default, the flags in this file are appended to flags specified |
||||||
|
# in ${sdk.dir}/tools/proguard/proguard-android.txt |
||||||
|
# You can edit the include path and order by changing the ProGuard |
||||||
|
# include property in project.properties. |
||||||
|
# |
||||||
|
# For more details, see |
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html |
||||||
|
|
||||||
|
# Add any project specific keep options here: |
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following |
||||||
|
# and specify the fully qualified class name to the JavaScript interface |
||||||
|
# class: |
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
||||||
|
# public *; |
||||||
|
#} |
@ -0,0 +1,15 @@ |
|||||||
|
# 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 |
||||||
|
|
||||||
|
# Project target. |
||||||
|
target=android-18 |
||||||
|
android.library=true |
After Width: | Height: | Size: 257 B |
After Width: | Height: | Size: 603 B |
After Width: | Height: | Size: 725 B |
After Width: | Height: | Size: 716 B |
After Width: | Height: | Size: 761 B |
After Width: | Height: | Size: 675 B |
After Width: | Height: | Size: 761 B |
After Width: | Height: | Size: 647 B |
After Width: | Height: | Size: 692 B |
After Width: | Height: | Size: 272 B |
After Width: | Height: | Size: 602 B |
After Width: | Height: | Size: 716 B |
After Width: | Height: | Size: 778 B |
After Width: | Height: | Size: 771 B |
After Width: | Height: | Size: 722 B |
After Width: | Height: | Size: 824 B |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 741 B |
@ -0,0 +1,27 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> |
||||||
|
|
||||||
|
<item android:id="@android:id/progress"> |
||||||
|
<scale |
||||||
|
android:scaleWidth="100%" |
||||||
|
android:scaleGravity="center" |
||||||
|
android:drawable="@drawable/ptr_progress_primary_holo" /> |
||||||
|
</item> |
||||||
|
|
||||||
|
</layer-list> |
@ -0,0 +1,45 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
/* |
||||||
|
** Copyright 2011, The Android Open Source Project |
||||||
|
** |
||||||
|
** 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. |
||||||
|
*/ |
||||||
|
--> |
||||||
|
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:oneshot="false"> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo1" |
||||||
|
android:duration="50" /> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo2" |
||||||
|
android:duration="50" /> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo3" |
||||||
|
android:duration="50" /> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo4" |
||||||
|
android:duration="50" /> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo5" |
||||||
|
android:duration="50" /> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo6" |
||||||
|
android:duration="50" /> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo7" |
||||||
|
android:duration="50" /> |
||||||
|
<item |
||||||
|
android:drawable="@drawable/ptr_progressbar_indeterminate_holo8" |
||||||
|
android:duration="50" /> |
||||||
|
</animation-list> |
@ -0,0 +1,45 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:orientation="vertical" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="wrap_content"> |
||||||
|
|
||||||
|
<FrameLayout |
||||||
|
android:id="@id/ptr_content" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="48dp" |
||||||
|
android:background="?android:attr/colorBackground"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@id/ptr_text" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium" |
||||||
|
android:gravity="center" /> |
||||||
|
|
||||||
|
</FrameLayout> |
||||||
|
|
||||||
|
<ProgressBar |
||||||
|
android:id="@id/ptr_progress" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_width="match_parent" |
||||||
|
style="@style/Widget.PullToRefresh.ProgressBar.Horizontal.Center" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">Načítání…</string> |
||||||
|
</resources> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">Laden…</string> |
||||||
|
</resources> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<string name="pull_to_refresh_pull_label">Desliza el dedo hacia abajo para actualizar.</string> |
||||||
|
<string name="pull_to_refresh_release_label">Soltar para actualizar…</string> |
||||||
|
<string name="pull_to_refresh_refreshing_label">Cargando…</string> |
||||||
|
</resources> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<string name="pull_to_refresh_pull_label">Päivitä vetämällä alas…</string> |
||||||
|
<string name="pull_to_refresh_release_label">Päivitä vapauttamalla…</string> |
||||||
|
<string name="pull_to_refresh_refreshing_label">Päivitetään…</string> |
||||||
|
</resources> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">Chargement…</string> |
||||||
|
</resources> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">Caricamento…</string> |
||||||
|
</resources> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">Laden…</string> |
||||||
|
</resources> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">Wczytywanie…</string> |
||||||
|
</resources> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">Carregando…</string> |
||||||
|
</resources> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
<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_refreshing_label">A carregar…</string> |
||||||
|
</resources> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,21 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,23 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
|
||||||
|
<string name="pull_to_refresh_pull_label">Dra nedåt om du vill uppdatera</string> |
||||||
|
<string name="pull_to_refresh_release_label">Släpp om du vill uppdatera</string> |
||||||
|
<string name="pull_to_refresh_refreshing_label">Uppdaterar…</string> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<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> |
@ -0,0 +1,48 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
|
||||||
|
<!-- The attribute to set in your Application/Activity theme to reference your custom theme --> |
||||||
|
<attr name="ptrHeaderStyle" format="reference" /> |
||||||
|
|
||||||
|
<declare-styleable name="PullToRefreshHeader"> |
||||||
|
|
||||||
|
<!-- A drawable to use as the background of the Header View --> |
||||||
|
<attr name="ptrHeaderBackground" format="reference|color" /> |
||||||
|
|
||||||
|
<!-- The height of the Header View --> |
||||||
|
<attr name="ptrHeaderHeight" format="reference|dimension" /> |
||||||
|
|
||||||
|
<!-- The Text Appearance of the Header View's Title text --> |
||||||
|
<attr name="ptrHeaderTitleTextAppearance" format="reference" /> |
||||||
|
|
||||||
|
<!-- The color that the Progress Bar should be tinted with --> |
||||||
|
<attr name="ptrProgressBarColor" format="reference|color" /> |
||||||
|
|
||||||
|
<!-- Text to show to prompt the user is pull (or keep pulling) --> |
||||||
|
<attr name="ptrPullText" format="reference|string" /> |
||||||
|
|
||||||
|
<!-- Text to show to tell the user that a refresh is currently in progress --> |
||||||
|
<attr name="ptrRefreshingText" format="reference|string" /> |
||||||
|
|
||||||
|
<!-- Text to show to tell the user has scrolled enough to refresh --> |
||||||
|
<attr name="ptrReleaseText" format="reference|string" /> |
||||||
|
|
||||||
|
</declare-styleable> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,24 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
|
||||||
|
<item type="id" name="ptr_content" /> |
||||||
|
<item type="id" name="ptr_text" /> |
||||||
|
<item type="id" name="ptr_progress" /> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,23 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
|
||||||
|
<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_refreshing_label">Loading…</string> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,29 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
~ Copyright 2013 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. |
||||||
|
--> |
||||||
|
|
||||||
|
<resources> |
||||||
|
|
||||||
|
<style name="Widget.PullToRefresh.ProgressBar.Horizontal.Center" |
||||||
|
parent="android:Widget.ProgressBar.Horizontal"> |
||||||
|
<item name="android:progressDrawable">@drawable/ptr_progress_horizontal_holo_center</item> |
||||||
|
<item name="android:indeterminateDrawable"> |
||||||
|
@drawable/ptr_progress_indeterminate_horizontal_holo |
||||||
|
</item> |
||||||
|
<item name="android:minHeight">4dip</item> |
||||||
|
<item name="android:maxHeight">4dip</item> |
||||||
|
</style> |
||||||
|
|
||||||
|
</resources> |
@ -0,0 +1,397 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library; |
||||||
|
|
||||||
|
import android.animation.Animator; |
||||||
|
import android.animation.AnimatorListenerAdapter; |
||||||
|
import android.animation.AnimatorSet; |
||||||
|
import android.animation.ObjectAnimator; |
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.content.res.TypedArray; |
||||||
|
import android.graphics.PixelFormat; |
||||||
|
import android.graphics.PorterDuff; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
import android.os.Build; |
||||||
|
import android.util.TypedValue; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.view.animation.AccelerateInterpolator; |
||||||
|
import android.view.animation.Interpolator; |
||||||
|
import android.widget.ProgressBar; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.platform.SDK11; |
||||||
|
|
||||||
|
/** |
||||||
|
* Default Header Transformer. |
||||||
|
*/ |
||||||
|
public class DefaultHeaderTransformer extends PullToRefreshAttacher.HeaderTransformer { |
||||||
|
|
||||||
|
private View mHeaderView; |
||||||
|
private ViewGroup mContentLayout; |
||||||
|
private TextView mHeaderTextView; |
||||||
|
private ProgressBar mHeaderProgressBar; |
||||||
|
|
||||||
|
private CharSequence mPullRefreshLabel, mRefreshingLabel, mReleaseLabel; |
||||||
|
|
||||||
|
private boolean mUseCustomProgressColor = false; |
||||||
|
private int mProgressDrawableColor; |
||||||
|
private long mAnimationDuration; |
||||||
|
|
||||||
|
private final Interpolator mInterpolator = new AccelerateInterpolator(); |
||||||
|
|
||||||
|
protected DefaultHeaderTransformer() { |
||||||
|
final int min = getMinimumApiLevel(); |
||||||
|
if (Build.VERSION.SDK_INT < min) { |
||||||
|
throw new IllegalStateException("This HeaderTransformer is designed to run on SDK " |
||||||
|
+ min |
||||||
|
+ "+. If using ActionBarSherlock or ActionBarCompat you should use the appropriate provided extra."); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onViewCreated(Activity activity, View headerView) { |
||||||
|
mHeaderView = headerView; |
||||||
|
|
||||||
|
// Get ProgressBar and TextView
|
||||||
|
mHeaderProgressBar = (ProgressBar) headerView.findViewById(R.id.ptr_progress); |
||||||
|
mHeaderTextView = (TextView) headerView.findViewById(R.id.ptr_text); |
||||||
|
mContentLayout = (ViewGroup) headerView.findViewById(R.id.ptr_content); |
||||||
|
|
||||||
|
// Default Labels to display
|
||||||
|
mPullRefreshLabel = activity.getString(R.string.pull_to_refresh_pull_label); |
||||||
|
mRefreshingLabel = activity.getString(R.string.pull_to_refresh_refreshing_label); |
||||||
|
mReleaseLabel = activity.getString(R.string.pull_to_refresh_release_label); |
||||||
|
|
||||||
|
mAnimationDuration = activity.getResources() |
||||||
|
.getInteger(android.R.integer.config_shortAnimTime); |
||||||
|
|
||||||
|
// Setup the View styles
|
||||||
|
setupViewsFromStyles(activity, headerView); |
||||||
|
|
||||||
|
// Apply any custom ProgressBar colors
|
||||||
|
applyProgressBarColor(); |
||||||
|
|
||||||
|
// FIXME: I do not like this call here
|
||||||
|
onReset(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onConfigurationChanged(Activity activity, Configuration newConfig) { |
||||||
|
setupViewsFromStyles(activity, getHeaderView()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onReset() { |
||||||
|
// Reset Progress Bar
|
||||||
|
if (mHeaderProgressBar != null) { |
||||||
|
mHeaderProgressBar.setVisibility(View.GONE); |
||||||
|
mHeaderProgressBar.setProgress(0); |
||||||
|
mHeaderProgressBar.setIndeterminate(false); |
||||||
|
} |
||||||
|
|
||||||
|
// Reset Text View
|
||||||
|
if (mHeaderTextView != null) { |
||||||
|
mHeaderTextView.setVisibility(View.VISIBLE); |
||||||
|
mHeaderTextView.setText(mPullRefreshLabel); |
||||||
|
} |
||||||
|
|
||||||
|
// Reset the Content Layout
|
||||||
|
if (mContentLayout != null) { |
||||||
|
mContentLayout.setVisibility(View.VISIBLE); |
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { |
||||||
|
SDK11.setAlpha(mContentLayout, 1f); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onPulled(float percentagePulled) { |
||||||
|
if (mHeaderProgressBar != null) { |
||||||
|
mHeaderProgressBar.setVisibility(View.VISIBLE); |
||||||
|
final float progress = mInterpolator.getInterpolation(percentagePulled); |
||||||
|
mHeaderProgressBar.setProgress(Math.round(mHeaderProgressBar.getMax() * progress)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onRefreshStarted() { |
||||||
|
if (mHeaderTextView != null) { |
||||||
|
mHeaderTextView.setText(mRefreshingLabel); |
||||||
|
} |
||||||
|
if (mHeaderProgressBar != null) { |
||||||
|
mHeaderProgressBar.setVisibility(View.VISIBLE); |
||||||
|
mHeaderProgressBar.setIndeterminate(true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onReleaseToRefresh() { |
||||||
|
if (mHeaderTextView != null) { |
||||||
|
mHeaderTextView.setText(mReleaseLabel); |
||||||
|
} |
||||||
|
if (mHeaderProgressBar != null) { |
||||||
|
mHeaderProgressBar.setProgress(mHeaderProgressBar.getMax()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onRefreshMinimized() { |
||||||
|
// Here we fade out most of the header, leaving just the progress bar
|
||||||
|
if (mContentLayout != null) { |
||||||
|
ObjectAnimator.ofFloat(mContentLayout, "alpha", 1f, 0f).start(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public View getHeaderView() { |
||||||
|
return mHeaderView; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean showHeaderView() { |
||||||
|
final boolean changeVis = mHeaderView.getVisibility() != View.VISIBLE; |
||||||
|
|
||||||
|
if (changeVis) { |
||||||
|
mHeaderView.setVisibility(View.VISIBLE); |
||||||
|
AnimatorSet animSet = new AnimatorSet(); |
||||||
|
ObjectAnimator transAnim = ObjectAnimator.ofFloat(mContentLayout, "translationY", |
||||||
|
-mContentLayout.getHeight(), 0f); |
||||||
|
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(mHeaderView, "alpha", 0f, 1f); |
||||||
|
animSet.playTogether(transAnim, alphaAnim); |
||||||
|
animSet.setDuration(mAnimationDuration); |
||||||
|
animSet.start(); |
||||||
|
} |
||||||
|
|
||||||
|
return changeVis; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean hideHeaderView() { |
||||||
|
final boolean changeVis = mHeaderView.getVisibility() != View.GONE; |
||||||
|
|
||||||
|
if (changeVis) { |
||||||
|
Animator animator; |
||||||
|
if (mContentLayout.getAlpha() >= 0.5f) { |
||||||
|
// If the content layout is showing, translate and fade out
|
||||||
|
animator = new AnimatorSet(); |
||||||
|
ObjectAnimator transAnim = ObjectAnimator.ofFloat(mContentLayout, "translationY", |
||||||
|
0f, -mContentLayout.getHeight()); |
||||||
|
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(mHeaderView, "alpha", 1f, 0f); |
||||||
|
((AnimatorSet) animator).playTogether(transAnim, alphaAnim); |
||||||
|
} else { |
||||||
|
// If the content layout isn't showing (minimized), just fade out
|
||||||
|
animator = ObjectAnimator.ofFloat(mHeaderView, "alpha", 1f, 0f); |
||||||
|
} |
||||||
|
animator.setDuration(mAnimationDuration); |
||||||
|
animator.addListener(new HideAnimationCallback()); |
||||||
|
animator.start(); |
||||||
|
} |
||||||
|
|
||||||
|
return changeVis; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set color to apply to the progress bar. Automatically enables usage of the custom color. Use |
||||||
|
* {@link #setProgressBarColorEnabled(boolean)} to disable and re-enable the custom color usage. |
||||||
|
* <p/> |
||||||
|
* The best way to apply a color is to load the color from resources: {@code |
||||||
|
* setProgressBarColor(getResources().getColor(R.color.your_color_name))}. |
||||||
|
* |
||||||
|
* @param color The color to use. |
||||||
|
*/ |
||||||
|
public void setProgressBarColor(int color) { |
||||||
|
mProgressDrawableColor = color; |
||||||
|
setProgressBarColorEnabled(true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Enable or disable the use of a custom progress bar color. You can set what color to use with |
||||||
|
* {@link #setProgressBarColor(int)}, which also automatically enables custom color usage. |
||||||
|
*/ |
||||||
|
public void setProgressBarColorEnabled(boolean enabled) { |
||||||
|
mUseCustomProgressColor = enabled; |
||||||
|
applyProgressBarColor(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Set Text to show to prompt the user is pull (or keep pulling). |
||||||
|
* |
||||||
|
* @param pullText - Text to display. |
||||||
|
*/ |
||||||
|
public void setPullText(CharSequence pullText) { |
||||||
|
mPullRefreshLabel = pullText; |
||||||
|
if (mHeaderTextView != null) { |
||||||
|
mHeaderTextView.setText(mPullRefreshLabel); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set Text to show to tell the user that a refresh is currently in progress. |
||||||
|
* |
||||||
|
* @param refreshingText - Text to display. |
||||||
|
*/ |
||||||
|
public void setRefreshingText(CharSequence refreshingText) { |
||||||
|
mRefreshingLabel = refreshingText; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set Text to show to tell the user has scrolled enough to refresh. |
||||||
|
* |
||||||
|
* @param releaseText - Text to display. |
||||||
|
*/ |
||||||
|
public void setReleaseText(CharSequence releaseText) { |
||||||
|
mReleaseLabel = releaseText; |
||||||
|
} |
||||||
|
|
||||||
|
private void setupViewsFromStyles(Activity activity, View headerView) { |
||||||
|
final TypedArray styleAttrs = obtainStyledAttrsFromThemeAttr(activity, |
||||||
|
R.attr.ptrHeaderStyle, R.styleable.PullToRefreshHeader); |
||||||
|
|
||||||
|
// Retrieve the Action Bar size from the app theme or the Action Bar's style
|
||||||
|
if (mContentLayout != null) { |
||||||
|
final int height = styleAttrs |
||||||
|
.getDimensionPixelSize(R.styleable.PullToRefreshHeader_ptrHeaderHeight, |
||||||
|
getActionBarSize(activity)); |
||||||
|
mContentLayout.getLayoutParams().height = height; |
||||||
|
mContentLayout.requestLayout(); |
||||||
|
} |
||||||
|
|
||||||
|
// Retrieve the Action Bar background from the app theme or the Action Bar's style (see #93)
|
||||||
|
Drawable bg = styleAttrs.hasValue(R.styleable.PullToRefreshHeader_ptrHeaderBackground) |
||||||
|
? styleAttrs.getDrawable(R.styleable.PullToRefreshHeader_ptrHeaderBackground) |
||||||
|
: getActionBarBackground(activity); |
||||||
|
if (bg != null) { |
||||||
|
mHeaderTextView.setBackgroundDrawable(bg); |
||||||
|
|
||||||
|
// If we have an opaque background we can remove the background from the content layout
|
||||||
|
if (mContentLayout != null && bg.getOpacity() == PixelFormat.OPAQUE) { |
||||||
|
mContentLayout.setBackgroundResource(0); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Retrieve the Action Bar Title Style from the app theme or the Action Bar's style
|
||||||
|
Context abContext = headerView.getContext(); |
||||||
|
final int titleTextStyle = styleAttrs |
||||||
|
.getResourceId(R.styleable.PullToRefreshHeader_ptrHeaderTitleTextAppearance, |
||||||
|
getActionBarTitleStyle(abContext)); |
||||||
|
if (titleTextStyle != 0) { |
||||||
|
mHeaderTextView.setTextAppearance(abContext, titleTextStyle); |
||||||
|
} |
||||||
|
|
||||||
|
// Retrieve the Progress Bar Color the style
|
||||||
|
if (styleAttrs.hasValue(R.styleable.PullToRefreshHeader_ptrProgressBarColor)) { |
||||||
|
mUseCustomProgressColor = true; |
||||||
|
mProgressDrawableColor = styleAttrs |
||||||
|
.getColor(R.styleable.PullToRefreshHeader_ptrProgressBarColor, 0); |
||||||
|
} |
||||||
|
|
||||||
|
// Retrieve the text strings from the style (if they're set)
|
||||||
|
if (styleAttrs.hasValue(R.styleable.PullToRefreshHeader_ptrPullText)) { |
||||||
|
mPullRefreshLabel = styleAttrs.getString(R.styleable.PullToRefreshHeader_ptrPullText); |
||||||
|
} |
||||||
|
if (styleAttrs.hasValue(R.styleable.PullToRefreshHeader_ptrRefreshingText)) { |
||||||
|
mRefreshingLabel = styleAttrs |
||||||
|
.getString(R.styleable.PullToRefreshHeader_ptrRefreshingText); |
||||||
|
} |
||||||
|
if (styleAttrs.hasValue(R.styleable.PullToRefreshHeader_ptrReleaseText)) { |
||||||
|
mReleaseLabel = styleAttrs.getString(R.styleable.PullToRefreshHeader_ptrReleaseText); |
||||||
|
} |
||||||
|
|
||||||
|
styleAttrs.recycle(); |
||||||
|
} |
||||||
|
|
||||||
|
private void applyProgressBarColor() { |
||||||
|
if (mHeaderProgressBar != null) { |
||||||
|
if (mUseCustomProgressColor) { |
||||||
|
mHeaderProgressBar.getProgressDrawable() |
||||||
|
.setColorFilter(mProgressDrawableColor, PorterDuff.Mode.SRC_ATOP); |
||||||
|
mHeaderProgressBar.getIndeterminateDrawable() |
||||||
|
.setColorFilter(mProgressDrawableColor, PorterDuff.Mode.SRC_ATOP); |
||||||
|
} else { |
||||||
|
mHeaderProgressBar.getProgressDrawable().clearColorFilter(); |
||||||
|
mHeaderProgressBar.getIndeterminateDrawable().clearColorFilter(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected Drawable getActionBarBackground(Context context) { |
||||||
|
int[] android_styleable_ActionBar = {android.R.attr.background}; |
||||||
|
|
||||||
|
// Now get the action bar style values...
|
||||||
|
TypedArray abStyle = obtainStyledAttrsFromThemeAttr(context, android.R.attr.actionBarStyle, |
||||||
|
android_styleable_ActionBar); |
||||||
|
try { |
||||||
|
// background is the first attr in the array above so it's index is 0.
|
||||||
|
return abStyle.getDrawable(0); |
||||||
|
} finally { |
||||||
|
abStyle.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected int getActionBarSize(Context context) { |
||||||
|
int[] attrs = {android.R.attr.actionBarSize}; |
||||||
|
TypedArray values = context.getTheme().obtainStyledAttributes(attrs); |
||||||
|
try { |
||||||
|
return values.getDimensionPixelSize(0, 0); |
||||||
|
} finally { |
||||||
|
values.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected int getActionBarTitleStyle(Context context) { |
||||||
|
int[] android_styleable_ActionBar = {android.R.attr.titleTextStyle}; |
||||||
|
|
||||||
|
// Now get the action bar style values...
|
||||||
|
TypedArray abStyle = obtainStyledAttrsFromThemeAttr(context, android.R.attr.actionBarStyle, |
||||||
|
android_styleable_ActionBar); |
||||||
|
try { |
||||||
|
// titleTextStyle is the first attr in the array above so it's index is 0.
|
||||||
|
return abStyle.getResourceId(0, 0); |
||||||
|
} finally { |
||||||
|
abStyle.recycle(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected int getMinimumApiLevel() { |
||||||
|
return Build.VERSION_CODES.ICE_CREAM_SANDWICH; |
||||||
|
} |
||||||
|
|
||||||
|
class HideAnimationCallback extends AnimatorListenerAdapter { |
||||||
|
@Override |
||||||
|
public void onAnimationEnd(Animator animation) { |
||||||
|
View headerView = getHeaderView(); |
||||||
|
if (headerView != null) { |
||||||
|
headerView.setVisibility(View.GONE); |
||||||
|
} |
||||||
|
onReset(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected static TypedArray obtainStyledAttrsFromThemeAttr(Context context, int themeAttr, |
||||||
|
int[] styleAttrs) { |
||||||
|
// Need to get resource id of style pointed to from the theme attr
|
||||||
|
TypedValue outValue = new TypedValue(); |
||||||
|
context.getTheme().resolveAttribute(themeAttr, outValue, true); |
||||||
|
final int styleResId = outValue.resourceId; |
||||||
|
|
||||||
|
// Now return the values (from styleAttrs) from the style
|
||||||
|
return context.obtainStyledAttributes(styleResId, styleAttrs); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,91 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import java.lang.reflect.Constructor; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
|
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.AbsListViewDelegate; |
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.ScrollYDelegate; |
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.viewdelegates.WebViewDelegate; |
||||||
|
|
||||||
|
class InstanceCreationUtils { |
||||||
|
|
||||||
|
private static final String LOG_TAG = "InstanceCreationUtils"; |
||||||
|
|
||||||
|
private static final Class<?>[] VIEW_DELEGATE_CONSTRUCTOR_SIGNATURE = new Class[]{}; |
||||||
|
private static final Class<?>[] TRANSFORMER_CONSTRUCTOR_SIGNATURE = new Class[]{}; |
||||||
|
|
||||||
|
private static final HashMap<Class, Class> BUILT_IN_DELEGATES; |
||||||
|
static { |
||||||
|
BUILT_IN_DELEGATES = new HashMap<Class, Class>(); |
||||||
|
BUILT_IN_DELEGATES.put(AbsListViewDelegate.SUPPORTED_VIEW_CLASS, AbsListViewDelegate.class); |
||||||
|
BUILT_IN_DELEGATES.put(WebViewDelegate.SUPPORTED_VIEW_CLASS, WebViewDelegate.class); |
||||||
|
} |
||||||
|
|
||||||
|
static PullToRefreshAttacher.ViewDelegate getBuiltInViewDelegate(final View view) { |
||||||
|
final Set<Map.Entry<Class, Class>> entries = BUILT_IN_DELEGATES.entrySet(); |
||||||
|
for (final Map.Entry<Class, Class> entry : entries) { |
||||||
|
if (entry.getKey().isInstance(view)) { |
||||||
|
return InstanceCreationUtils.newInstance(view.getContext(), |
||||||
|
entry.getValue(), VIEW_DELEGATE_CONSTRUCTOR_SIGNATURE, null); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Default is the ScrollYDelegate
|
||||||
|
return InstanceCreationUtils.newInstance(view.getContext(), |
||||||
|
ScrollYDelegate.class, VIEW_DELEGATE_CONSTRUCTOR_SIGNATURE, null); |
||||||
|
} |
||||||
|
|
||||||
|
static <T> T instantiateViewDelegate(Context context, String className, Object[] arguments) { |
||||||
|
try { |
||||||
|
Class<?> clazz = context.getClassLoader().loadClass(className); |
||||||
|
return newInstance(context, clazz, VIEW_DELEGATE_CONSTRUCTOR_SIGNATURE, arguments); |
||||||
|
} catch (Exception e) { |
||||||
|
Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
static <T> T instantiateTransformer(Context context, String className, Object[] arguments) { |
||||||
|
try { |
||||||
|
Class<?> clazz = context.getClassLoader().loadClass(className); |
||||||
|
return newInstance(context, clazz, TRANSFORMER_CONSTRUCTOR_SIGNATURE, arguments); |
||||||
|
} catch (Exception e) { |
||||||
|
Log.w(LOG_TAG, "Cannot instantiate class: " + className, e); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
private static <T> T newInstance(Context context, Class clazz, Class[] constructorSig, |
||||||
|
Object[] arguments) { |
||||||
|
try { |
||||||
|
Constructor<?> constructor = clazz.getConstructor(constructorSig); |
||||||
|
return (T) constructor.newInstance(arguments); |
||||||
|
} catch (Exception e) { |
||||||
|
Log.w(LOG_TAG, "Cannot instantiate class: " + clazz.getName(), e); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,948 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library; |
||||||
|
|
||||||
|
import android.app.Activity; |
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.graphics.Rect; |
||||||
|
import android.os.Build; |
||||||
|
import android.os.Handler; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewConfiguration; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
|
||||||
|
import java.util.Set; |
||||||
|
import java.util.WeakHashMap; |
||||||
|
|
||||||
|
/** |
||||||
|
* FIXME |
||||||
|
*/ |
||||||
|
public class PullToRefreshAttacher implements View.OnTouchListener { |
||||||
|
|
||||||
|
/* Default configuration values */ |
||||||
|
private static final int DEFAULT_HEADER_LAYOUT = R.layout.default_header; |
||||||
|
private static final float DEFAULT_REFRESH_SCROLL_DISTANCE = 0.5f; |
||||||
|
private static final boolean DEFAULT_REFRESH_ON_UP = false; |
||||||
|
private static final int DEFAULT_REFRESH_MINIMIZED_DELAY = 1 * 1000; |
||||||
|
private static final boolean DEFAULT_REFRESH_MINIMIZE = true; |
||||||
|
|
||||||
|
private static final boolean DEBUG = false; |
||||||
|
private static final String LOG_TAG = "PullToRefreshAttacher"; |
||||||
|
|
||||||
|
/* Member Variables */ |
||||||
|
|
||||||
|
private final EnvironmentDelegate mEnvironmentDelegate; |
||||||
|
private final HeaderTransformer mHeaderTransformer; |
||||||
|
|
||||||
|
private final Activity mActivity; |
||||||
|
private final View mHeaderView; |
||||||
|
private HeaderViewListener mHeaderViewListener; |
||||||
|
|
||||||
|
private final int mTouchSlop; |
||||||
|
private final float mRefreshScrollDistance; |
||||||
|
|
||||||
|
private int mInitialMotionY, mLastMotionY, mPullBeginY; |
||||||
|
private boolean mIsBeingDragged, mIsRefreshing, mHandlingTouchEventFromDown; |
||||||
|
|
||||||
|
private final WeakHashMap<View, ViewParams> mRefreshableViews; |
||||||
|
|
||||||
|
private boolean mEnabled = true; |
||||||
|
private final boolean mRefreshOnUp; |
||||||
|
private final int mRefreshMinimizeDelay; |
||||||
|
private final boolean mRefreshMinimize; |
||||||
|
|
||||||
|
private final Handler mHandler = new Handler(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Get a PullToRefreshAttacher for this Activity. If there is already a |
||||||
|
* PullToRefreshAttacher attached to the Activity, the existing one is |
||||||
|
* returned, otherwise a new instance is created. This version of the method |
||||||
|
* will use default configuration options for everything. |
||||||
|
* |
||||||
|
* @param activity |
||||||
|
* Activity to attach to. |
||||||
|
* @return PullToRefresh attached to the Activity. |
||||||
|
*/ |
||||||
|
public static PullToRefreshAttacher get(Activity activity) { |
||||||
|
return get(activity, new Options()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Get a PullToRefreshAttacher for this Activity. If there is already a |
||||||
|
* PullToRefreshAttacher attached to the Activity, the existing one is |
||||||
|
* returned, otherwise a new instance is created. |
||||||
|
* |
||||||
|
* @param activity |
||||||
|
* Activity to attach to. |
||||||
|
* @param options |
||||||
|
* Options used when creating the PullToRefreshAttacher. |
||||||
|
* @return PullToRefresh attached to the Activity. |
||||||
|
*/ |
||||||
|
public static PullToRefreshAttacher get(Activity activity, Options options) { |
||||||
|
return new PullToRefreshAttacher(activity, options); |
||||||
|
} |
||||||
|
|
||||||
|
protected PullToRefreshAttacher(Activity activity, Options options) { |
||||||
|
if (options == null) { |
||||||
|
Log.i(LOG_TAG, "Given null options so using default options."); |
||||||
|
options = new Options(); |
||||||
|
} |
||||||
|
|
||||||
|
mActivity = activity; |
||||||
|
mRefreshableViews = new WeakHashMap<View, ViewParams>(); |
||||||
|
|
||||||
|
// Copy necessary values from options
|
||||||
|
mRefreshScrollDistance = options.refreshScrollDistance; |
||||||
|
mRefreshOnUp = options.refreshOnUp; |
||||||
|
mRefreshMinimizeDelay = options.refreshMinimizeDelay; |
||||||
|
mRefreshMinimize = options.refreshMinimize; |
||||||
|
|
||||||
|
// EnvironmentDelegate
|
||||||
|
mEnvironmentDelegate = options.environmentDelegate != null ? options.environmentDelegate |
||||||
|
: createDefaultEnvironmentDelegate(); |
||||||
|
|
||||||
|
// Header Transformer
|
||||||
|
mHeaderTransformer = options.headerTransformer != null ? options.headerTransformer |
||||||
|
: createDefaultHeaderTransformer(); |
||||||
|
|
||||||
|
// Get touch slop for use later
|
||||||
|
mTouchSlop = ViewConfiguration.get(activity).getScaledTouchSlop(); |
||||||
|
|
||||||
|
// Get Window Decor View
|
||||||
|
final ViewGroup decorView = (ViewGroup) activity.getWindow() |
||||||
|
.getDecorView(); |
||||||
|
|
||||||
|
// Check to see if there is already a Attacher view installed
|
||||||
|
if (decorView.getChildCount() == 1 |
||||||
|
&& decorView.getChildAt(0) instanceof DecorChildLayout) { |
||||||
|
throw new IllegalStateException( |
||||||
|
"You should only create one PullToRefreshAttacher per Activity"); |
||||||
|
} |
||||||
|
|
||||||
|
// Create Header view and then add to Decor View
|
||||||
|
mHeaderView = LayoutInflater.from( |
||||||
|
mEnvironmentDelegate.getContextForInflater(activity)).inflate( |
||||||
|
options.headerLayout, decorView, false); |
||||||
|
if (mHeaderView == null) { |
||||||
|
throw new IllegalArgumentException( |
||||||
|
"Must supply valid layout id for header."); |
||||||
|
} |
||||||
|
// Make Header View invisible so it still gets a layout pass
|
||||||
|
mHeaderView.setVisibility(View.INVISIBLE); |
||||||
|
|
||||||
|
// Create DecorChildLayout which will move all of the system's decor
|
||||||
|
// view's children + the
|
||||||
|
// Header View to itself. See DecorChildLayout for more info.
|
||||||
|
DecorChildLayout decorContents = new DecorChildLayout(activity, |
||||||
|
decorView, mHeaderView); |
||||||
|
|
||||||
|
// Now add the DecorChildLayout to the decor view
|
||||||
|
decorView.addView(decorContents, ViewGroup.LayoutParams.MATCH_PARENT, |
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT); |
||||||
|
|
||||||
|
// Notify transformer
|
||||||
|
mHeaderTransformer.onViewCreated(activity, mHeaderView); |
||||||
|
// TODO Remove the follow deprecated method call before v1.0
|
||||||
|
mHeaderTransformer.onViewCreated(mHeaderView); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a view which will be used to initiate refresh requests and a listener |
||||||
|
* to be invoked when a refresh is started. This version of the method will |
||||||
|
* try to find a handler for the view from the built-in view delegates. |
||||||
|
* |
||||||
|
* @param view |
||||||
|
* View which will be used to initiate refresh requests. |
||||||
|
* @param refreshListener |
||||||
|
* Listener to be invoked when a refresh is started. |
||||||
|
*/ |
||||||
|
public void addRefreshableView(View view, OnRefreshListener refreshListener) { |
||||||
|
addRefreshableView(view, null, refreshListener); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a view which will be used to initiate refresh requests, along with a |
||||||
|
* delegate which knows how to handle the given view, and a listener to be |
||||||
|
* invoked when a refresh is started. |
||||||
|
* |
||||||
|
* @param view |
||||||
|
* View which will be used to initiate refresh requests. |
||||||
|
* @param viewDelegate |
||||||
|
* delegate which knows how to handle <code>view</code>. |
||||||
|
* @param refreshListener |
||||||
|
* Listener to be invoked when a refresh is started. |
||||||
|
*/ |
||||||
|
public void addRefreshableView(View view, ViewDelegate viewDelegate, |
||||||
|
OnRefreshListener refreshListener) { |
||||||
|
addRefreshableView(view, viewDelegate, refreshListener, true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Add a view which will be used to initiate refresh requests, along with a |
||||||
|
* delegate which knows how to handle the given view, and a listener to be |
||||||
|
* invoked when a refresh is started. |
||||||
|
* |
||||||
|
* @param view |
||||||
|
* View which will be used to initiate refresh requests. |
||||||
|
* @param viewDelegate |
||||||
|
* delegate which knows how to handle <code>view</code>. |
||||||
|
* @param refreshListener |
||||||
|
* Listener to be invoked when a refresh is started. |
||||||
|
* @param setTouchListener |
||||||
|
* Whether to set this as the |
||||||
|
* {@link android.view.View.OnTouchListener}. |
||||||
|
*/ |
||||||
|
void addRefreshableView(View view, ViewDelegate viewDelegate, |
||||||
|
OnRefreshListener refreshListener, final boolean setTouchListener) { |
||||||
|
// Check to see if view is null
|
||||||
|
if (view == null) { |
||||||
|
Log.i(LOG_TAG, "Refreshable View is null."); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (refreshListener == null) { |
||||||
|
throw new IllegalArgumentException( |
||||||
|
"OnRefreshListener not given. Please provide one."); |
||||||
|
} |
||||||
|
|
||||||
|
// ViewDelegate
|
||||||
|
if (viewDelegate == null) { |
||||||
|
viewDelegate = InstanceCreationUtils.getBuiltInViewDelegate(view); |
||||||
|
if (viewDelegate == null) { |
||||||
|
throw new IllegalArgumentException( |
||||||
|
"No view handler found. Please provide one."); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// View to detect refreshes for
|
||||||
|
mRefreshableViews.put(view, new ViewParams(viewDelegate, refreshListener)); |
||||||
|
if (setTouchListener) { |
||||||
|
view.setOnTouchListener(this); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Remove a view which was previously used to initiate refresh requests. |
||||||
|
* |
||||||
|
* @param view |
||||||
|
* - View which will be used to initiate refresh requests. |
||||||
|
*/ |
||||||
|
public void removeRefreshableView(View view) { |
||||||
|
if (mRefreshableViews.containsKey(view)) { |
||||||
|
mRefreshableViews.remove(view); |
||||||
|
view.setOnTouchListener(null); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Clear all views which were previously used to initiate refresh requests. |
||||||
|
*/ |
||||||
|
public void clearRefreshableViews() { |
||||||
|
Set<View> views = mRefreshableViews.keySet(); |
||||||
|
for (View view : views) { |
||||||
|
view.setOnTouchListener(null); |
||||||
|
} |
||||||
|
mRefreshableViews.clear(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This method should be called by your Activity's or Fragment's |
||||||
|
* onConfigurationChanged method. |
||||||
|
* |
||||||
|
* @param newConfig The new configuration |
||||||
|
*/ |
||||||
|
public void onConfigurationChanged(Configuration newConfig) { |
||||||
|
mHeaderTransformer.onConfigurationChanged(mActivity, newConfig); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Manually set this Attacher's refreshing state. The header will be |
||||||
|
* displayed or hidden as requested. |
||||||
|
* |
||||||
|
* @param refreshing |
||||||
|
* - Whether the attacher should be in a refreshing state, |
||||||
|
*/ |
||||||
|
public final void setRefreshing(boolean refreshing) { |
||||||
|
setRefreshingInt(null, refreshing, false); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return true if this Attacher is currently in a refreshing state. |
||||||
|
*/ |
||||||
|
public final boolean isRefreshing() { |
||||||
|
return mIsRefreshing; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return true if this PullToRefresh is currently enabled (defaults to |
||||||
|
* <code>true</code>) |
||||||
|
*/ |
||||||
|
public boolean isEnabled() { |
||||||
|
return mEnabled; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Allows the enable/disable of this PullToRefreshAttacher. If disabled when |
||||||
|
* refreshing then the UI is automatically reset. |
||||||
|
* |
||||||
|
* @param enabled |
||||||
|
* - Whether this PullToRefreshAttacher is enabled. |
||||||
|
*/ |
||||||
|
public void setEnabled(boolean enabled) { |
||||||
|
mEnabled = enabled; |
||||||
|
|
||||||
|
if (!enabled) { |
||||||
|
// If we're not enabled, reset any touch handling
|
||||||
|
resetTouch(); |
||||||
|
|
||||||
|
// If we're currently refreshing, reset the ptr UI
|
||||||
|
if (mIsRefreshing) { |
||||||
|
reset(false); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Call this when your refresh is complete and this view should reset itself |
||||||
|
* (header view will be hidden). |
||||||
|
* |
||||||
|
* This is the equivalent of calling <code>setRefreshing(false)</code>. |
||||||
|
*/ |
||||||
|
public final void setRefreshComplete() { |
||||||
|
setRefreshingInt(null, false, false); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set a {@link HeaderViewListener} which is called when the visibility |
||||||
|
* state of the Header View has changed. |
||||||
|
* |
||||||
|
* @param listener |
||||||
|
*/ |
||||||
|
public final void setHeaderViewListener(HeaderViewListener listener) { |
||||||
|
mHeaderViewListener = listener; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return The Header View which is displayed when the user is pulling, or |
||||||
|
* we are refreshing. |
||||||
|
*/ |
||||||
|
public final View getHeaderView() { |
||||||
|
return mHeaderView; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return The HeaderTransformer currently used by this Attacher. |
||||||
|
*/ |
||||||
|
public HeaderTransformer getHeaderTransformer() { |
||||||
|
return mHeaderTransformer; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public final boolean onTouch(final View view, final MotionEvent event) { |
||||||
|
// Just call onTouchEvent. It now handles the proper calling of onInterceptTouchEvent
|
||||||
|
onTouchEvent(view, event); |
||||||
|
// Always return false as we only want to observe events
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
final boolean onInterceptTouchEvent(View view, MotionEvent event) { |
||||||
|
if (DEBUG) { |
||||||
|
Log.d(LOG_TAG, "onInterceptTouchEvent: " + event.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
// If we're not enabled or currently refreshing don't handle any touch
|
||||||
|
// events
|
||||||
|
if (!isEnabled() || isRefreshing()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
final ViewParams params = mRefreshableViews.get(view); |
||||||
|
if (params == null) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
if (DEBUG) Log.d(LOG_TAG, "onInterceptTouchEvent. Got ViewParams. " + view.toString()); |
||||||
|
|
||||||
|
switch (event.getAction()) { |
||||||
|
case MotionEvent.ACTION_MOVE: { |
||||||
|
// We're not currently being dragged so check to see if the user has
|
||||||
|
// scrolled enough
|
||||||
|
if (!mIsBeingDragged && mInitialMotionY > 0) { |
||||||
|
final int y = (int) event.getY(); |
||||||
|
final int yDiff = y - mInitialMotionY; |
||||||
|
|
||||||
|
if (yDiff > mTouchSlop) { |
||||||
|
mIsBeingDragged = true; |
||||||
|
onPullStarted(y); |
||||||
|
} else if (yDiff < -mTouchSlop) { |
||||||
|
resetTouch(); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
case MotionEvent.ACTION_DOWN: { |
||||||
|
// If we're already refreshing, ignore
|
||||||
|
if (canRefresh(true, params.onRefreshListener) |
||||||
|
&& params.viewDelegate.isReadyForPull(view, event.getX(), event.getY())) { |
||||||
|
mInitialMotionY = (int) event.getY(); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
case MotionEvent.ACTION_CANCEL: |
||||||
|
case MotionEvent.ACTION_UP: { |
||||||
|
resetTouch(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (DEBUG) Log.d(LOG_TAG, "onInterceptTouchEvent. Returning " + mIsBeingDragged); |
||||||
|
|
||||||
|
return mIsBeingDragged; |
||||||
|
} |
||||||
|
|
||||||
|
final boolean onTouchEvent(View view, MotionEvent event) { |
||||||
|
if (DEBUG) { |
||||||
|
Log.d(LOG_TAG, "onTouchEvent: " + event.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
// If we're not enabled or currently refreshing don't handle any touch
|
||||||
|
// events
|
||||||
|
if (!isEnabled()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
final ViewParams params = mRefreshableViews.get(view); |
||||||
|
if (params == null) { |
||||||
|
Log.i(LOG_TAG, "View does not have ViewParams"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
// Record whether our handling is started from ACTION_DOWN
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN) { |
||||||
|
mHandlingTouchEventFromDown = true; |
||||||
|
} |
||||||
|
|
||||||
|
// If we're being called from ACTION_DOWN then we must call through to
|
||||||
|
// onInterceptTouchEvent until it sets mIsBeingDragged
|
||||||
|
if (mHandlingTouchEventFromDown && !mIsBeingDragged) { |
||||||
|
onInterceptTouchEvent(view, event); |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
switch (event.getAction()) { |
||||||
|
case MotionEvent.ACTION_MOVE: { |
||||||
|
// If we're already refreshing ignore it
|
||||||
|
if (isRefreshing()) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
final int y = (int) event.getY(); |
||||||
|
|
||||||
|
if (mIsBeingDragged && y != mLastMotionY) { |
||||||
|
final int yDx = y - mLastMotionY; |
||||||
|
|
||||||
|
/** |
||||||
|
* Check to see if the user is scrolling the right direction |
||||||
|
* (down). We allow a small scroll up which is the check against |
||||||
|
* negative touch slop. |
||||||
|
*/ |
||||||
|
if (yDx >= -mTouchSlop) { |
||||||
|
onPull(view, y); |
||||||
|
// Only record the y motion if the user has scrolled down.
|
||||||
|
if (yDx > 0) { |
||||||
|
mLastMotionY = y; |
||||||
|
} |
||||||
|
} else { |
||||||
|
onPullEnded(); |
||||||
|
resetTouch(); |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
case MotionEvent.ACTION_CANCEL: |
||||||
|
case MotionEvent.ACTION_UP: { |
||||||
|
checkScrollForRefresh(view); |
||||||
|
if (mIsBeingDragged) { |
||||||
|
onPullEnded(); |
||||||
|
} |
||||||
|
resetTouch(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
void resetTouch() { |
||||||
|
mIsBeingDragged = false; |
||||||
|
mHandlingTouchEventFromDown = false; |
||||||
|
mInitialMotionY = mLastMotionY = mPullBeginY = -1; |
||||||
|
} |
||||||
|
|
||||||
|
void onPullStarted(int y) { |
||||||
|
if (DEBUG) { |
||||||
|
Log.d(LOG_TAG, "onPullStarted"); |
||||||
|
} |
||||||
|
showHeaderView(); |
||||||
|
mPullBeginY = y; |
||||||
|
} |
||||||
|
|
||||||
|
void onPull(View view, int y) { |
||||||
|
if (DEBUG) { |
||||||
|
Log.d(LOG_TAG, "onPull"); |
||||||
|
} |
||||||
|
|
||||||
|
final float pxScrollForRefresh = getScrollNeededForRefresh(view); |
||||||
|
final int scrollLength = y - mPullBeginY; |
||||||
|
|
||||||
|
if (scrollLength < pxScrollForRefresh) { |
||||||
|
mHeaderTransformer.onPulled(scrollLength / pxScrollForRefresh); |
||||||
|
} else { |
||||||
|
if (mRefreshOnUp) { |
||||||
|
mHeaderTransformer.onReleaseToRefresh(); |
||||||
|
} else { |
||||||
|
setRefreshingInt(view, true, true); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void onPullEnded() { |
||||||
|
if (DEBUG) { |
||||||
|
Log.d(LOG_TAG, "onPullEnded"); |
||||||
|
} |
||||||
|
if (!mIsRefreshing) { |
||||||
|
reset(true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void showHeaderView() { |
||||||
|
if (mHeaderTransformer.showHeaderView()) { |
||||||
|
if (mHeaderViewListener != null) { |
||||||
|
mHeaderViewListener.onStateChanged(mHeaderView, |
||||||
|
HeaderViewListener.STATE_VISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void hideHeaderView() { |
||||||
|
if (mHeaderTransformer.hideHeaderView()) { |
||||||
|
if (mHeaderViewListener != null) { |
||||||
|
mHeaderViewListener.onStateChanged(mHeaderView, |
||||||
|
HeaderViewListener.STATE_HIDDEN); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected EnvironmentDelegate createDefaultEnvironmentDelegate() { |
||||||
|
return new EnvironmentDelegate(); |
||||||
|
} |
||||||
|
|
||||||
|
protected HeaderTransformer createDefaultHeaderTransformer() { |
||||||
|
return new DefaultHeaderTransformer(); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean checkScrollForRefresh(View view) { |
||||||
|
if (mIsBeingDragged && mRefreshOnUp && view != null) { |
||||||
|
if (mLastMotionY - mPullBeginY >= getScrollNeededForRefresh(view)) { |
||||||
|
setRefreshingInt(view, true, true); |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
private void setRefreshingInt(View view, boolean refreshing, boolean fromTouch) { |
||||||
|
if (DEBUG) { |
||||||
|
Log.d(LOG_TAG, "setRefreshingInt: " + refreshing); |
||||||
|
} |
||||||
|
// Check to see if we need to do anything
|
||||||
|
if (mIsRefreshing == refreshing) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
resetTouch(); |
||||||
|
|
||||||
|
if (refreshing && canRefresh(fromTouch, getRefreshListenerForView(view))) { |
||||||
|
startRefresh(view, fromTouch); |
||||||
|
} else { |
||||||
|
reset(fromTouch); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private OnRefreshListener getRefreshListenerForView(View view) { |
||||||
|
if (view != null) { |
||||||
|
ViewParams params = mRefreshableViews.get(view); |
||||||
|
if (params != null) { |
||||||
|
return params.onRefreshListener; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @param fromTouch |
||||||
|
* - Whether this is being invoked from a touch event |
||||||
|
* @return true if we're currently in a state where a refresh can be |
||||||
|
* started. |
||||||
|
*/ |
||||||
|
private boolean canRefresh(boolean fromTouch, OnRefreshListener listener) { |
||||||
|
return !mIsRefreshing && (!fromTouch || listener != null); |
||||||
|
} |
||||||
|
|
||||||
|
private float getScrollNeededForRefresh(View view) { |
||||||
|
return view.getHeight() * mRefreshScrollDistance; |
||||||
|
} |
||||||
|
|
||||||
|
private void reset(boolean fromTouch) { |
||||||
|
// Update isRefreshing state
|
||||||
|
mIsRefreshing = false; |
||||||
|
|
||||||
|
// Remove any minimize callbacks
|
||||||
|
if (mRefreshMinimize) { |
||||||
|
mHandler.removeCallbacks(mRefreshMinimizeRunnable); |
||||||
|
} |
||||||
|
|
||||||
|
// Hide Header View
|
||||||
|
hideHeaderView(); |
||||||
|
} |
||||||
|
|
||||||
|
private void startRefresh(View view, boolean fromTouch) { |
||||||
|
// Update isRefreshing state
|
||||||
|
mIsRefreshing = true; |
||||||
|
|
||||||
|
// Call OnRefreshListener if this call has originated from a touch event
|
||||||
|
if (fromTouch) { |
||||||
|
OnRefreshListener listener = getRefreshListenerForView(view); |
||||||
|
if (listener != null) { |
||||||
|
listener.onRefreshStarted(view); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Call Transformer
|
||||||
|
mHeaderTransformer.onRefreshStarted(); |
||||||
|
|
||||||
|
// Show Header View
|
||||||
|
showHeaderView(); |
||||||
|
|
||||||
|
// Post a runnable to minimize the refresh header
|
||||||
|
if (mRefreshMinimize) { |
||||||
|
if (mRefreshMinimizeDelay > 0) { |
||||||
|
mHandler.postDelayed(mRefreshMinimizeRunnable, mRefreshMinimizeDelay); |
||||||
|
} else { |
||||||
|
mHandler.post(mRefreshMinimizeRunnable); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Simple Listener to listen for any callbacks to Refresh. |
||||||
|
*/ |
||||||
|
public interface OnRefreshListener { |
||||||
|
/** |
||||||
|
* Called when the user has initiated a refresh by pulling. |
||||||
|
* |
||||||
|
* @param view |
||||||
|
* - View which the user has started the refresh from. |
||||||
|
*/ |
||||||
|
public void onRefreshStarted(View view); |
||||||
|
} |
||||||
|
|
||||||
|
public interface HeaderViewListener { |
||||||
|
/** |
||||||
|
* The state when the header view is completely visible. |
||||||
|
*/ |
||||||
|
public static int STATE_VISIBLE = 0; |
||||||
|
|
||||||
|
/** |
||||||
|
* The state when the header view is minimized. By default this means |
||||||
|
* that the progress bar is still visible, but the rest of the view is |
||||||
|
* hidden, showing the Action Bar behind. |
||||||
|
* <p/> |
||||||
|
* This will not be called in header minimization is disabled. |
||||||
|
*/ |
||||||
|
public static int STATE_MINIMIZED = 1; |
||||||
|
|
||||||
|
/** |
||||||
|
* The state when the header view is completely hidden. |
||||||
|
*/ |
||||||
|
public static int STATE_HIDDEN = 2; |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when the visibility state of the Header View has changed. |
||||||
|
* |
||||||
|
* @param headerView |
||||||
|
* HeaderView who's state has changed. |
||||||
|
* @param state |
||||||
|
* The new state. One of {@link #STATE_VISIBLE}, |
||||||
|
* {@link #STATE_MINIMIZED} and {@link #STATE_HIDDEN} |
||||||
|
*/ |
||||||
|
public void onStateChanged(View headerView, int state); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* HeaderTransformers are what controls and update the Header View to reflect the current state |
||||||
|
* of the pull-to-refresh interaction. They are responsible for showing and hiding the header |
||||||
|
* view, as well as update the state. |
||||||
|
*/ |
||||||
|
public static abstract class HeaderTransformer { |
||||||
|
|
||||||
|
/** |
||||||
|
* Called whether the header view has been inflated from the resources |
||||||
|
* defined in {@link Options#headerLayout}. |
||||||
|
* |
||||||
|
* @param activity The {@link Activity} that the header view is attached to. |
||||||
|
* @param headerView The inflated header view. |
||||||
|
*/ |
||||||
|
public void onViewCreated(Activity activity, View headerView) {} |
||||||
|
|
||||||
|
/** |
||||||
|
* @deprecated This will be removed before v1.0. Override |
||||||
|
* {@link #onViewCreated(android.app.Activity, android.view.View)} instead. |
||||||
|
*/ |
||||||
|
public void onViewCreated(View headerView) {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when the header should be reset. You should update any child |
||||||
|
* views to reflect this. |
||||||
|
* <p/> |
||||||
|
* You should <strong>not</strong> change the visibility of the header |
||||||
|
* view. |
||||||
|
*/ |
||||||
|
public void onReset() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called the user has pulled on the scrollable view. |
||||||
|
* |
||||||
|
* @param percentagePulled value between 0.0f and 1.0f depending on how far the |
||||||
|
* user has pulled. |
||||||
|
*/ |
||||||
|
public void onPulled(float percentagePulled) {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when a refresh has begun. Theoretically this call is similar |
||||||
|
* to that provided from {@link OnRefreshListener} but is more suitable |
||||||
|
* for header view updates. |
||||||
|
*/ |
||||||
|
public void onRefreshStarted() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when a refresh can be initiated when the user ends the touch |
||||||
|
* event. This is only called when {@link Options#refreshOnUp} is set to |
||||||
|
* true. |
||||||
|
*/ |
||||||
|
public void onReleaseToRefresh() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when the current refresh has taken longer than the time |
||||||
|
* specified in {@link Options#refreshMinimizeDelay}. |
||||||
|
*/ |
||||||
|
public void onRefreshMinimized() {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when the Header View should be made visible, usually with an animation. |
||||||
|
* |
||||||
|
* @return true if the visibility has changed. |
||||||
|
*/ |
||||||
|
public abstract boolean showHeaderView(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when the Header View should be made invisible, usually with an animation. |
||||||
|
* |
||||||
|
* @return true if the visibility has changed. |
||||||
|
*/ |
||||||
|
public abstract boolean hideHeaderView(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Called when the Activity's configuration has changed. |
||||||
|
* |
||||||
|
* @param activity The {@link Activity} that the header view is attached to. |
||||||
|
* @param newConfig New configuration. |
||||||
|
* |
||||||
|
* @see android.app.Activity#onConfigurationChanged(android.content.res.Configuration) |
||||||
|
*/ |
||||||
|
public void onConfigurationChanged(Activity activity, Configuration newConfig) {} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* ViewDelegates are what are used to de-couple the Attacher from the different types of |
||||||
|
* scrollable views. |
||||||
|
*/ |
||||||
|
public static abstract class ViewDelegate { |
||||||
|
|
||||||
|
/** |
||||||
|
* Allows you to provide support for View which do not have built-in |
||||||
|
* support. In this method you should cast <code>view</code> to it's |
||||||
|
* native class, and check if it is scrolled to the top. |
||||||
|
* |
||||||
|
* @param view |
||||||
|
* The view which has should be checked against. |
||||||
|
* @param x The X co-ordinate of the touch event |
||||||
|
* @param y The Y co-ordinate of the touch event |
||||||
|
* @return true if <code>view</code> is scrolled to the top. |
||||||
|
*/ |
||||||
|
public abstract boolean isReadyForPull(View view, float x, float y); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This is used to provide platform and environment specific functionality for the Attacher. |
||||||
|
*/ |
||||||
|
public static class EnvironmentDelegate { |
||||||
|
|
||||||
|
/** |
||||||
|
* @return Context which should be used for inflating the header layout |
||||||
|
*/ |
||||||
|
public Context getContextForInflater(Activity activity) { |
||||||
|
if (Build.VERSION.SDK_INT >= 14) { |
||||||
|
return activity.getActionBar().getThemedContext(); |
||||||
|
} else { |
||||||
|
return activity; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Allows you to specify a number of configuration options when instantiating a |
||||||
|
* {@link PullToRefreshAttacher}. Used with {@link #get(Activity, Options) get()}. |
||||||
|
*/ |
||||||
|
public static class Options { |
||||||
|
|
||||||
|
/** |
||||||
|
* EnvironmentDelegate instance which will be used. If null, we will |
||||||
|
* create an instance of the default class. |
||||||
|
*/ |
||||||
|
public EnvironmentDelegate environmentDelegate = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* The layout resource ID which should be inflated to be displayed above |
||||||
|
* the Action Bar |
||||||
|
*/ |
||||||
|
public int headerLayout = DEFAULT_HEADER_LAYOUT; |
||||||
|
|
||||||
|
/** |
||||||
|
* The header transformer to be used to transfer the header view. If |
||||||
|
* null, an instance of {@link DefaultHeaderTransformer} will be used. |
||||||
|
*/ |
||||||
|
public HeaderTransformer headerTransformer = null; |
||||||
|
|
||||||
|
/** |
||||||
|
* The percentage of the refreshable view that needs to be scrolled |
||||||
|
* before a refresh is initiated. |
||||||
|
*/ |
||||||
|
public float refreshScrollDistance = DEFAULT_REFRESH_SCROLL_DISTANCE; |
||||||
|
|
||||||
|
/** |
||||||
|
* Whether a refresh should only be initiated when the user has finished |
||||||
|
* the touch event. |
||||||
|
*/ |
||||||
|
public boolean refreshOnUp = DEFAULT_REFRESH_ON_UP; |
||||||
|
|
||||||
|
/** |
||||||
|
* The delay after a refresh is started in which the header should be |
||||||
|
* 'minimized'. By default, most of the header is faded out, leaving |
||||||
|
* only the progress bar signifying that a refresh is taking place. |
||||||
|
*/ |
||||||
|
public int refreshMinimizeDelay = DEFAULT_REFRESH_MINIMIZED_DELAY; |
||||||
|
|
||||||
|
/** |
||||||
|
* Enable or disable the header 'minimization', which by default means that the majority of |
||||||
|
* the header is hidden, leaving only the progress bar still showing. |
||||||
|
* <p/> |
||||||
|
* If set to true, the header will be minimized after the delay set in |
||||||
|
* {@link #refreshMinimizeDelay}. If set to false then the whole header will be displayed |
||||||
|
* until the refresh is finished. |
||||||
|
*/ |
||||||
|
public boolean refreshMinimize = DEFAULT_REFRESH_MINIMIZE; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This class allows us to insert a layer in between the system decor view |
||||||
|
* and the actual decor. (e.g. Action Bar views). This is needed so we can |
||||||
|
* receive a call to fitSystemWindows(Rect) so we can adjust the header view |
||||||
|
* to fit the system windows too. |
||||||
|
*/ |
||||||
|
final static class DecorChildLayout extends FrameLayout { |
||||||
|
private final ViewGroup mHeaderViewWrapper; |
||||||
|
|
||||||
|
DecorChildLayout(Context context, ViewGroup systemDecorView, |
||||||
|
View headerView) { |
||||||
|
super(context); |
||||||
|
|
||||||
|
// Move all children from decor view to here
|
||||||
|
for (int i = 0, z = systemDecorView.getChildCount(); i < z; i++) { |
||||||
|
View child = systemDecorView.getChildAt(i); |
||||||
|
systemDecorView.removeView(child); |
||||||
|
addView(child); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Wrap the Header View in a FrameLayout and add it to this view. It |
||||||
|
* is wrapped so any inset changes do not affect the actual header |
||||||
|
* view. |
||||||
|
*/ |
||||||
|
mHeaderViewWrapper = new FrameLayout(context); |
||||||
|
mHeaderViewWrapper.addView(headerView); |
||||||
|
addView(mHeaderViewWrapper, ViewGroup.LayoutParams.MATCH_PARENT, |
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected boolean fitSystemWindows(Rect insets) { |
||||||
|
if (DEBUG) { |
||||||
|
Log.d(LOG_TAG, "fitSystemWindows: " + insets.toString()); |
||||||
|
} |
||||||
|
|
||||||
|
// Adjust the Header View's padding to take the insets into account
|
||||||
|
mHeaderViewWrapper.setPadding(insets.left, insets.top, |
||||||
|
insets.right, insets.bottom); |
||||||
|
|
||||||
|
// Call return super so that the rest of the
|
||||||
|
return super.fitSystemWindows(insets); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static final class ViewParams { |
||||||
|
final OnRefreshListener onRefreshListener; |
||||||
|
final ViewDelegate viewDelegate; |
||||||
|
|
||||||
|
ViewParams(ViewDelegate _viewDelegate, |
||||||
|
OnRefreshListener _onRefreshListener) { |
||||||
|
onRefreshListener = _onRefreshListener; |
||||||
|
viewDelegate = _viewDelegate; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private final Runnable mRefreshMinimizeRunnable = new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
mHeaderTransformer.onRefreshMinimized(); |
||||||
|
|
||||||
|
if (mHeaderViewListener != null) { |
||||||
|
mHeaderViewListener.onStateChanged(mHeaderView, |
||||||
|
HeaderViewListener.STATE_MINIMIZED); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.content.res.Configuration; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.MotionEvent; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.FrameLayout; |
||||||
|
|
||||||
|
/** |
||||||
|
* FIXME |
||||||
|
*/ |
||||||
|
public class PullToRefreshLayout extends FrameLayout { |
||||||
|
|
||||||
|
private static final boolean DEBUG = false; |
||||||
|
private static final String LOG_TAG = "PullToRefreshLayout"; |
||||||
|
|
||||||
|
private PullToRefreshAttacher mPullToRefreshAttacher; |
||||||
|
private View mCurrentTouchTarget; |
||||||
|
|
||||||
|
public PullToRefreshLayout(Context context) { |
||||||
|
this(context, null); |
||||||
|
} |
||||||
|
|
||||||
|
public PullToRefreshLayout(Context context, AttributeSet attrs) { |
||||||
|
this(context, attrs, 0); |
||||||
|
} |
||||||
|
|
||||||
|
public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyle) { |
||||||
|
super(context, attrs, defStyle); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Set the {@link PullToRefreshAttacher} to be used with this layout. The view which is added |
||||||
|
* to this layout will automatically be added as a refreshable-view in the attacher. |
||||||
|
*/ |
||||||
|
public void setPullToRefreshAttacher(PullToRefreshAttacher attacher, |
||||||
|
PullToRefreshAttacher.OnRefreshListener refreshListener) { |
||||||
|
View view; |
||||||
|
for (int i = 0, z = getChildCount(); i < z; i++) { |
||||||
|
view = getChildAt(i); |
||||||
|
|
||||||
|
if (mPullToRefreshAttacher != null) { |
||||||
|
mPullToRefreshAttacher.removeRefreshableView(view); |
||||||
|
} |
||||||
|
|
||||||
|
if (attacher != null) { |
||||||
|
if (DEBUG) Log.d(LOG_TAG, "Adding View to Attacher: " + view); |
||||||
|
attacher.addRefreshableView(view, null, refreshListener, false); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
mPullToRefreshAttacher = attacher; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onInterceptTouchEvent(MotionEvent event) { |
||||||
|
if (DEBUG) Log.d(LOG_TAG, "onInterceptTouchEvent. " + event.toString()); |
||||||
|
|
||||||
|
if (mPullToRefreshAttacher != null && getChildCount() > 0) { |
||||||
|
View target = getChildForTouchEvent(event); |
||||||
|
if (target != null && mPullToRefreshAttacher.onInterceptTouchEvent(target, event)) { |
||||||
|
mCurrentTouchTarget = target; |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
// Reset Current Touch Target
|
||||||
|
mCurrentTouchTarget = null; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onTouchEvent(MotionEvent event) { |
||||||
|
if (DEBUG) Log.d(LOG_TAG, "onTouchEvent. " + event.toString()); |
||||||
|
|
||||||
|
if (mPullToRefreshAttacher != null) { |
||||||
|
// This is an edge-case. If the ViewGroup does not contain a valid touch target then
|
||||||
|
// Android calls onTouchEvent after onInterceptTouchEvent with ACTION_DOWN event.
|
||||||
|
// If that happens then we need to find the visible view and pass it to the attacher as
|
||||||
|
// usual.
|
||||||
|
if (mCurrentTouchTarget == null && event.getAction() == MotionEvent.ACTION_DOWN) { |
||||||
|
mCurrentTouchTarget = getChildForTouchEvent(event); |
||||||
|
} |
||||||
|
|
||||||
|
if (mCurrentTouchTarget != null) { |
||||||
|
return mPullToRefreshAttacher.onTouchEvent(mCurrentTouchTarget, event); |
||||||
|
} |
||||||
|
} |
||||||
|
// Reset Current Touch Target
|
||||||
|
mCurrentTouchTarget = null; |
||||||
|
return super.onTouchEvent(event); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onConfigurationChanged(Configuration newConfig) { |
||||||
|
super.onConfigurationChanged(newConfig); |
||||||
|
|
||||||
|
if (mPullToRefreshAttacher != null) { |
||||||
|
mPullToRefreshAttacher.onConfigurationChanged(newConfig); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private View getChildForTouchEvent(MotionEvent event) { |
||||||
|
final float x = event.getX(), y = event.getY(); |
||||||
|
View child; |
||||||
|
for (int z = getChildCount() - 1; z >= 0 ; z--) { |
||||||
|
child = getChildAt(z); |
||||||
|
if (child.isShown() && x >= child.getLeft() && x <= child.getRight() |
||||||
|
&& y >= child.getTop() && y <= child.getBottom()) { |
||||||
|
if (DEBUG) Log.d(LOG_TAG, "Got Child for Touch Event: " + child); |
||||||
|
return child; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library.platform; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
public class SDK11 { |
||||||
|
|
||||||
|
public static void setAlpha(View view, float alpha) { |
||||||
|
view.setAlpha(alpha); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,93 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library.viewdelegates; |
||||||
|
|
||||||
|
import android.annotation.TargetApi; |
||||||
|
import android.os.Build; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.AbsListView; |
||||||
|
|
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher; |
||||||
|
|
||||||
|
/** |
||||||
|
* FIXME |
||||||
|
*/ |
||||||
|
public class AbsListViewDelegate |
||||||
|
extends PullToRefreshAttacher.ViewDelegate { |
||||||
|
|
||||||
|
public static final Class SUPPORTED_VIEW_CLASS = AbsListView.class; |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isReadyForPull(View view, final float x, final float y) { |
||||||
|
boolean ready = false; |
||||||
|
|
||||||
|
// First we check whether we're scrolled to the top
|
||||||
|
AbsListView absListView = (AbsListView) view; |
||||||
|
if (absListView.getCount() == 0) { |
||||||
|
ready = true; |
||||||
|
} else if (absListView.getFirstVisiblePosition() == 0) { |
||||||
|
final View firstVisibleChild = absListView.getChildAt(0); |
||||||
|
ready = firstVisibleChild != null && firstVisibleChild.getTop() >= 0; |
||||||
|
} |
||||||
|
|
||||||
|
// Then we have to check whether the fas scroller is enabled, and check we're not starting
|
||||||
|
// the gesture from the scroller
|
||||||
|
if (ready && absListView.isFastScrollEnabled() && isFastScrollAlwaysVisible(absListView)) { |
||||||
|
switch (getVerticalScrollbarPosition(absListView)) { |
||||||
|
case View.SCROLLBAR_POSITION_RIGHT: |
||||||
|
ready = x < absListView.getRight() - absListView.getVerticalScrollbarWidth(); |
||||||
|
break; |
||||||
|
case View.SCROLLBAR_POSITION_LEFT: |
||||||
|
ready = x > absListView.getVerticalScrollbarWidth(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ready; |
||||||
|
} |
||||||
|
|
||||||
|
int getVerticalScrollbarPosition(AbsListView absListView) { |
||||||
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? |
||||||
|
CompatV11.getVerticalScrollbarPosition(absListView) : |
||||||
|
Compat.getVerticalScrollbarPosition(absListView); |
||||||
|
} |
||||||
|
|
||||||
|
boolean isFastScrollAlwaysVisible(AbsListView absListView) { |
||||||
|
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ? |
||||||
|
CompatV11.isFastScrollAlwaysVisible(absListView) : |
||||||
|
Compat.isFastScrollAlwaysVisible(absListView); |
||||||
|
} |
||||||
|
|
||||||
|
static class Compat { |
||||||
|
static int getVerticalScrollbarPosition(AbsListView absListView) { |
||||||
|
return View.SCROLLBAR_POSITION_RIGHT; |
||||||
|
} |
||||||
|
static boolean isFastScrollAlwaysVisible(AbsListView absListView) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.HONEYCOMB) |
||||||
|
static class CompatV11 { |
||||||
|
static int getVerticalScrollbarPosition(AbsListView absListView) { |
||||||
|
return absListView.getVerticalScrollbarPosition(); |
||||||
|
} |
||||||
|
static boolean isFastScrollAlwaysVisible(AbsListView absListView) { |
||||||
|
return absListView.isFastScrollAlwaysVisible(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library.viewdelegates; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
|
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher; |
||||||
|
|
||||||
|
/** |
||||||
|
* FIXME |
||||||
|
*/ |
||||||
|
public class ScrollYDelegate extends PullToRefreshAttacher.ViewDelegate { |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isReadyForPull(View view, float x, float y) { |
||||||
|
return view.getScrollY() <= 0; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,35 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2013 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 uk.co.senab.actionbarpulltorefresh.library.viewdelegates; |
||||||
|
|
||||||
|
import android.view.View; |
||||||
|
import android.webkit.WebView; |
||||||
|
|
||||||
|
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshAttacher; |
||||||
|
|
||||||
|
/** |
||||||
|
* FIXME |
||||||
|
*/ |
||||||
|
public class WebViewDelegate extends PullToRefreshAttacher.ViewDelegate { |
||||||
|
|
||||||
|
public static final Class SUPPORTED_VIEW_CLASS = WebView.class; |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isReadyForPull(View view, float x, float y) { |
||||||
|
return view.getScrollY() <= 0; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,2 @@ |
|||||||
|
key.store=/home/eric/Dev/erickok.keystore |
||||||
|
key.alias=transdroid |
@ -0,0 +1,92 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project name="Transdrone" default="help"> |
||||||
|
|
||||||
|
<!-- The local.properties file is created and updated by the 'android' tool. |
||||||
|
It contains the path to the SDK. It should *NOT* be checked into |
||||||
|
Version Control Systems. --> |
||||||
|
<property file="local.properties" /> |
||||||
|
|
||||||
|
<!-- The ant.properties file can be created by you. It is only edited by the |
||||||
|
'android' tool to add properties to it. |
||||||
|
This is the place to change some Ant specific build properties. |
||||||
|
Here are some properties you may want to change/update: |
||||||
|
|
||||||
|
source.dir |
||||||
|
The name of the source directory. Default is 'src'. |
||||||
|
out.dir |
||||||
|
The name of the output directory. Default is 'bin'. |
||||||
|
|
||||||
|
For other overridable properties, look at the beginning of the rules |
||||||
|
files in the SDK, at tools/ant/build.xml |
||||||
|
|
||||||
|
Properties related to the SDK location or the project target should |
||||||
|
be updated using the 'android' tool with the 'update' action. |
||||||
|
|
||||||
|
This file is an integral part of the build system for your |
||||||
|
application and should be checked into Version Control Systems. |
||||||
|
|
||||||
|
--> |
||||||
|
<property file="ant.properties" /> |
||||||
|
|
||||||
|
<!-- if sdk.dir was not set from one of the property file, then |
||||||
|
get it from the ANDROID_HOME env var. |
||||||
|
This must be done before we load project.properties since |
||||||
|
the proguard config can use sdk.dir --> |
||||||
|
<property environment="env" /> |
||||||
|
<condition property="sdk.dir" value="${env.ANDROID_HOME}"> |
||||||
|
<isset property="env.ANDROID_HOME" /> |
||||||
|
</condition> |
||||||
|
|
||||||
|
<!-- The project.properties file is created and updated by the 'android' |
||||||
|
tool, as well as ADT. |
||||||
|
|
||||||
|
This contains project specific properties such as project target, and library |
||||||
|
dependencies. Lower level build properties are stored in ant.properties |
||||||
|
(or in .classpath for Eclipse projects). |
||||||
|
|
||||||
|
This file is an integral part of the build system for your |
||||||
|
application and should be checked into Version Control Systems. --> |
||||||
|
<loadproperties srcFile="project.properties" /> |
||||||
|
|
||||||
|
<!-- quick check on sdk.dir --> |
||||||
|
<fail |
||||||
|
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable." |
||||||
|
unless="sdk.dir" |
||||||
|
/> |
||||||
|
|
||||||
|
<!-- |
||||||
|
Import per project custom build rules if present at the root of the project. |
||||||
|
This is the place to put custom intermediary targets such as: |
||||||
|
-pre-build |
||||||
|
-pre-compile |
||||||
|
-post-compile (This is typically used for code obfuscation. |
||||||
|
Compiled code location: ${out.classes.absolute.dir} |
||||||
|
If this is not done in place, override ${out.dex.input.absolute.dir}) |
||||||
|
-post-package |
||||||
|
-post-build |
||||||
|
-pre-clean |
||||||
|
--> |
||||||
|
<import file="custom_rules.xml" optional="true" /> |
||||||
|
|
||||||
|
<!-- Import the actual build file. |
||||||
|
|
||||||
|
To customize existing targets, there are two options: |
||||||
|
- Customize only one target: |
||||||
|
- copy/paste the target into this file, *before* the |
||||||
|
<import> task. |
||||||
|
- customize it to your needs. |
||||||
|
- Customize the whole content of build.xml |
||||||
|
- copy/paste the content of the rules files (minus the top node) |
||||||
|
into this file, replacing the <import> task. |
||||||
|
- customize to your needs. |
||||||
|
|
||||||
|
*********************** |
||||||
|
****** IMPORTANT ****** |
||||||
|
*********************** |
||||||
|
In all cases you must update the value of version-tag below to read 'custom' instead of an integer, |
||||||
|
in order to avoid having your file be overridden by tools such as "android update project" |
||||||
|
--> |
||||||
|
<!-- version-tag: 1 --> |
||||||
|
<import file="${sdk.dir}/tools/ant/build.xml" /> |
||||||
|
|
||||||
|
</project> |