├── .gitignore
├── README.md
├── build.gradle
├── demo
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── pullrefresh
│ │ └── demo
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── pullrefresh
│ │ └── demo
│ │ ├── DemoAct.java
│ │ ├── RecyclerViewAct.java
│ │ └── ScrollViewAct.java
│ └── res
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ ├── ic_launcher.png
│ └── pulltorefresh_arrow.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ ├── activity_main.xml
│ └── recycler.xml
│ ├── menu
│ └── menu_main.xml
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── lib
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── pullrefreshlayout
│ │ └── ApplicationTest.java
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── pullrefreshlayout
│ │ ├── DefaultHeadView.java
│ │ ├── ILoadingLayout.java
│ │ ├── PullRefresScrollView.java
│ │ ├── PullRefreshRecyclerView.java
│ │ ├── RefreshLayout.java
│ │ └── WaterfallRecyclerView.java
│ └── res
│ ├── anim
│ ├── down_to_up.xml
│ └── up_to_down.xml
│ ├── drawable-hdpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ ├── ic_launcher.png
│ └── pulltorefresh_arrow.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── layout
│ └── head_layout.xml
│ ├── values-zh
│ └── strings.xml
│ └── values
│ ├── strings.xml
│ └── styles.xml
├── recyclerview.gif
├── scrollview.gif
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | .DS_Store
3 |
4 | # library
5 | mgim/
6 | mglibs/
7 | mgim-android/
8 | library/
9 |
10 | # android generated
11 | bin/
12 | gen/
13 |
14 | # eclipse
15 | .classpath
16 | .settings
17 | .project
18 |
19 | local.properties
20 | project.properties
21 |
22 | # IDEA
23 | .idea/
24 | *.iml
25 | out/
26 |
27 | # gradle
28 | build/
29 | .gradle/
30 | gradle/
31 | gradlew
32 | gradlew.bat
33 | gradle.properties
34 |
35 | # build
36 | lint.xml
37 | lint.html
38 | proguard-rules.txt
39 |
40 | run.sh
41 | com_crashlytics_export_strings.xml
42 | crashlytics-build.properties
43 | Mogujie4Android/libs/eventbus-2.2.1.jar
44 |
45 | # test
46 | test.html
47 |
48 | Mogujie4Android/assets/crashlytics-build.properties
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## PullRefreshLayout
2 |
3 | a pull down to Refresh Layout .
4 |
5 |
6 | support RecyclerView & ScrollView
7 |
8 | ---------------------
9 |
10 | ## how to use
11 |
12 | ``` compile 'com.pullrefreshlayout:lib:0.5.3@aar ```
13 |
14 | ### demo
15 |
16 | RecyclerView
17 |
18 | 
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | mavenCentral()
5 | }
6 | dependencies {
7 | classpath 'com.android.tools.build:gradle:1.0.1'
8 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.1'
9 | classpath 'com.github.dcendents:android-maven-plugin:1.2'
10 | }
11 | }
12 |
13 | allprojects {
14 | repositories {
15 | mavenCentral()
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/demo/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/demo/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 20
5 | buildToolsVersion "21.1.2"
6 |
7 | defaultConfig {
8 | applicationId "com.pullrefresh.demo"
9 | minSdkVersion 15
10 | targetSdkVersion 20
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | }
20 |
21 |
22 |
23 | repositories {
24 | mavenCentral()
25 | }
26 |
27 |
28 | dependencies {
29 | provided fileTree(dir: 'libs', include: ['*.jar'])
30 | compile project(':lib')
31 | }
32 |
--------------------------------------------------------------------------------
/demo/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/6a209/dev/android/android-sdks/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/demo/src/androidTest/java/com/pullrefresh/demo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.pullrefresh.demo;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/demo/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/pullrefresh/demo/DemoAct.java:
--------------------------------------------------------------------------------
1 | package com.pullrefresh.demo;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.util.Log;
8 |
9 | /**
10 | * Created by 6a209 on 14/10/29.
11 | */
12 | public class DemoAct extends Activity{
13 |
14 | @Override
15 | public void onCreate(Bundle bundle){
16 | super.onCreate(bundle);
17 | setContentView(R.layout.activity_main);
18 | Log.e("DemoAct", getClassLoader().toString());
19 | }
20 |
21 |
22 |
23 | public void toScrollAct(View view){
24 | Intent intent = new Intent(this, ScrollViewAct.class);
25 | startActivity(intent);
26 | }
27 |
28 | public void toRecyclerAct(View view){
29 | Intent intent = new Intent(this, RecyclerViewAct.class);
30 | startActivity(intent);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/pullrefresh/demo/RecyclerViewAct.java:
--------------------------------------------------------------------------------
1 | package com.pullrefresh.demo;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.LayoutInflater;
7 | import android.view.ViewGroup;
8 | import android.widget.TextView;
9 | import android.util.Log;
10 |
11 | import com.pullrefreshlayout.PullRefreshRecyclerView;
12 | import com.pullrefreshlayout.RefreshLayout;
13 |
14 | /**
15 | * Created by 6a209 on 14/10/21.
16 | */
17 | public class RecyclerViewAct extends Activity{
18 |
19 | @Override
20 | public void onCreate(Bundle bundle){
21 | super.onCreate(bundle);
22 |
23 | Log.e("DemoAct", getClassLoader().toString());
24 | String [] datas = new String[50];
25 | for(int i = 0; i < 50; i++){
26 | datas[i] = "it is test data " + i;
27 | }
28 | MyAdapter adapter = new MyAdapter(datas);
29 |
30 | setContentView(R.layout.recycler);
31 |
32 | final PullRefreshRecyclerView pullRefreshRecyclerView = (PullRefreshRecyclerView)findViewById(R.id.recycler);
33 | RecyclerView recyclerView = (RecyclerView)pullRefreshRecyclerView.getRefreshView();
34 | recyclerView.setAdapter(adapter);
35 |
36 | // setContentView(pullRefreshRecyclerView);
37 | pullRefreshRecyclerView.setOnRefreshListener(new RefreshLayout.OnRefreshListener() {
38 | @Override
39 | public void onPullDown(float y) {
40 |
41 | }
42 |
43 | @Override
44 | public void onRefresh() {
45 | pullRefreshRecyclerView.postDelayed(new Runnable() {
46 | @Override
47 | public void run() {
48 | pullRefreshRecyclerView.refreshOver(null);
49 | }
50 | }, 2000);
51 | }
52 |
53 | @Override
54 | public void onRefreshOver(Object obj) {
55 |
56 | }
57 |
58 |
59 | });
60 | }
61 |
62 | public static class ViewHolder extends RecyclerView.ViewHolder {
63 | public TextView mTextView;
64 | public ViewHolder(TextView v) {
65 | super(v);
66 | mTextView = v;
67 | }
68 | }
69 |
70 | public static class MyAdapter extends RecyclerView.Adapter {
71 | private String[] mDataset;
72 |
73 |
74 | public MyAdapter(String[] myDataset) {
75 | mDataset = myDataset;
76 | }
77 |
78 | @Override
79 | public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
80 | TextView v = (TextView) LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_1, parent, false);
81 | ViewHolder vh = new ViewHolder(v);
82 | return vh;
83 | }
84 |
85 |
86 | @Override
87 | public void onBindViewHolder(ViewHolder holder, int position) {
88 | holder.mTextView.setText(mDataset[position]);
89 |
90 | }
91 |
92 | @Override
93 | public int getItemCount() {
94 | return mDataset.length;
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/demo/src/main/java/com/pullrefresh/demo/ScrollViewAct.java:
--------------------------------------------------------------------------------
1 | package com.pullrefresh.demo;
2 |
3 | import android.app.Activity;
4 | import android.graphics.Color;
5 | import android.os.Bundle;
6 | import android.support.v4.view.ViewPager;
7 | import android.view.Gravity;
8 | import android.view.Menu;
9 | import android.view.MenuItem;
10 | import android.view.View;
11 | import android.widget.ScrollView;
12 | import android.widget.TextView;
13 |
14 | import com.pullrefreshlayout.PullRefresScrollView;
15 | import com.pullrefreshlayout.RefreshLayout;
16 |
17 |
18 | public class ScrollViewAct extends Activity {
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | final PullRefresScrollView scrollView = new PullRefresScrollView(this);
24 | setContentView(scrollView);
25 | ViewPager viewPager = new ViewPager(this);
26 |
27 | TextView tv = new TextView(this);
28 | tv.setGravity(Gravity.CENTER);
29 | tv.setPadding(0, 300, 0, 300);
30 | tv.setBackgroundColor(Color.BLACK);
31 | tv.setTextSize(80);
32 | tv.setText("Hi \n Android \n here \n come \n from \n 6a209");
33 | ((ScrollView)scrollView.getRefreshView()).addView(tv);
34 |
35 | tv.setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View v) {
38 | scrollView.setToRefreshing();
39 | }
40 | });
41 | scrollView.setOnRefreshListener(new RefreshLayout.OnRefreshListener() {
42 | @Override
43 | public void onPullDown(float y) {
44 |
45 | }
46 |
47 | @Override
48 | public void onRefresh() {
49 | scrollView.postDelayed(new Runnable() {
50 | @Override
51 | public void run() {
52 | scrollView.refreshOver(null);
53 | }
54 | }, 2000);
55 | }
56 |
57 | @Override
58 | public void onRefreshOver(Object obj) {
59 |
60 | }
61 | });
62 | }
63 |
64 |
65 | @Override
66 | public boolean onCreateOptionsMenu(Menu menu) {
67 | // Inflate the menu; this adds items to the action bar if it is present.
68 | getMenuInflater().inflate(R.menu.menu_main, menu);
69 | return true;
70 | }
71 |
72 | @Override
73 | public boolean onOptionsItemSelected(MenuItem item) {
74 | // Handle action bar item clicks here. The action bar will
75 | // automatically handle clicks on the Home/Up button, so long
76 | // as you specify a parent activity in AndroidManifest.xml.
77 | int id = item.getItemId();
78 |
79 | //noinspection SimplifiableIfStatement
80 | if (id == R.id.action_settings) {
81 | return true;
82 | }
83 |
84 | return super.onOptionsItemSelected(item);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/demo/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/demo/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/demo/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xhdpi/pulltorefresh_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/demo/src/main/res/drawable-xhdpi/pulltorefresh_arrow.png
--------------------------------------------------------------------------------
/demo/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/demo/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/demo/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
15 |
16 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/src/main/res/layout/recycler.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
16 |
17 |
24 |
25 |
33 |
34 |
--------------------------------------------------------------------------------
/demo/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/demo/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | My Application
5 | Hello world!
6 | Settings
7 |
8 |
9 |
--------------------------------------------------------------------------------
/demo/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/lib/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'android-library'
2 | apply plugin: 'com.jfrog.bintray'
3 | //apply plugin: 'maven'
4 | apply plugin: 'com.github.dcendents.android-maven'
5 |
6 |
7 |
8 | android {
9 | compileSdkVersion 20
10 | buildToolsVersion "20.0.0"
11 |
12 | defaultConfig {
13 | targetSdkVersion 20
14 | minSdkVersion 15
15 | versionCode 1
16 | versionName "1.0"
17 | }
18 |
19 | buildTypes {
20 | release {
21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
22 | }
23 | }
24 | lintOptions {
25 | abortOnError false
26 | }
27 |
28 | }
29 |
30 |
31 | repositories {
32 | mavenCentral()
33 | }
34 |
35 |
36 | dependencies {
37 | compile fileTree(dir: 'libs', include: ['*.jar'])
38 | compile 'com.android.support:recyclerview-v7:22.0.0'
39 | }
40 |
41 |
42 | uploadArchives {
43 | repositories {
44 | mavenDeployer {
45 | pom.artifactId = 'lib'
46 | pom.groupId = 'com.pullrefreshlayout'
47 | pom.version = '0.3.0-SNAPSHOT'
48 | repository() {
49 | mavenCentral()
50 | }
51 | }
52 | }
53 | }
54 |
55 | apply plugin: 'com.jfrog.bintray'
56 | apply plugin: 'maven-publish'
57 |
58 |
59 | group = GROUP
60 | version = VERSION
61 |
62 | def pomConfig = {
63 | licenses {
64 | license {
65 | name LICENSES_NAME
66 | url LICENSES_URL
67 | }
68 | }
69 |
70 | developers {
71 | developer {
72 | id DEVELOPER_ID
73 | name DEVELOPER_NAME
74 | email DEVELOPER_EMAIL
75 | }
76 | }
77 | }
78 | install {
79 | repositories.mavenInstaller {
80 | // This generates POM.xml with proper parameters
81 | pom {
82 | project {
83 | packaging 'aar'
84 | name NAME
85 | url SITE_URL
86 | licenses {
87 | license {
88 | name LICENSES_NAME
89 | }
90 | }
91 | developers {
92 | developer {
93 | id DEVELOPER_ID
94 | name DEVELOPER_NAME
95 | email DEVELOPER_EMAIL
96 | }
97 | }
98 | scm {
99 | connection GIT_URL
100 | developerConnection GIT_URL
101 | url SITE_URL
102 | }
103 | }
104 | }
105 | }
106 | }
107 |
108 |
109 | task sourcesJar(type: Jar) {
110 | from android.sourceSets.main.java.srcDirs
111 | classifier = 'sources'
112 | }
113 |
114 | task javadoc(type: Javadoc) {
115 | source = android.sourceSets.main.java.srcDirs
116 | //classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
117 | }
118 |
119 | task javadocJar(type: Jar, dependsOn: javadoc) {
120 | classifier = 'javadoc'
121 | from javadoc.destinationDir
122 | }
123 |
124 | artifacts {
125 | archives javadocJar
126 | archives sourcesJar
127 | }
128 |
129 | bintray {
130 | user = BINTRAY_USER
131 | key = BINTRAY_APIKEY
132 | configurations = ['archives']
133 | pkg {
134 | repo = "maven"
135 | name = 'pullrefreshlayout' // project name in jcenter
136 | websiteUrl = SITE_URL
137 | vcsUrl = GIT_URL
138 | licenses = LICENSES_NAME
139 | publish = true
140 | version {
141 | attributes = ['gradle-plugin': 'com.li6a209:pullrefreshlayout']
142 | }
143 | }
144 | }
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/lib/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/6a209/dev/android/android-sdks/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/lib/src/androidTest/java/com/pullrefreshlayout/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.pullrefreshlayout;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/lib/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/pullrefreshlayout/DefaultHeadView.java:
--------------------------------------------------------------------------------
1 | package com.pullrefreshlayout;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.view.animation.Animation;
9 | import android.view.animation.AnimationUtils;
10 | import android.widget.ImageView;
11 | import android.widget.RelativeLayout;
12 | import android.widget.TextView;
13 |
14 | /**
15 | * Created by 6a209 on 14/11/1.
16 | */
17 | public class DefaultHeadView extends RelativeLayout implements ILoadingLayout{
18 |
19 |
20 | private Animation mDownToUpAnim;
21 | private Animation mUpToDownAnim;
22 | private View mLeftProgress;
23 | private ImageView mLeftImage;
24 | private TextView mTitle;
25 | private boolean mImageIsUp;
26 |
27 |
28 | public DefaultHeadView(Context context){
29 | this(context, null);
30 | mDownToUpAnim = AnimationUtils.loadAnimation(this.getContext(), R.anim.down_to_up);
31 | mUpToDownAnim = AnimationUtils.loadAnimation(this.getContext(), R.anim.up_to_down);
32 | mDownToUpAnim.setFillAfter(true);
33 | mUpToDownAnim.setFillAfter(true);
34 | LayoutInflater.from(context).inflate(R.layout.head_layout, this);
35 | setLayoutParams(new RefreshLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 200));
36 | mLeftProgress = findViewById(R.id.head_layout_left_progressbar);
37 | mLeftImage = (ImageView)findViewById(R.id.head_layout_left_arrow);
38 | mTitle = (TextView)findViewById(R.id.head_layout_title);
39 | }
40 |
41 | public DefaultHeadView(Context context, AttributeSet attrs) {
42 | super(context, attrs);
43 |
44 | }
45 |
46 | @Override
47 | public void pullToRefresh() {
48 | if(mImageIsUp){
49 | mLeftImage.startAnimation(mUpToDownAnim);
50 | mImageIsUp = false;
51 | }
52 | mTitle.setText(getResources().getString(R.string.pull_to_refresh));
53 | }
54 |
55 | @Override
56 | public void releaseToRefresh() {
57 | mLeftImage.startAnimation(mDownToUpAnim);
58 | mImageIsUp = true;
59 | mTitle.setText(getResources().getString(R.string.release_to_refresh));
60 | }
61 |
62 | @Override
63 | public void refreshing() {
64 | mImageIsUp = false;
65 | mLeftProgress.setVisibility(View.VISIBLE);
66 | mTitle.setText(getResources().getString(R.string.refreshing));
67 | mLeftImage.clearAnimation();
68 | mLeftImage.setVisibility(View.INVISIBLE);
69 | }
70 |
71 | @Override
72 | public void normal(){
73 | mImageIsUp = false;
74 | mLeftImage.setVisibility(View.VISIBLE);
75 | mLeftProgress.setVisibility(View.GONE);
76 | mTitle.setText(getResources().getString(R.string.pull_to_refresh));
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/pullrefreshlayout/ILoadingLayout.java:
--------------------------------------------------------------------------------
1 | package com.pullrefreshlayout;
2 |
3 | /**
4 | * Created by 6a209 on 14/10/19.
5 | */
6 | public interface ILoadingLayout {
7 |
8 | public void pullToRefresh();
9 | public void releaseToRefresh();
10 | public void refreshing();
11 | public void normal();
12 | }
13 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/pullrefreshlayout/PullRefresScrollView.java:
--------------------------------------------------------------------------------
1 | package com.pullrefreshlayout;
2 | import android.content.Context;
3 | import android.util.AttributeSet;
4 | import android.view.View;
5 | import android.widget.ScrollView;
6 |
7 | /**
8 | * Created by 6a209 on 14/10/21.
9 | */
10 | public class PullRefresScrollView extends RefreshLayout{
11 |
12 | public PullRefresScrollView(Context context){
13 | this(context, null);
14 | }
15 |
16 | public PullRefresScrollView(Context context, AttributeSet attrs) {
17 | super(context, attrs);
18 | }
19 |
20 | @Override
21 | protected View createRefreshView() {
22 | return new ScrollView(getContext());
23 | }
24 |
25 | }
--------------------------------------------------------------------------------
/lib/src/main/java/com/pullrefreshlayout/PullRefreshRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.pullrefreshlayout;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.LinearLayoutManager;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.AttributeSet;
7 | import android.view.View;
8 |
9 | /**
10 | * just support the LinearLayoutManager and the orientation is vertical
11 | * Created by 6a209 on 14/10/29.
12 | */
13 | public class PullRefreshRecyclerView extends RefreshLayout{
14 |
15 | public PullRefreshRecyclerView(Context context){
16 | this(context, null);
17 | }
18 |
19 | public PullRefreshRecyclerView(Context context, AttributeSet attrs) {
20 | super(context, attrs);
21 | }
22 |
23 | @Override
24 | protected View createRefreshView() {
25 | RecyclerView rv = new RecyclerView(getContext());
26 | LinearLayoutManager lm = new LinearLayoutManager(getContext());
27 | lm.setOrientation(LinearLayoutManager.VERTICAL);
28 | rv.setLayoutManager(lm);
29 | return rv;
30 | }
31 |
32 |
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/pullrefreshlayout/RefreshLayout.java:
--------------------------------------------------------------------------------
1 | package com.pullrefreshlayout;
2 |
3 | import android.content.Context;
4 | import android.graphics.Color;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.util.AttributeSet;
7 | import android.util.Log;
8 | import android.view.MotionEvent;
9 | import android.view.View;
10 | import android.view.ViewConfiguration;
11 | import android.view.ViewGroup;
12 | import android.view.animation.Animation;
13 | import android.view.animation.Transformation;
14 | import android.widget.ScrollView;
15 |
16 | /**
17 | * Created by 6a209 on 14/10/19.
18 | *
19 | * just support ScrollView & RecycleView
20 | *
21 | *
22 | */
23 | public abstract class RefreshLayout extends ViewGroup{
24 |
25 | private static final String TAG = "PullRefreshLayout";
26 |
27 | private static final int PULL_TO_REFRESH_STATUS = 0x00;
28 | private static final int RELEASE_TO_REFRESH_STATUS = 0x01;
29 | private static final int REFRESHING_STATUS = 0x02;
30 | private static final int NORMAL_STATUS = 0x03;
31 |
32 | private static final int RELEASE_TO_NORMAL = 0x0;
33 |
34 | private static final int DEFAULT_HEAD_HEIGHT = 200;
35 |
36 |
37 | View mRefreshView;
38 | View mRefreshHeaderView;
39 |
40 | // LinearLayout mContentLy;
41 |
42 | private int mCurStatus;
43 | private float mLastMotionY;
44 | private float mActionDownY;
45 | private float mTouchSlop;
46 | private boolean mIsBeingDragged;
47 | private int mHeaderViewHeight = DEFAULT_HEAD_HEIGHT;
48 | private int mMediumAnimationDuration;
49 |
50 | private int mToPosition;
51 | private int mOriginalOffsetTop;
52 | private int mLayoutOffsetTop = 0;
53 |
54 | /** the distance of refresh*/
55 | private int mNeedRefreshDeltaY = 120;
56 |
57 |
58 | OnRefreshListener mRefreshListener;
59 |
60 | public interface OnRefreshListener {
61 |
62 | /**
63 | * on pull down status
64 | * @param y
65 | */
66 | void onPullDown(float y);
67 |
68 | /**
69 | * on refreshing status
70 | */
71 | void onRefresh();
72 |
73 | /**
74 | * on refresh over on normal status
75 | *
76 | * i suggest in this callback refresh the view data;
77 | *
78 | */
79 | void onRefreshOver(Object obj);
80 | }
81 |
82 | public void setOnRefreshListener(OnRefreshListener listener){
83 | mRefreshListener = listener;
84 | }
85 |
86 | public RefreshLayout(Context context){
87 | this(context, null);
88 | }
89 |
90 | public RefreshLayout(Context context, AttributeSet attrs) {
91 | super(context, attrs);
92 | mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
93 | mMediumAnimationDuration = getResources().getInteger(android.R.integer.config_mediumAnimTime);
94 | mRefreshHeaderView = (View)createHeaderView();
95 | mRefreshHeaderView.setBackgroundColor(Color.parseColor("#FF0000"));
96 | addView(mRefreshHeaderView);
97 | mRefreshView = createRefreshView();
98 | addView(mRefreshView);
99 | mRefreshView.setFadingEdgeLength(0);
100 | mRefreshView.setOverScrollMode(View.OVER_SCROLL_NEVER);
101 | mCurStatus = NORMAL_STATUS;
102 | }
103 |
104 | public View getRefreshView(){
105 | return mRefreshView;
106 | }
107 |
108 | protected ILoadingLayout createHeaderView(){
109 | return new DefaultHeadView(getContext());
110 | }
111 |
112 | protected abstract View createRefreshView();
113 |
114 |
115 |
116 | @Override
117 | public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
118 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
119 | // Log.d("onMeasure", "onMeasure");
120 | // Log.d("heightMode", MeasureSpec.getMode(heightMeasureSpec) + "");
121 | // Log.d("heightSize", MeasureSpec.getSize(heightMeasureSpec) + "");
122 | // int headHeightSpec = MeasureSpec.makeMeasureSpec(mHeaderViewHeight, MeasureSpec.getMode(heightMeasureSpec));
123 | measureChildWithMargins(mRefreshHeaderView, widthMeasureSpec, 0, heightMeasureSpec, 0);
124 | MarginLayoutParams headLp = (MarginLayoutParams)mRefreshHeaderView.getLayoutParams();
125 | mHeaderViewHeight = mRefreshHeaderView.getMeasuredHeight() + headLp.bottomMargin + headLp.topMargin;
126 | // Log.d("the head height is => ", mHeaderViewHeight + "");
127 |
128 |
129 | MarginLayoutParams contentLp = (MarginLayoutParams)mRefreshView.getLayoutParams();
130 | int contentWidthSpec = getChildMeasureSpec(widthMeasureSpec, getPaddingLeft() + getPaddingRight() + contentLp.leftMargin + contentLp.rightMargin, contentLp.width);
131 | int contentHeightSpec = getChildMeasureSpec(heightMeasureSpec, getPaddingBottom() + getPaddingTop() + contentLp.topMargin + contentLp.bottomMargin, contentLp.height);
132 |
133 | // Log.d("heightSize", MeasureSpec.getSize(contentHeightSpec) + "");
134 | mRefreshView.measure(contentWidthSpec, contentHeightSpec);
135 | }
136 |
137 |
138 | @Override
139 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
140 | Log.d("onLayout", "onLayout");
141 |
142 |
143 | MarginLayoutParams headLp = (MarginLayoutParams)mRefreshHeaderView.getLayoutParams();
144 | int left = getPaddingLeft() + headLp.leftMargin;
145 | int top = getPaddingTop() + headLp.topMargin - mHeaderViewHeight + mLayoutOffsetTop;
146 | int right = left + mRefreshHeaderView.getMeasuredWidth();
147 | int bottom = top + mRefreshHeaderView.getMeasuredHeight();
148 |
149 | mRefreshHeaderView.layout(left, top, right, bottom);
150 |
151 |
152 | MarginLayoutParams contentLp = (MarginLayoutParams)mRefreshView.getLayoutParams();
153 | left = getPaddingLeft() + contentLp.leftMargin;
154 | top = contentLp.topMargin + mLayoutOffsetTop;
155 | right = left + mRefreshView.getMeasuredWidth();
156 | bottom = top + mRefreshView.getMeasuredHeight();
157 | mRefreshView.layout(left, top, right, bottom);
158 | }
159 |
160 |
161 | Animation mAnimateToPosition = new Animation() {
162 |
163 |
164 | @Override
165 | protected void applyTransformation(float interpolatedTime, Transformation t) {
166 | Log.d("Animation", "in=> Animation");
167 | final int curTop = getCurTop();
168 | if(mToPosition == curTop){
169 | return;
170 | }
171 | int toTop = (int) (mOriginalOffsetTop - (mOriginalOffsetTop - mToPosition) * interpolatedTime);
172 | if(toTop <= -mHeaderViewHeight){
173 | toTop = -mHeaderViewHeight;
174 | }
175 | int offset = toTop - curTop;
176 | setOffsetTopAndBottom(offset);
177 | }
178 | };
179 |
180 | public void setToRefreshing(){
181 | if(NORMAL_STATUS != mCurStatus) {
182 | return;
183 | }
184 | updateStatus(PULL_TO_REFRESH_STATUS);
185 | mAnimateToPosition.reset();
186 | mAnimateToPosition.setDuration(mMediumAnimationDuration);
187 | mToPosition = 0;
188 | mOriginalOffsetTop = getCurTop();
189 | startAnimation(mAnimateToPosition);
190 | mAnimateToPosition.setAnimationListener(new SimpleAnimationListener(){
191 | @Override
192 | public void onAnimationEnd(Animation animation){
193 |
194 | updateStatus(REFRESHING_STATUS);
195 | if(null != mRefreshListener){
196 | mRefreshListener.onRefresh();
197 | }
198 | }
199 | });
200 | }
201 |
202 |
203 | public void refreshOver(final Object obj){
204 | if(REFRESHING_STATUS != mCurStatus){
205 | return;
206 | }
207 | updateStatus(RELEASE_TO_NORMAL);
208 | mAnimateToPosition.reset();
209 | mAnimateToPosition.setDuration(mMediumAnimationDuration);
210 | mToPosition = -mHeaderViewHeight;
211 | mOriginalOffsetTop = getCurTop();
212 | startAnimation(mAnimateToPosition);
213 |
214 | mAnimateToPosition.setAnimationListener(new SimpleAnimationListener(){
215 | @Override
216 | public void onAnimationEnd(Animation animation) {
217 | updateStatus(NORMAL_STATUS);
218 | if(null != mRefreshListener){
219 | mRefreshListener.onRefreshOver(obj);
220 | }
221 | }
222 | });
223 | }
224 |
225 |
226 | @Override
227 | public boolean onInterceptTouchEvent(MotionEvent ev){
228 | Log.d("on intercept ", "****");
229 | if(!childIsOnTop()){
230 | return super.onInterceptTouchEvent(ev);
231 | }
232 |
233 | final int action = ev.getAction();
234 |
235 | switch (action){
236 | case MotionEvent.ACTION_DOWN:
237 | mLastMotionY = mActionDownY = ev.getY();
238 | mIsBeingDragged = false;
239 | break;
240 | case MotionEvent.ACTION_MOVE:
241 | final float y = ev.getY();
242 | final float yDiff = y - mActionDownY;
243 | if(yDiff > mTouchSlop){
244 | mLastMotionY = y;
245 | mIsBeingDragged = true;
246 | }
247 | break;
248 |
249 | case MotionEvent.ACTION_UP:
250 | case MotionEvent.ACTION_CANCEL:
251 |
252 | Log.d("******", "up or cancel");
253 | mIsBeingDragged = false;
254 | break;
255 | }
256 |
257 | if(mIsBeingDragged){
258 | return true;
259 | }else{
260 | return super.onInterceptTouchEvent(ev);
261 | }
262 | };
263 |
264 |
265 | @Override
266 | public boolean onTouchEvent(MotionEvent ev){
267 |
268 | final int aciont = ev.getAction();
269 | if(!childIsOnTop()){
270 | return super.onTouchEvent(ev);
271 | }
272 |
273 | switch (aciont){
274 | case MotionEvent.ACTION_DOWN:
275 | Log.d("on touche down", "****");
276 | mLastMotionY = mActionDownY = ev.getY();
277 | mIsBeingDragged = false;
278 | break;
279 | case MotionEvent.ACTION_MOVE:
280 | final float y = ev.getY();
281 | final float yDiff = y - mLastMotionY;
282 |
283 |
284 | Log.d("y && ydiff", y + " __ " + yDiff);
285 | Log.d("mIsBeginDra" , mIsBeingDragged + "");
286 |
287 | if(!mIsBeingDragged && yDiff > mTouchSlop){
288 | mIsBeingDragged = true;
289 | }
290 | int curTop = getCurTop();
291 | Log.d("curTop", curTop + "");
292 | if(curTop <= -mHeaderViewHeight && yDiff < 0 ){
293 | mIsBeingDragged = false;
294 | }
295 |
296 | if(mCurStatus == REFRESHING_STATUS){
297 | mIsBeingDragged = false;
298 | }
299 | if(mIsBeingDragged){
300 |
301 | float offset = yDiff / 2;
302 | if(offset < 0 && curTop + offset <= -mHeaderViewHeight){
303 | offset = -mHeaderViewHeight - curTop;
304 | }
305 |
306 | Log.d("isDragged", offset + "");
307 | setOffsetTopAndBottom((int) (offset));
308 | if(mRefreshListener != null){
309 | mRefreshListener.onPullDown(y);
310 | }
311 | if(mCurStatus != REFRESHING_STATUS){
312 | if(curTop >= mNeedRefreshDeltaY){
313 | updateStatus(RELEASE_TO_REFRESH_STATUS);
314 | }else if(curTop > -mHeaderViewHeight && curTop < mNeedRefreshDeltaY){
315 | updateStatus(PULL_TO_REFRESH_STATUS);
316 | }else{
317 | updateStatus(NORMAL_STATUS);
318 | }
319 | }
320 | mLastMotionY = y;
321 | }
322 | break;
323 |
324 | case MotionEvent.ACTION_UP:
325 | case MotionEvent.ACTION_CANCEL:
326 |
327 | Log.d("on touche up or cancel", "****");
328 | handleRelease();
329 |
330 | break;
331 | default:
332 | break;
333 | }
334 | if(mIsBeingDragged){
335 | return true;
336 | }else{
337 | return super.onTouchEvent(ev);
338 | }
339 | }
340 |
341 | private int getCurTop(){
342 | return mRefreshHeaderView.getTop();
343 | }
344 |
345 |
346 |
347 | private void setOffsetTopAndBottom(int offset){
348 | // offsetTopAndBottom(offset);
349 | mLayoutOffsetTop = mHeaderViewHeight + getCurTop();
350 | mRefreshHeaderView.offsetTopAndBottom(offset);
351 | mRefreshView.offsetTopAndBottom(offset);
352 | invalidate();
353 | }
354 |
355 |
356 | private void handleRelease(){
357 | int toPostion;
358 | if(RELEASE_TO_REFRESH_STATUS == mCurStatus){
359 | toPostion = 0;
360 | }else if(PULL_TO_REFRESH_STATUS == mCurStatus){
361 | toPostion = -mHeaderViewHeight;
362 | updateStatus(RELEASE_TO_NORMAL);
363 | }else {
364 | return;
365 | }
366 | mAnimateToPosition.reset();
367 | mAnimateToPosition.setDuration(mMediumAnimationDuration);
368 | mToPosition = toPostion;
369 | mOriginalOffsetTop = getCurTop();
370 | mAnimateToPosition.setAnimationListener(new SimpleAnimationListener(){
371 | @Override
372 | public void onAnimationEnd(Animation animation) {
373 | if(RELEASE_TO_NORMAL == mCurStatus){
374 | updateStatus(NORMAL_STATUS);
375 | }else if(RELEASE_TO_REFRESH_STATUS == mCurStatus){
376 | updateStatus(REFRESHING_STATUS);
377 | if(null != mRefreshListener){
378 | mRefreshListener.onRefresh();
379 | }
380 | }
381 |
382 | }
383 | });
384 | startAnimation(mAnimateToPosition);
385 | }
386 |
387 | private static class SimpleAnimationListener implements Animation.AnimationListener{
388 |
389 | @Override
390 | public void onAnimationStart(Animation animation) {
391 |
392 | }
393 |
394 | @Override
395 | public void onAnimationEnd(Animation animation) {
396 |
397 | }
398 |
399 | @Override
400 | public void onAnimationRepeat(Animation animation) {
401 |
402 | }
403 | }
404 |
405 |
406 | /**
407 | * update the pull status
408 | * @param status
409 | */
410 | private void updateStatus(int status){
411 | if(mCurStatus == status){
412 | return;
413 | }
414 |
415 | mCurStatus = status;
416 | switch (mCurStatus){
417 | case PULL_TO_REFRESH_STATUS:
418 | ((ILoadingLayout)mRefreshHeaderView).pullToRefresh();
419 | break;
420 | case RELEASE_TO_REFRESH_STATUS:
421 | ((ILoadingLayout)mRefreshHeaderView).releaseToRefresh();
422 | break;
423 | case REFRESHING_STATUS:
424 | ((ILoadingLayout)mRefreshHeaderView).refreshing();
425 | break;
426 | case NORMAL_STATUS:
427 | ((ILoadingLayout)mRefreshHeaderView).normal();
428 | break;
429 | default:
430 | break;
431 | }
432 |
433 | }
434 |
435 | protected boolean childIsOnTop(){
436 | if(mRefreshView instanceof ScrollView){
437 | return mRefreshView.getScrollY() <= 0;
438 | }else if(mRefreshView instanceof RecyclerView){
439 | RecyclerView recyclerView = (RecyclerView) mRefreshView;
440 | View child = recyclerView.getChildAt(0);
441 | if(null != child){
442 | return child.getTop() >= 0;
443 | }
444 | // RecycleView
445 | return false;
446 | }else {
447 | return false;
448 | }
449 | }
450 |
451 |
452 |
453 |
454 | @Override
455 | protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
456 | return p instanceof LayoutParams;
457 | }
458 | @Override
459 | protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
460 | return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
461 | }
462 | @Override
463 | protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
464 | return new LayoutParams(p);
465 | }
466 | @Override
467 | public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
468 | return new LayoutParams(getContext(), attrs);
469 | }
470 |
471 |
472 |
473 | public static class LayoutParams extends MarginLayoutParams {
474 | public LayoutParams(Context c, AttributeSet attrs) {
475 | super(c, attrs);
476 | }
477 | public LayoutParams(int width, int height) {
478 | super(width, height);
479 | }
480 | public LayoutParams(MarginLayoutParams source) {
481 | super(source);
482 | }
483 | public LayoutParams(ViewGroup.LayoutParams source) {
484 | super(source);
485 | }
486 | }
487 | }
488 |
--------------------------------------------------------------------------------
/lib/src/main/java/com/pullrefreshlayout/WaterfallRecyclerView.java:
--------------------------------------------------------------------------------
1 | package com.pullrefreshlayout;
2 |
3 | /**
4 | * Created by 6a209 on 14/11/9.
5 | */
6 | public class WaterfallRecyclerView {
7 | }
8 |
--------------------------------------------------------------------------------
/lib/src/main/res/anim/down_to_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
--------------------------------------------------------------------------------
/lib/src/main/res/anim/up_to_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/lib/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/lib/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/lib/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-xhdpi/pulltorefresh_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/lib/src/main/res/drawable-xhdpi/pulltorefresh_arrow.png
--------------------------------------------------------------------------------
/lib/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/lib/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/src/main/res/layout/head_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
14 |
15 |
21 |
22 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/lib/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 下拉刷新
5 | 刷新中...
6 | 松手刷新
7 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | PullRefreshLayout
3 | pull to refresh
4 | refreshing...
5 | release to refresh
6 |
7 |
--------------------------------------------------------------------------------
/lib/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/recyclerview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/recyclerview.gif
--------------------------------------------------------------------------------
/scrollview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/6a209/PullRefreshLayout/74c6ca3432b26d87c11deff15c6c2482c904850b/scrollview.gif
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':lib', ':demo'
2 |
--------------------------------------------------------------------------------