@ -0,0 +1,17 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -0,0 +1,3 @@
|
||||
POM_NAME=ActionBar-PullToRefresh Extras: ActionBarSherlock |
||||
POM_ARTIFACT_ID=extra-abs |
||||
POM_PACKAGING=aar |
@ -0,0 +1,20 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -0,0 +1,3 @@
|
||||
POM_NAME=ActionBar-PullToRefresh Library |
||||
POM_ARTIFACT_ID=library |
||||
POM_PACKAGING=aar |
@ -0,0 +1,20 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -0,0 +1,2 @@
|
||||
key.store=/home/eric/Dev/erickok.keystore |
||||
key.alias=transdroid |
@ -0,0 +1,92 @@
@@ -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> |