├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── LICENSE.txt
├── README.md
├── README_CN.md
├── TODO_list.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── lcodecore
│ │ └── twinklingrefreshlayout
│ │ ├── BaseActivity.java
│ │ ├── CoordinateActivity.java
│ │ ├── FoodActivity.java
│ │ ├── MainActivity.java
│ │ ├── MusicActivity.java
│ │ ├── NestedLayoutActivity.java
│ │ ├── NormalViewActivity.java
│ │ ├── PhotoActivity.java
│ │ ├── ScienceActivity.java
│ │ ├── StoryActivity.java
│ │ ├── TestActivity.java
│ │ ├── TextHeaderView.java
│ │ ├── TkApplication.java
│ │ ├── WebActivity.java
│ │ ├── adapter
│ │ ├── FoodAdapter.java
│ │ ├── LoopViewPagerAdapter.java
│ │ ├── MusicAdapter.java
│ │ ├── PhotoAdapter.java
│ │ ├── ScienceAdapter.java
│ │ ├── ViewPagerHolder.java
│ │ └── base
│ │ │ ├── BaseLoopPagerAdapter.java
│ │ │ ├── BaseRecyclerAdapter.java
│ │ │ ├── CommonAdapter.java
│ │ │ └── CommonHolder.java
│ │ ├── beans
│ │ ├── Card.java
│ │ ├── Food.java
│ │ └── Photo.java
│ │ ├── utils
│ │ ├── DensityUtil.java
│ │ └── ToastUtil.java
│ │ └── views
│ │ └── CircleImageView.java
│ └── res
│ ├── drawable-xhdpi
│ ├── arrow.png
│ ├── avatar0.jpg
│ ├── avatar1.jpg
│ ├── avatar2.jpg
│ ├── avatar3.jpg
│ ├── avatar4.jpg
│ ├── avatar5.jpg
│ ├── avatar6.jpg
│ ├── avatar7.jpg
│ ├── avatar8.jpg
│ ├── avatar9.jpg
│ ├── back.png
│ ├── back_dark.png
│ ├── back_pink.png
│ ├── back_white.png
│ ├── food1.jpg
│ ├── food2.jpg
│ ├── food3.jpg
│ ├── food4.jpg
│ ├── food5.jpg
│ ├── map.png
│ ├── pager_bg.png
│ ├── photo1.jpg
│ ├── photo10.jpg
│ ├── photo2.jpg
│ ├── photo3.jpg
│ ├── photo4.jpg
│ ├── photo5.jpg
│ ├── photo6.jpg
│ ├── photo7.jpg
│ ├── photo8.jpg
│ ├── photo9.jpg
│ ├── play.png
│ ├── play_white.png
│ ├── science1.png
│ ├── science10.png
│ ├── science2.png
│ ├── science3.png
│ ├── science4.png
│ ├── science5.png
│ ├── science6.png
│ ├── science7.png
│ ├── science8.png
│ ├── science9.png
│ └── wave.png
│ ├── drawable-xxhdpi
│ └── ic_create_white_36dp.png
│ ├── drawable
│ ├── bg_wood.png
│ └── selector_indicator.xml
│ ├── layout
│ ├── activity_coordinate.xml
│ ├── activity_food.xml
│ ├── activity_main.xml
│ ├── activity_music.xml
│ ├── activity_nested_layout.xml
│ ├── activity_normalview.xml
│ ├── activity_photo.xml
│ ├── activity_science.xml
│ ├── activity_story.xml
│ ├── activity_test.xml
│ ├── activity_web.xml
│ ├── content_main.xml
│ ├── header_music.xml
│ ├── header_tv.xml
│ ├── inc_toolbar.xml
│ ├── item_food.xml
│ ├── item_music.xml
│ ├── item_photo.xml
│ ├── item_science.xml
│ ├── item_viewpager.xml
│ └── layout_viewpager.xml
│ ├── mipmap-hdpi
│ └── ic_launcher.png
│ ├── mipmap-mdpi
│ └── ic_launcher.png
│ ├── mipmap-xhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxhdpi
│ └── ic_launcher.png
│ ├── mipmap-xxxhdpi
│ └── ic_launcher.png
│ ├── values-w820dp
│ └── dimens.xml
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── art
├── alipay.jpg
├── app-debug.apk
├── gif2.gif
├── gif_gridview.gif
├── gif_gridview.mp4
├── gif_listview.gif
├── gif_listview.mp4
├── gif_recyclerview.gif
├── gif_recyclerview.mp4
├── gif_recyclerview2.gif
├── gif_recyclerview2.mp4
├── gif_scrollview.gif
├── gif_scrollview.mp4
├── gif_webview.gif
├── gif_webview.mp4
├── pic_large.png
├── structure_v1.0.png
└── wepay.png
├── build.gradle
├── introduction.md
├── library
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── lcodecore
│ │ └── tkrefreshlayout
│ │ ├── Footer
│ │ ├── BallPulseView.java
│ │ └── LoadingView.java
│ │ ├── IBottomView.java
│ │ ├── IHeaderView.java
│ │ ├── OnAnimEndListener.java
│ │ ├── OnGestureListener.java
│ │ ├── PullListener.java
│ │ ├── RefreshListenerAdapter.java
│ │ ├── TwinklingRefreshLayout.java
│ │ ├── header
│ │ ├── GoogleDotView.java
│ │ ├── SinaRefreshView.java
│ │ ├── bezierlayout
│ │ │ ├── BezierLayout.java
│ │ │ ├── RippleView.java
│ │ │ ├── RoundDotView.java
│ │ │ ├── RoundProgressView.java
│ │ │ └── WaveView.java
│ │ └── progresslayout
│ │ │ ├── CircleImageView.java
│ │ │ ├── MaterialProgressDrawable.java
│ │ │ └── ProgressLayout.java
│ │ ├── processor
│ │ ├── AnimProcessor.java
│ │ ├── Decorator.java
│ │ ├── IAnimOverScroll.java
│ │ ├── IAnimRefresh.java
│ │ ├── IDecorator.java
│ │ ├── OverScrollDecorator.java
│ │ └── RefreshProcessor.java
│ │ └── utils
│ │ ├── DensityUtil.java
│ │ ├── LogUtil.java
│ │ └── ScrollingUtil.java
│ └── res
│ ├── drawable-xhdpi
│ └── ic_arrow.png
│ ├── drawable
│ └── anim_loading_view.xml
│ ├── layout
│ ├── view_bezier.xml
│ └── view_sinaheader.xml
│ ├── mipmap-hdpi
│ ├── refresh_head_arrow.png
│ ├── refresh_loading01.png
│ ├── refresh_loading02.png
│ ├── refresh_loading03.png
│ ├── refresh_loading04.png
│ ├── refresh_loading05.png
│ ├── refresh_loading06.png
│ ├── refresh_loading07.png
│ ├── refresh_loading08.png
│ ├── refresh_loading09.png
│ ├── refresh_loading10.png
│ ├── refresh_loading11.png
│ └── refresh_loading12.png
│ └── values
│ ├── attrs.xml
│ ├── colors.xml
│ ├── ids.xml
│ └── strings.xml
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 | gradle*
9 | /TODO_list.md
10 |
11 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/TODO_list.md:
--------------------------------------------------------------------------------
1 | # v1.07开发计划
2 | - 华为7.0 P9奔溃问题
3 | - setFloatRefresh(true)下拉刷新不可见问题 --View添加顺序的问题 **done**
4 | - 确认item点击失效问题是否解决
5 | - header添加时机的空指针和不显示问题 --去掉post **done**
6 | - 提供设置默认header、footer的方法 **done**
7 | - 频繁设置禁止下拉和加载失效问题?(增加RefreshMode类)
8 | - fixedHeader ontouch事件无响应,需手动设置clickable=true
9 | - setOverScrollTopShow(false)/setOverScrollBottomShow(false)/setOverScrollRefreshShow(false) 设置无效 **done**
10 | - 兼容nestedscroll
11 | - 状态保持问题
12 | - onFinishRefresh不回调问题
13 | - 刷新时禁止加载更多,去加载更多底部空白没回去
14 | - 空白View下拉无效
15 | - 不停下拉导致head悬浮
16 | - 测试autoLoadMore
17 |
18 |
19 | # v1.06开发计划
20 | ## 存在的问题
21 | 1. 三星、酷派手机的兼容问题
22 | 2. 依赖太旧的问题->选择去除依赖还是更新依赖 **done** 已去除依赖
23 | 3. 自动刷新动画生硬 todo 问题待验证
24 | 4. 加载更多闪烁问题 **done** 做了优化
25 | 5. layout_behavior支持问题 添加了Demo但未完成任何逻辑处理
26 | 6. 是否要支持ViewPager回弹问题 TODO
27 | 7. 是否要支持所有的View TODO 不能滑动NormalView是因为没有焦点的原因(需手动设置),暂时不考虑支持
28 | 8. 测试事件监听冲突问题 理论上修改后已经不存在这个问题 **done**
29 | 9. 内存泄漏问题 -> 解决ValueAnimator潜在的内存泄漏问题;WebView内存泄漏问题;**done**
30 | 10. 仿QQ视差效果
31 | 11. 测试加载更多后不添加数据 **done**
32 | 12. 考虑是否要给Loadmore添加完成延时
33 | 13. FixedHeader问题
34 | 14. 多点触摸处理
35 | 15. 控制底部下拉后或者顶部上拉后再次进入动画可以保持!
36 | 16. Refresh和OverScroll的开关耦合问题,即禁用loadmore后OverScroll不可用问题 **done**
37 | 17. 测试自动加载更多功能是否正常 **done**正常
38 |
39 | ## 新发现的问题
40 | 1. beizierlayout主动调用刷新时会一片白 todo
41 | 2. BallPulseView引入了内存泄漏 **done**
42 | 3. 新的方案,怎么让scroll更平滑;计算Footer降低与TargetView显示距离是否一致:结论,一致,问题在每次滚动的距离上 **done**
43 | 4. requestLayout时提示 **improperly called by android.support.v7.widget.AppCompatTextView**
44 | 5. WebView上拉不起作用 **done**
45 | 6. 修改IBottomView中的参数错误,增加max_head_height,max_bottom_height属性;修改setWaveHeight方法为setMaxHeadHeight,增加setMaxBottomHeight方法 **done**
46 | 7. 在最顶部或最底部时fling会多次反弹 **done**(解决办法,在最顶端fling时不响应动作)
47 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion '25.0.1'
6 | defaultConfig {
7 | applicationId 'com.lcodecore.twinklingrefreshlayout'
8 | minSdkVersion 14
9 | targetSdkVersion 22
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 | productFlavors {
20 | }
21 | lintOptions {
22 | abortOnError false
23 | }
24 | }
25 |
26 | dependencies {
27 | compile fileTree(include: ['*.jar'], dir: 'libs')
28 | compile 'com.android.support:design:25.2.0'
29 | compile project(':library')
30 | compile 'com.android.support:appcompat-v7:25.2.0'
31 | compile 'com.android.support:cardview-v7:25.2.0'
32 | compile 'com.jakewharton:butterknife:7.0.1'
33 | compile 'com.squareup.leakcanary:leakcanary-android:1.5'
34 | compile 'com.github.moduth:blockcanary-android:1.2.1'
35 | }
36 |
--------------------------------------------------------------------------------
/app/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/lcodecore/Documents/android_sdk_macosx/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 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.View;
8 |
9 | /**
10 | * Created by lcodecore on 16/3/2.
11 | */
12 | public abstract class BaseActivity extends AppCompatActivity {
13 |
14 | @Override
15 | protected void onCreate(@Nullable Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(setInflateId());
18 | init();
19 | initAcition();
20 | }
21 |
22 | //设置布局id
23 | public abstract int setInflateId();
24 |
25 | //视图,组件,数据的初始化
26 | public abstract void init();
27 |
28 | //事件监听
29 | public void initAcition(){}
30 |
31 | //Activity设置带返回按钮的Toolbar
32 | public void setupBackToolbar(String title){
33 | setupBackToolbar(R.id.toolbar,title);
34 | }
35 |
36 | public void setupBackToolbar(int toolbarId,String title){
37 | Toolbar mToolbar = (Toolbar) findViewById(toolbarId);
38 | setSupportActionBar(mToolbar);
39 | getSupportActionBar().setHomeButtonEnabled(true); //显示小箭头
40 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
41 | mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
42 | @Override
43 | public void onClick(View v) {
44 | onBackPressed();
45 | }
46 | });
47 | setTitle(title);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/CoordinateActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.support.design.widget.AppBarLayout;
6 | import android.support.v7.app.AppCompatActivity;
7 | import android.support.v7.widget.RecyclerView;
8 | import android.support.v7.widget.StaggeredGridLayoutManager;
9 | import android.view.WindowManager;
10 |
11 | import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
12 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
13 | import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
14 | import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAdapter;
15 | import com.lcodecore.twinklingrefreshlayout.beans.Photo;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | /**
21 | * Created by lcodecore on 2017/3/8.
22 | */
23 |
24 | public class CoordinateActivity extends AppCompatActivity {
25 | private PhotoAdapter photoAdapter;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_coordinate);
31 |
32 | setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
33 |
34 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
35 | }
36 |
37 | private void setupRecyclerView(RecyclerView rv) {
38 | rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
39 | photoAdapter = new PhotoAdapter();
40 | rv.setAdapter(photoAdapter);
41 |
42 | final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
43 | ProgressLayout header = new ProgressLayout(this);
44 | refreshLayout.setHeaderView(header);
45 | refreshLayout.setFloatRefresh(true);
46 | refreshLayout.setEnableOverScroll(false);
47 | refreshLayout.setHeaderHeight(140);
48 | refreshLayout.setMaxHeadHeight(240);
49 | refreshLayout.setTargetView(rv);
50 |
51 | refreshCard();
52 |
53 | refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
54 | @Override
55 | public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
56 | new Handler().postDelayed(new Runnable() {
57 | @Override
58 | public void run() {
59 | refreshCard();
60 | refreshLayout.finishRefreshing();
61 | }
62 | }, 2000);
63 | }
64 |
65 | @Override
66 | public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
67 | new Handler().postDelayed(new Runnable() {
68 | @Override
69 | public void run() {
70 | loadMoreCard();
71 | refreshLayout.finishLoadmore();
72 | }
73 | }, 2000);
74 | }
75 | });
76 |
77 | AppBarLayout appBarLayout = (AppBarLayout) findViewById(R.id.appbar_layout);
78 | appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
79 | @Override
80 | public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
81 | if (verticalOffset >= 0) {
82 | refreshLayout.setEnableRefresh(true);
83 | refreshLayout.setEnableOverScroll(false);
84 | } else {
85 | refreshLayout.setEnableRefresh(false);
86 | refreshLayout.setEnableOverScroll(false);
87 | }
88 | }
89 | });
90 | }
91 |
92 | void refreshCard() {
93 | List photos = new ArrayList<>();
94 | photos.add(new Photo("chest nut", R.drawable.photo1));
95 | photos.add(new Photo("fish", R.drawable.photo2));
96 | photos.add(new Photo("cat", R.drawable.photo10));
97 | photos.add(new Photo("guitar", R.drawable.photo3));
98 | photos.add(new Photo("common-hazel", R.drawable.photo4));
99 | photos.add(new Photo("cherry", R.drawable.photo5));
100 | photos.add(new Photo("flower details", R.drawable.photo6));
101 | photos.add(new Photo("tree", R.drawable.photo7));
102 | photos.add(new Photo("blue berries", R.drawable.photo8));
103 | photos.add(new Photo("snow man", R.drawable.photo9));
104 | photoAdapter.setDataList(photos);
105 | }
106 |
107 | void loadMoreCard() {
108 | List photos = new ArrayList<>();
109 | photos.add(new Photo("chest nut", R.drawable.photo1));
110 | photos.add(new Photo("fish", R.drawable.photo2));
111 | photos.add(new Photo("cat", R.drawable.photo10));
112 | photos.add(new Photo("guitar", R.drawable.photo3));
113 | photos.add(new Photo("common-hazel", R.drawable.photo4));
114 | photos.add(new Photo("cherry", R.drawable.photo5));
115 | photos.add(new Photo("flower details", R.drawable.photo6));
116 | photos.add(new Photo("tree", R.drawable.photo7));
117 | photos.add(new Photo("blue berries", R.drawable.photo8));
118 | photos.add(new Photo("snow man", R.drawable.photo9));
119 | photoAdapter.addItems(photos);
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/FoodActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.support.v7.widget.LinearLayoutManager;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.view.View;
8 | import android.view.WindowManager;
9 |
10 | import com.lcodecore.tkrefreshlayout.header.bezierlayout.BezierLayout;
11 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
12 | import com.lcodecore.twinklingrefreshlayout.adapter.FoodAdapter;
13 | import com.lcodecore.twinklingrefreshlayout.beans.Food;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 |
18 | public class FoodActivity extends AppCompatActivity {
19 |
20 | private FoodAdapter foodAdapter;
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_food);
26 | setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
27 |
28 | findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
29 | @Override
30 | public void onClick(View v) {
31 | finish();
32 | }
33 | });
34 |
35 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
36 | }
37 |
38 | private void setupRecyclerView(RecyclerView rv) {
39 | rv.setLayoutManager(new LinearLayoutManager(rv.getContext()));
40 | foodAdapter = new FoodAdapter();
41 | rv.setAdapter(foodAdapter);
42 |
43 | final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
44 | // ProgressLayout headerView = new ProgressLayout(getContext());
45 | BezierLayout headerView = new BezierLayout(this);
46 | refreshLayout.setHeaderView(headerView);
47 | // refreshLayout.setFloatRefresh(false);
48 | refreshLayout.setPureScrollModeOn();
49 | // refreshLayout.setEnableOverlayRefreshView(false);
50 | // refreshLayout.setAutoLoadMore(true);
51 |
52 | refreshCard();
53 |
54 | }
55 |
56 | void refreshCard() {
57 | List foods = new ArrayList<>();
58 | foods.add(new Food("Preparing Salmon Steak Close Up", "BY VIKTOR HANACEK", R.drawable.food1, R.drawable.avatar0));
59 | foods.add(new Food("Fresh & Healthy Fitness Broccoli Pie with Basil", "BY VIKTOR HANACEK", R.drawable.food2, R.drawable.avatar1));
60 | foods.add(new Food("Enjoying a Tasty Burger", "BY VIKTOR HANACEK", R.drawable.food3, R.drawable.avatar2));
61 | foods.add(new Food("Fresh Strawberries and Blackberries in Little Bowl", "BY VIKTOR HANACEK", R.drawable.food4, R.drawable.avatar3));
62 | foods.add(new Food("Baked Healthy Fitness Broccoli Pie with Basil", "BY VIKTOR HANACEK", R.drawable.food5, R.drawable.avatar4));
63 | foodAdapter.setDataList(foods);
64 | }
65 |
66 | void loadMoreCard() {
67 | List foods = new ArrayList<>();
68 | // foods.add(new Food(R.drawable.food3));
69 | // foods.add(new Food(R.drawable.food2));
70 | // foods.add(new Food(R.drawable.food1));
71 | foodAdapter.addItems(foods);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.content.Intent;
4 | import android.support.v7.widget.Toolbar;
5 | import android.view.View;
6 |
7 | public class MainActivity extends BaseActivity implements View.OnClickListener {
8 |
9 | @Override
10 | public int setInflateId() {
11 | return R.layout.activity_main;
12 | }
13 |
14 | @Override
15 | public void init() {
16 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
17 | setSupportActionBar(toolbar);
18 | findViewById(R.id.bt_music).setOnClickListener(this);
19 | findViewById(R.id.bt_food).setOnClickListener(this);
20 | findViewById(R.id.bt_science).setOnClickListener(this);
21 | findViewById(R.id.bt_photo).setOnClickListener(this);
22 | findViewById(R.id.bt_story).setOnClickListener(this);
23 | findViewById(R.id.bt_enjoy).setOnClickListener(this);
24 | findViewById(R.id.bt_coordinate).setOnClickListener(this);
25 | findViewById(R.id.bt_test).setOnClickListener(this);
26 | findViewById(R.id.bt_normalView).setOnClickListener(this);
27 | }
28 |
29 | @Override
30 | public void onClick(View v) {
31 | switch (v.getId()) {
32 | case R.id.bt_music:
33 | startActivity(new Intent(MainActivity.this, MusicActivity.class));
34 | break;
35 | case R.id.bt_food:
36 | startActivity(new Intent(MainActivity.this, FoodActivity.class));
37 | break;
38 | case R.id.bt_science:
39 | startActivity(new Intent(MainActivity.this, ScienceActivity.class));
40 | break;
41 | case R.id.bt_photo:
42 | startActivity(new Intent(MainActivity.this, PhotoActivity.class));
43 | break;
44 | case R.id.bt_story:
45 | startActivity(new Intent(MainActivity.this, StoryActivity.class));
46 | break;
47 | case R.id.bt_enjoy:
48 | startActivity(new Intent(MainActivity.this, WebActivity.class));
49 | break;
50 | case R.id.bt_coordinate:
51 | startActivity(new Intent(MainActivity.this,CoordinateActivity.class));
52 | break;
53 | case R.id.bt_normalView:
54 | startActivity(new Intent(MainActivity.this,NormalViewActivity.class));
55 | break;
56 | case R.id.bt_test:
57 | startActivity(new Intent(MainActivity.this,TestActivity.class));
58 | break;
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/MusicActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.Toolbar;
7 | import android.view.View;
8 | import android.widget.AdapterView;
9 | import android.widget.ListView;
10 |
11 | import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
12 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
13 | import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
14 | import com.lcodecore.twinklingrefreshlayout.adapter.MusicAdapter;
15 | import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
16 |
17 | //TODO 有FixedHeader的界面fling有问题
18 | public class MusicActivity extends AppCompatActivity {
19 |
20 | private MusicAdapter adapter;
21 |
22 | @Override
23 | protected void onCreate(Bundle savedInstanceState) {
24 | super.onCreate(savedInstanceState);
25 | setContentView(R.layout.activity_music);
26 |
27 | Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
28 | mToolbar.setNavigationIcon(R.drawable.back);
29 | mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
30 | @Override
31 | public void onClick(View v) {
32 | finish();
33 | }
34 | });
35 |
36 | setupListView((ListView) findViewById(R.id.listView));
37 | }
38 |
39 | private void setupListView(ListView listView) {
40 | TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
41 | ProgressLayout headerView = new ProgressLayout(this);
42 | refreshLayout.setHeaderView(headerView);
43 | View exHeader = View.inflate(this, R.layout.header_music, null);
44 | refreshLayout.addFixedExHeader(exHeader);
45 | refreshLayout.setOverScrollRefreshShow(false);
46 | // refreshLayout.setFloatRefresh(true);
47 | adapter = new MusicAdapter();
48 | listView.setAdapter(adapter);
49 | adapter.refreshCard();
50 |
51 | exHeader.setOnClickListener(new View.OnClickListener() {
52 | @Override
53 | public void onClick(View v) {
54 | ToastUtil.show("fixed header clicked!");
55 | }
56 | });
57 |
58 | listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
59 | @Override
60 | public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
61 | ToastUtil.show("item clicked!");
62 | }
63 | });
64 |
65 | refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
66 | @Override
67 | public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
68 | new Handler().postDelayed(new Runnable() {
69 | @Override
70 | public void run() {
71 | adapter.refreshCard();
72 | refreshLayout.finishRefreshing();
73 | }
74 | }, 2000);
75 | }
76 |
77 | @Override
78 | public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
79 | new Handler().postDelayed(new Runnable() {
80 | @Override
81 | public void run() {
82 | adapter.loadMoreCard();
83 | refreshLayout.finishLoadmore();
84 | }
85 | }, 2000);
86 | }
87 | });
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NestedLayoutActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.support.v7.widget.StaggeredGridLayoutManager;
8 | import android.view.View;
9 | import android.view.WindowManager;
10 |
11 | import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
12 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
13 | import com.lcodecore.tkrefreshlayout.header.bezierlayout.BezierLayout;
14 | import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAdapter;
15 | import com.lcodecore.twinklingrefreshlayout.beans.Photo;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | /**
21 | * Created by lcodecore on 2017/3/4.
22 | */
23 |
24 | public class NestedLayoutActivity extends AppCompatActivity {
25 | private PhotoAdapter photoAdapter;
26 |
27 | @Override
28 | protected void onCreate(Bundle savedInstanceState) {
29 | super.onCreate(savedInstanceState);
30 | setContentView(R.layout.activity_nested_layout);
31 |
32 | setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
33 |
34 | findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
35 | @Override
36 | public void onClick(View v) {
37 | finish();
38 | }
39 | });
40 |
41 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
42 | }
43 |
44 | private void setupRecyclerView(RecyclerView rv) {
45 | rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
46 | photoAdapter = new PhotoAdapter();
47 | rv.setAdapter(photoAdapter);
48 |
49 | final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
50 | // ProgressLayout headerView = new ProgressLayout(this);
51 | BezierLayout headerView = new BezierLayout(this);
52 | refreshLayout.setHeaderView(headerView);
53 | refreshLayout.setMaxHeadHeight(140);
54 | // refreshLayout.setFloatRefresh(true);
55 | // refreshLayout.setPureScrollModeOn(true);
56 | refreshLayout.setOverScrollBottomShow(false);
57 | refreshLayout.setTargetView(rv);
58 | // refreshLayout.setAutoLoadMore(true);
59 |
60 | // addHeader();
61 | refreshCard();
62 |
63 |
64 | refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
65 | @Override
66 | public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
67 | new Handler().postDelayed(new Runnable() {
68 | @Override
69 | public void run() {
70 | refreshCard();
71 | refreshLayout.finishRefreshing();
72 | }
73 | }, 2000);
74 | }
75 |
76 | @Override
77 | public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
78 | new Handler().postDelayed(new Runnable() {
79 | @Override
80 | public void run() {
81 | loadMoreCard();
82 | refreshLayout.finishLoadmore();
83 | }
84 | }, 2000);
85 | }
86 | });
87 |
88 | // refreshLayout.startRefresh();
89 | }
90 |
91 | void refreshCard() {
92 | List photos = new ArrayList<>();
93 | // foods.add(new Food("Preparing Salmon Steak Close Up","BY VIKTOR HANACEK",R.drawable.food1,R.drawable.avatar0));
94 | // foods.add(new Food("Fresh & Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food2,R.drawable.avatar1));
95 | // foods.add(new Food("Enjoying a Tasty Burger","BY VIKTOR HANACEK",R.drawable.food3,R.drawable.avatar2));
96 | // foods.add(new Food("Fresh Strawberries and Blackberries in Little Bowl","BY VIKTOR HANACEK",R.drawable.food4,R.drawable.avatar3));
97 | // foods.add(new Food("Baked Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food5,R.drawable.avatar4));
98 | photos.add(new Photo("chest nut", R.drawable.photo1));
99 | photos.add(new Photo("fish", R.drawable.photo2));
100 | photos.add(new Photo("cat", R.drawable.photo10));
101 | photos.add(new Photo("guitar", R.drawable.photo3));
102 | photos.add(new Photo("common-hazel", R.drawable.photo4));
103 | photos.add(new Photo("cherry", R.drawable.photo5));
104 | photos.add(new Photo("flower details", R.drawable.photo6));
105 | photos.add(new Photo("tree", R.drawable.photo7));
106 | photos.add(new Photo("blue berries", R.drawable.photo8));
107 | photos.add(new Photo("snow man", R.drawable.photo9));
108 | photoAdapter.setDataList(photos);
109 | }
110 |
111 | void loadMoreCard() {
112 | List photos = new ArrayList<>();
113 | photos.add(new Photo("chest nut", R.drawable.photo1));
114 | photos.add(new Photo("fish", R.drawable.photo2));
115 | photos.add(new Photo("cat", R.drawable.photo10));
116 | photos.add(new Photo("guitar", R.drawable.photo3));
117 | photos.add(new Photo("common-hazel", R.drawable.photo4));
118 | photos.add(new Photo("cherry", R.drawable.photo5));
119 | photos.add(new Photo("flower details", R.drawable.photo6));
120 | photos.add(new Photo("tree", R.drawable.photo7));
121 | photos.add(new Photo("blue berries", R.drawable.photo8));
122 | photos.add(new Photo("snow man", R.drawable.photo9));
123 | //chest nut cat and fish guitar common-hazel cherry flower details tree
124 | //blue berries snow man
125 | // foods.add(new Food(R.drawable.food3));
126 | // foods.add(new Food(R.drawable.food2));
127 | // foods.add(new Food(R.drawable.food1));
128 | photoAdapter.addItems(photos);
129 | }
130 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/NormalViewActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 |
6 | /**
7 | * Created by lcodecore on 2017/4/6.
8 | */
9 |
10 | public class NormalViewActivity extends AppCompatActivity {
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_normalview);
16 | }
17 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/PhotoActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Handler;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.os.Bundle;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.support.v7.widget.StaggeredGridLayoutManager;
8 | import android.view.View;
9 | import android.view.WindowManager;
10 |
11 | import com.lcodecore.tkrefreshlayout.header.bezierlayout.BezierLayout;
12 | import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
13 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
14 | import com.lcodecore.twinklingrefreshlayout.adapter.PhotoAdapter;
15 | import com.lcodecore.twinklingrefreshlayout.beans.Photo;
16 |
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | public class PhotoActivity extends AppCompatActivity {
21 | private PhotoAdapter photoAdapter;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_photo);
27 |
28 | setupRecyclerView((RecyclerView) findViewById(R.id.recyclerview));
29 |
30 | findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
31 | @Override
32 | public void onClick(View v) {
33 | finish();
34 | }
35 | });
36 |
37 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
38 | }
39 |
40 | private void setupRecyclerView(RecyclerView rv) {
41 | rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
42 | photoAdapter = new PhotoAdapter();
43 | rv.setAdapter(photoAdapter);
44 |
45 | final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
46 | // ProgressLayout headerView = new ProgressLayout(this);
47 | BezierLayout headerView = new BezierLayout(this);
48 | refreshLayout.setHeaderView(headerView);
49 | refreshLayout.setMaxHeadHeight(140);
50 | // refreshLayout.setFloatRefresh(true);
51 | // refreshLayout.setPureScrollModeOn(true);
52 | refreshLayout.setOverScrollBottomShow(false);
53 | // refreshLayout.setAutoLoadMore(true);
54 |
55 | // addHeader();
56 | refreshCard();
57 | findViewById(R.id.ib_refresh).setOnClickListener(new View.OnClickListener() {
58 | @Override
59 | public void onClick(View v) {
60 | refreshLayout.startRefresh();
61 | }
62 | });
63 |
64 | refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
65 | @Override
66 | public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
67 | new Handler().postDelayed(new Runnable() {
68 | @Override
69 | public void run() {
70 | refreshCard();
71 | refreshLayout.finishRefreshing();
72 | }
73 | }, 2000);
74 | }
75 |
76 | @Override
77 | public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
78 | new Handler().postDelayed(new Runnable() {
79 | @Override
80 | public void run() {
81 | loadMoreCard();
82 | refreshLayout.finishLoadmore();
83 | }
84 | }, 2000);
85 | }
86 | });
87 |
88 | // refreshLayout.startRefresh();
89 | }
90 |
91 | void refreshCard() {
92 | List photos = new ArrayList<>();
93 | // foods.add(new Food("Preparing Salmon Steak Close Up","BY VIKTOR HANACEK",R.drawable.food1,R.drawable.avatar0));
94 | // foods.add(new Food("Fresh & Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food2,R.drawable.avatar1));
95 | // foods.add(new Food("Enjoying a Tasty Burger","BY VIKTOR HANACEK",R.drawable.food3,R.drawable.avatar2));
96 | // foods.add(new Food("Fresh Strawberries and Blackberries in Little Bowl","BY VIKTOR HANACEK",R.drawable.food4,R.drawable.avatar3));
97 | // foods.add(new Food("Baked Healthy Fitness Broccoli Pie with Basil","BY VIKTOR HANACEK",R.drawable.food5,R.drawable.avatar4));
98 | photos.add(new Photo("chest nut", R.drawable.photo1));
99 | photos.add(new Photo("fish", R.drawable.photo2));
100 | photos.add(new Photo("cat", R.drawable.photo10));
101 | photos.add(new Photo("guitar", R.drawable.photo3));
102 | photos.add(new Photo("common-hazel", R.drawable.photo4));
103 | photos.add(new Photo("cherry", R.drawable.photo5));
104 | photos.add(new Photo("flower details", R.drawable.photo6));
105 | photos.add(new Photo("tree", R.drawable.photo7));
106 | photos.add(new Photo("blue berries", R.drawable.photo8));
107 | photos.add(new Photo("snow man", R.drawable.photo9));
108 | photoAdapter.setDataList(photos);
109 | }
110 |
111 | void loadMoreCard() {
112 | List photos = new ArrayList<>();
113 | photos.add(new Photo("chest nut", R.drawable.photo1));
114 | photos.add(new Photo("fish", R.drawable.photo2));
115 | photos.add(new Photo("cat", R.drawable.photo10));
116 | photos.add(new Photo("guitar", R.drawable.photo3));
117 | photos.add(new Photo("common-hazel", R.drawable.photo4));
118 | photos.add(new Photo("cherry", R.drawable.photo5));
119 | photos.add(new Photo("flower details", R.drawable.photo6));
120 | photos.add(new Photo("tree", R.drawable.photo7));
121 | photos.add(new Photo("blue berries", R.drawable.photo8));
122 | photos.add(new Photo("snow man", R.drawable.photo9));
123 | //chest nut cat and fish guitar common-hazel cherry flower details tree
124 | //blue berries snow man
125 | // foods.add(new Food(R.drawable.food3));
126 | // foods.add(new Food(R.drawable.food2));
127 | // foods.add(new Food(R.drawable.food1));
128 | photoAdapter.addItems(photos);
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/ScienceActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 | import android.widget.AdapterView;
8 | import android.widget.GridView;
9 |
10 | import com.lcodecore.tkrefreshlayout.footer.LoadingView;
11 | import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
12 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
13 | import com.lcodecore.tkrefreshlayout.header.SinaRefreshView;
14 | import com.lcodecore.twinklingrefreshlayout.adapter.ScienceAdapter;
15 | import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
16 |
17 | public class ScienceActivity extends AppCompatActivity {
18 |
19 | private ScienceAdapter adapter;
20 |
21 | @Override
22 | protected void onCreate(Bundle savedInstanceState) {
23 | super.onCreate(savedInstanceState);
24 | setContentView(R.layout.activity_science);
25 | setupGridView((GridView) findViewById(R.id.gridView));
26 |
27 | findViewById(R.id.bt_back).setOnClickListener(new View.OnClickListener() {
28 | @Override
29 | public void onClick(View v) {
30 | finish();
31 | }
32 | });
33 | }
34 |
35 | private void setupGridView(GridView gridView) {
36 | final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
37 | SinaRefreshView headerView = new SinaRefreshView(this);
38 | headerView.setArrowResource(R.drawable.arrow);
39 | headerView.setTextColor(0xff745D5C);
40 | // TextHeaderView headerView = (TextHeaderView) View.inflate(this,R.layout.header_tv,null);
41 | refreshLayout.setHeaderView(headerView);
42 |
43 | LoadingView loadingView = new LoadingView(this);
44 | refreshLayout.setBottomView(loadingView);
45 |
46 | adapter = new ScienceAdapter();
47 | gridView.setAdapter(adapter);
48 | adapter.refreshCard();
49 |
50 | gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
51 | @Override
52 | public void onItemClick(AdapterView> adapterView, View view, int i, long l) {
53 | ToastUtil.show("item clicked!");
54 | }
55 | });
56 |
57 | refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
58 | @Override
59 | public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
60 | new Handler().postDelayed(new Runnable() {
61 | @Override
62 | public void run() {
63 | adapter.refreshCard();
64 | refreshLayout.finishRefreshing();
65 | }
66 | }, 2000);
67 | }
68 |
69 | @Override
70 | public void onLoadMore(final TwinklingRefreshLayout refreshLayout) {
71 | new Handler().postDelayed(new Runnable() {
72 | @Override
73 | public void run() {
74 | adapter.loadMoreCard();
75 | refreshLayout.finishLoadmore();
76 | }
77 | }, 2000);
78 | }
79 | });
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/StoryActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.os.Handler;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.os.Bundle;
6 |
7 | import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
8 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
9 | import com.lcodecore.tkrefreshlayout.footer.LoadingView;
10 | import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
11 |
12 | public class StoryActivity extends AppCompatActivity {
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_story);
18 |
19 | final TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refresh);
20 | // ProgressLayout header = new ProgressLayout(this);
21 | // refreshLayout.setHeaderView(header);
22 | // refreshLayout.setFloatRefresh(true);
23 | refreshLayout.setOverScrollRefreshShow(false);
24 | refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
25 | @Override
26 | public void onRefresh(TwinklingRefreshLayout refreshLayout1) {
27 | new Handler().postDelayed(new Runnable() {
28 | @Override
29 | public void run() {
30 | refreshLayout.finishRefreshing();
31 | }
32 | }, 4000);
33 | }
34 |
35 | @Override
36 | public void onLoadMore(final TwinklingRefreshLayout refreshLayout1) {
37 | new Handler().postDelayed(new Runnable() {
38 | @Override
39 | public void run() {
40 | refreshLayout.finishLoadmore();
41 | }
42 | }, 4000);
43 | }
44 | });
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TextHeaderView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.widget.TextView;
7 |
8 | import com.lcodecore.tkrefreshlayout.IHeaderView;
9 | import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
10 |
11 | /**
12 | * Created by lcodecore on 2016/10/1.
13 | */
14 |
15 | public class TextHeaderView extends TextView implements IHeaderView {
16 |
17 |
18 | public TextHeaderView(Context context) {
19 | super(context);
20 | }
21 |
22 | public TextHeaderView(Context context, AttributeSet attrs) {
23 | super(context, attrs);
24 | }
25 |
26 | public TextHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
27 | super(context, attrs, defStyleAttr);
28 | }
29 |
30 | @Override
31 | public View getView() {
32 | return this;
33 | }
34 |
35 | @Override
36 | public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
37 | if (fraction < 1f) setText("下拉刷新");
38 | if (fraction > 1f) setText("释放刷新");
39 | }
40 |
41 | @Override
42 | public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
43 | if (fraction < 1f) setText("下拉刷新");
44 | }
45 |
46 | @Override
47 | public void startAnim(float maxHeadHeight, float headHeight) {
48 | setText("正在刷新");
49 | }
50 |
51 | @Override
52 | public void onFinish(OnAnimEndListener listener) {
53 | listener.onAnimEnd();
54 | }
55 |
56 | @Override
57 | public void reset() {
58 | setText("下拉刷新");
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/TkApplication.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.os.StrictMode;
6 |
7 | import com.github.moduth.blockcanary.BlockCanary;
8 | import com.github.moduth.blockcanary.BlockCanaryContext;
9 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
10 | import com.lcodecore.tkrefreshlayout.footer.BallPulseView;
11 | import com.lcodecore.tkrefreshlayout.header.SinaRefreshView;
12 | import com.squareup.leakcanary.LeakCanary;
13 |
14 | import static android.os.Build.VERSION.SDK_INT;
15 | import static android.os.Build.VERSION_CODES.GINGERBREAD;
16 |
17 | /**
18 | * Created by lcodecore on 2016/12/4.
19 | */
20 |
21 | public class TkApplication extends Application {
22 |
23 | public static Context appContext;
24 |
25 | @Override
26 | public void onCreate() {
27 | super.onCreate();
28 |
29 | appContext = this;
30 |
31 | if (LeakCanary.isInAnalyzerProcess(this)) {
32 | return;
33 | }
34 | enabledStrictMode();
35 | LeakCanary.install(this);
36 |
37 | StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyDeath().build());
38 | StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyDeath().build());
39 |
40 | BlockCanary.install(this,new AppBlockCanaryContext()).start();
41 |
42 | // TwinklingRefreshLayout.setDefaultHeader(SinaRefreshView.class.getName());
43 | // TwinklingRefreshLayout.setDefaultFooter(BallPulseView.class.getName());
44 | }
45 |
46 | private class AppBlockCanaryContext extends BlockCanaryContext{}
47 |
48 | private void enabledStrictMode() {
49 | if (SDK_INT >= GINGERBREAD) {
50 | StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() //
51 | .detectAll() //
52 | .penaltyLog() //
53 | .penaltyDeath() //
54 | .build());
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/WebActivity.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.Handler;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.os.Bundle;
7 | import android.view.ViewGroup;
8 | import android.view.ViewParent;
9 | import android.webkit.WebView;
10 |
11 | import com.lcodecore.tkrefreshlayout.header.progresslayout.ProgressLayout;
12 | import com.lcodecore.tkrefreshlayout.RefreshListenerAdapter;
13 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
14 |
15 | public class WebActivity extends AppCompatActivity {
16 |
17 | private WebView mWebView;
18 |
19 | @SuppressLint("SetJavaScriptEnabled")
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_web);
24 |
25 | TwinklingRefreshLayout refreshLayout = (TwinklingRefreshLayout) findViewById(R.id.refreshLayout);
26 | ProgressLayout header = new ProgressLayout(this);
27 | refreshLayout.setHeaderView(header);
28 | refreshLayout.setFloatRefresh(true);
29 | refreshLayout.setOverScrollRefreshShow(false);
30 | refreshLayout.setHeaderHeight(140);
31 | refreshLayout.setMaxHeadHeight(240);
32 | refreshLayout.setOverScrollHeight(200);
33 | refreshLayout.setEnableLoadmore(false);
34 | header.setColorSchemeResources(R.color.Blue, R.color.Orange, R.color.Yellow, R.color.Green);
35 | // header.setColorSchemeColors(0xff4674e7,0xff0ba62c);
36 |
37 | mWebView = (WebView) findViewById(R.id.webView);
38 | mWebView.getSettings().setJavaScriptEnabled(true);
39 | mWebView.loadUrl("https://dribbble.com/shots");
40 |
41 | refreshLayout.startRefresh();
42 | refreshLayout.setOnRefreshListener(new RefreshListenerAdapter() {
43 | @Override
44 | public void onRefresh(final TwinklingRefreshLayout refreshLayout) {
45 | new Handler().postDelayed(new Runnable() {
46 | @Override
47 | public void run() {
48 | refreshLayout.finishRefreshing();
49 | }
50 | }, 4000);
51 | }
52 | });
53 | }
54 |
55 | @Override
56 | protected void onDestroy() {
57 | destroyWebView();
58 | super.onDestroy();
59 | }
60 |
61 | /**
62 | * 解决WebView持有mContext导致的内存泄漏问题
63 | */
64 | private void destroyWebView() {
65 | if (mWebView != null) {
66 | ViewParent parent = mWebView.getParent();
67 | if (parent != null) ((ViewGroup) parent).removeView(mWebView);
68 | mWebView.stopLoading();
69 | mWebView.getSettings().setJavaScriptEnabled(false);
70 | mWebView.clearHistory();
71 | mWebView.clearView();
72 | mWebView.removeAllViews();
73 | try {
74 | mWebView.destroy();
75 | } catch (Throwable e) {
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/FoodAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.lcodecore.twinklingrefreshlayout.R;
10 | import com.lcodecore.twinklingrefreshlayout.adapter.base.BaseRecyclerAdapter;
11 | import com.lcodecore.twinklingrefreshlayout.adapter.base.CommonHolder;
12 | import com.lcodecore.twinklingrefreshlayout.beans.Food;
13 | import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
14 | import com.lcodecore.twinklingrefreshlayout.views.CircleImageView;
15 |
16 | import butterknife.Bind;
17 |
18 | /**
19 | * Created by lcodecore on 2016/12/6.
20 | */
21 |
22 | public class FoodAdapter extends BaseRecyclerAdapter {
23 | @Override
24 | public CommonHolder setViewHolder(ViewGroup parent) {
25 | return new CardHolder(parent.getContext(), parent);
26 | }
27 |
28 | class CardHolder extends CommonHolder {
29 |
30 | @Bind(R.id.avatar)
31 | CircleImageView avatar;
32 |
33 | @Bind(R.id.tv_food)
34 | TextView tv_food;
35 |
36 | @Bind(R.id.tv_info)
37 | TextView tv_info;
38 |
39 | @Bind(R.id.iv_food)
40 | ImageView iv_food;
41 |
42 | public CardHolder(Context context, ViewGroup root) {
43 | super(context, root, R.layout.item_food);
44 | }
45 |
46 | @Override
47 | public void bindData(Food food) {
48 | avatar.setImageResource(food.avatar_id);
49 | iv_food.setImageResource(food.imageSrc);
50 | tv_food.setText(food.title);
51 | tv_info.setText(food.info);
52 |
53 | itemView.setOnClickListener(new View.OnClickListener() {
54 | @Override
55 | public void onClick(View view) {
56 | ToastUtil.show("item clicked!");
57 | }
58 | });
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/LoopViewPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter;
2 |
3 | import android.content.res.Resources;
4 | import android.graphics.drawable.Drawable;
5 | import android.os.Build;
6 | import android.support.v4.view.ViewPager;
7 | import android.view.Gravity;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.widget.ImageView;
12 | import android.widget.LinearLayout;
13 | import android.widget.TextView;
14 |
15 | import com.lcodecore.twinklingrefreshlayout.R;
16 | import com.lcodecore.twinklingrefreshlayout.adapter.base.BaseLoopPagerAdapter;
17 | import com.lcodecore.twinklingrefreshlayout.beans.Card;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 |
22 | public class LoopViewPagerAdapter extends BaseLoopPagerAdapter {
23 |
24 | private final List mHeroes;
25 |
26 | private final ViewGroup mIndicators;
27 |
28 | private int mLastPosition;
29 |
30 | public LoopViewPagerAdapter(ViewPager viewPager, ViewGroup indicators) {
31 | super(viewPager);
32 | mIndicators = indicators;
33 | mHeroes = new ArrayList<>();
34 | }
35 |
36 | public void setList(List heroes) {
37 | mHeroes.clear();
38 | mHeroes.addAll(heroes);
39 | initIndicators();
40 | notifyDataSetChanged();
41 | }
42 |
43 | /**
44 | * oh shit! An indicator view is badly needed!
45 | * this shit have no animation at all.
46 | */
47 | private void initIndicators() {
48 | if (mIndicators.getChildCount() != mHeroes.size() && mHeroes.size() > 1) {
49 | mIndicators.removeAllViews();
50 | Resources res = mIndicators.getResources();
51 | int size = res.getDimensionPixelOffset(R.dimen.indicator_size);
52 | int margin = res.getDimensionPixelOffset(R.dimen.indicator_margin);
53 | for (int i = 0; i < getPagerCount(); i++) {
54 | ImageView indicator = new ImageView(mIndicators.getContext());
55 | indicator.setAlpha(180);
56 | LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(size, size);
57 | lp.setMargins(margin, 0, 0, 0);
58 | lp.gravity = Gravity.CENTER;
59 | indicator.setLayoutParams(lp);
60 | Drawable drawable = res.getDrawable(R.drawable.selector_indicator);
61 | indicator.setImageDrawable(drawable);
62 | mIndicators.addView(indicator);
63 | }
64 | }
65 | }
66 |
67 | @Override
68 | public int getPagerCount() {
69 | return mHeroes.size();
70 | }
71 |
72 | @Override
73 | public Card getItem(int position) {
74 | return mHeroes.get(position);
75 | }
76 |
77 | @Override
78 | public View getView(int position, View convertView, ViewGroup parent) {
79 | ViewHolder holder = null;
80 | if (convertView == null) {
81 | convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_viewpager, parent, false);
82 | holder = new ViewHolder();
83 | holder.ivBanner = (ImageView) convertView.findViewById(R.id.ivBanner);
84 | holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
85 | convertView.setTag(holder);
86 | } else {
87 | holder = (ViewHolder) convertView.getTag();
88 | }
89 | int picSrcId = mHeroes.get(position).imageSrc;
90 | holder.tvName.setText(mHeroes.get(position).info);
91 | holder.ivBanner.setImageResource(picSrcId);
92 | return convertView;
93 | }
94 |
95 | @Override
96 | public void onPageItemSelected(int position) {
97 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
98 | mIndicators.getChildAt(mLastPosition).setActivated(false);
99 | mIndicators.getChildAt(position).setActivated(true);
100 | }
101 | mLastPosition = position;
102 | }
103 |
104 | public static class ViewHolder {
105 | ImageView ivBanner;
106 | TextView tvName;
107 | }
108 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/MusicAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 | import android.widget.BaseAdapter;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.lcodecore.twinklingrefreshlayout.R;
10 | import com.lcodecore.twinklingrefreshlayout.beans.Card;
11 | import com.lcodecore.twinklingrefreshlayout.views.CircleImageView;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * Created by lcodecore on 2016/12/6.
18 | */
19 |
20 | public class MusicAdapter extends BaseAdapter {
21 |
22 | private List cards = new ArrayList<>();
23 |
24 | @Override
25 | public int getCount() {
26 | return cards.size();
27 | }
28 |
29 | @Override
30 | public Card getItem(int position) {
31 | return cards.get(position);
32 | }
33 |
34 | @Override
35 | public long getItemId(int position) {
36 | return position;
37 | }
38 |
39 | @Override
40 | public View getView(int position, View convertView, ViewGroup parent) {
41 | final MusicAdapter.ViewHolder holder;
42 | if (convertView == null) {
43 | convertView = View.inflate(parent.getContext(), R.layout.item_music, null);
44 | holder = new MusicAdapter.ViewHolder(convertView);
45 | convertView.setTag(holder);
46 | } else {
47 | holder = (MusicAdapter.ViewHolder) convertView.getTag();
48 | }
49 |
50 | holder.tv_title.setText(cards.get(position).title);
51 | holder.tv_subTitle.setText(cards.get(position).info);
52 | holder.mImageView.setImageResource(cards.get(position).imageSrc);
53 |
54 | return convertView;
55 | }
56 |
57 | class ViewHolder {
58 | final CircleImageView mImageView;
59 | final TextView tv_title;
60 | final TextView tv_subTitle;
61 |
62 | ViewHolder(View view) {
63 | mImageView = (CircleImageView) view.findViewById(R.id.avatar);
64 | tv_title = (TextView) view.findViewById(R.id.tv_song);
65 | tv_subTitle = (TextView) view.findViewById(R.id.tv_singer);
66 | }
67 | }
68 |
69 | public void refreshCard(){
70 | cards.clear();
71 | cards.add(new Card("What Do You Mean?", "Justin Bieber", R.drawable.avatar1));
72 | cards.add(new Card("Secret Garden", "Song From A Secret Garden", R.drawable.avatar2));
73 | cards.add(new Card("Moves Like Jagger","Maroon 5",R.drawable.avatar3));
74 | cards.add(new Card("Work Hard, Play Hard","Wiz Khalifa",R.drawable.avatar4));
75 | cards.add(new Card("See You Again","Charlie Puth",R.drawable.avatar7));
76 | cards.add(new Card("Love The Way You Lie (Part Ii)","Rihanna",R.drawable.avatar5));
77 | cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",R.drawable.avatar9));
78 | cards.add(new Card("Let It Go","Demi Lovato",R.drawable.avatar8));
79 | notifyDataSetChanged();
80 | }
81 |
82 | public void loadMoreCard(){
83 | cards.add(new Card("You Raise Me Up","Westlife",R.drawable.avatar6));
84 | cards.add(new Card("See You Again","Charlie Puth",R.drawable.avatar7));
85 | cards.add(new Card("Love Story","Taylor Swift",R.drawable.avatar0));
86 | cards.add(new Card("Let It Go","Demi Lovato",R.drawable.avatar8));
87 | cards.add(new Card("Secret Garden", "Song From A Secret Garden", R.drawable.avatar2));
88 | cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",R.drawable.avatar9));
89 | notifyDataSetChanged();
90 | }
91 |
92 | public void addCard() {
93 | cards.add(new Card("What Do You Mean?", "Justin Bieber", R.drawable.avatar1));
94 | cards.add(new Card("Secret Garden", "Song From A Secret Garden", R.drawable.avatar2));
95 | cards.add(new Card("Moves Like Jagger","Maroon 5",R.drawable.avatar3));
96 | cards.add(new Card("Work Hard, Play Hard","Wiz Khalifa",R.drawable.avatar4));
97 | cards.add(new Card("Love The Way You Lie (Part Ii)","Rihanna",R.drawable.avatar5));
98 | cards.add(new Card("You Raise Me Up","Westlife",R.drawable.avatar6));
99 | cards.add(new Card("See You Again","Charlie Puth",R.drawable.avatar7));
100 | cards.add(new Card("Let It Go","Demi Lovato",R.drawable.avatar8));
101 | cards.add(new Card("Call Me Maybe","Carly Rae Jepsen",R.drawable.avatar9));
102 | //Love Story Taylor Swift
103 | }
104 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/PhotoAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter;
2 |
3 | import android.content.Context;
4 | import android.view.View;
5 | import android.view.ViewGroup;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.lcodecore.twinklingrefreshlayout.R;
10 | import com.lcodecore.twinklingrefreshlayout.adapter.base.BaseRecyclerAdapter;
11 | import com.lcodecore.twinklingrefreshlayout.adapter.base.CommonHolder;
12 | import com.lcodecore.twinklingrefreshlayout.beans.Photo;
13 | import com.lcodecore.twinklingrefreshlayout.utils.ToastUtil;
14 |
15 | import butterknife.Bind;
16 |
17 | /**
18 | * Created by lcodecore on 2016/12/7.
19 | */
20 |
21 | public class PhotoAdapter extends BaseRecyclerAdapter {
22 | @Override
23 | public CommonHolder setViewHolder(ViewGroup parent) {
24 | return new CardHolder(parent.getContext(), parent);
25 | }
26 |
27 | class CardHolder extends CommonHolder {
28 |
29 | @Bind(R.id.tv_info)
30 | TextView tv_info;
31 |
32 | @Bind(R.id.iv_pic)
33 | ImageView iv_pic;
34 |
35 | public CardHolder(Context context, ViewGroup root) {
36 | super(context, root, R.layout.item_photo);
37 | }
38 |
39 | @Override
40 | public void bindData(Photo photo) {
41 | iv_pic.setImageResource(photo.imgSrc);
42 | tv_info.setText(photo.name);
43 |
44 | itemView.setOnClickListener(new View.OnClickListener() {
45 | @Override
46 | public void onClick(View view) {
47 | ToastUtil.show("item clicked!");
48 | }
49 | });
50 | }
51 | }
52 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ScienceAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 | import android.widget.BaseAdapter;
6 | import android.widget.ImageView;
7 | import android.widget.TextView;
8 |
9 | import com.lcodecore.twinklingrefreshlayout.R;
10 | import com.lcodecore.twinklingrefreshlayout.beans.Card;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | /**
16 | * Created by lcodecore on 2016/12/7.
17 | */
18 |
19 | public class ScienceAdapter extends BaseAdapter {
20 |
21 | private List cards = new ArrayList<>();
22 |
23 | @Override
24 | public int getCount() {
25 | return cards.size();
26 | }
27 |
28 | @Override
29 | public Card getItem(int position) {
30 | return cards.get(position);
31 | }
32 |
33 | @Override
34 | public long getItemId(int position) {
35 | return position;
36 | }
37 |
38 | @Override
39 | public View getView(int position, View convertView, ViewGroup parent) {
40 | final ViewHolder holder;
41 | if (convertView == null) {
42 | convertView = View.inflate(parent.getContext(), R.layout.item_science, null);
43 | holder = new ViewHolder(convertView);
44 | convertView.setTag(holder);
45 | } else {
46 | holder = (ViewHolder) convertView.getTag();
47 | }
48 |
49 | holder.tv_name.setText(cards.get(position).title);
50 | holder.iv_cover.setImageResource(cards.get(position).imageSrc);
51 |
52 | return convertView;
53 | }
54 |
55 | class ViewHolder {
56 | final ImageView iv_cover;
57 | final TextView tv_name;
58 |
59 | ViewHolder(View view) {
60 | iv_cover = (ImageView) view.findViewById(R.id.iv_cover);
61 | tv_name = (TextView) view.findViewById(R.id.tv_name);
62 | }
63 | }
64 |
65 | public void refreshCard() {
66 | cards.clear();
67 | cards.add(new Card("genetics", "", R.drawable.science1));
68 | cards.add(new Card("globe", "", R.drawable.science2));
69 | cards.add(new Card("lab-flask-leaf", "", R.drawable.science3));
70 | cards.add(new Card("magnet", "", R.drawable.science4));
71 | cards.add(new Card("microscope", "", R.drawable.science5));
72 | cards.add(new Card("moon", "", R.drawable.science6));
73 | cards.add(new Card("telescope", "", R.drawable.science7));
74 | cards.add(new Card("satellite", "", R.drawable.science8));
75 | cards.add(new Card("Newtons-cradle", "", R.drawable.science9));
76 | cards.add(new Card("nuclear-symbol", "", R.drawable.science10));
77 | notifyDataSetChanged();
78 | }
79 |
80 | public void loadMoreCard() {
81 | cards.add(new Card("genetics", "", R.drawable.science1));
82 | cards.add(new Card("globe", "", R.drawable.science2));
83 | cards.add(new Card("lab-flask-leaf", "", R.drawable.science3));
84 | cards.add(new Card("magnet", "", R.drawable.science4));
85 | cards.add(new Card("microscope", "", R.drawable.science5));
86 | cards.add(new Card("moon", "", R.drawable.science6));
87 | cards.add(new Card("telescope", "", R.drawable.science7));
88 | cards.add(new Card("satellite", "", R.drawable.science8));
89 | cards.add(new Card("Newtons-cradle", "", R.drawable.science9));
90 | cards.add(new Card("nuclear-symbol", "", R.drawable.science10));
91 | notifyDataSetChanged();
92 | }
93 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/ViewPagerHolder.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.ViewPager;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.LinearLayout;
8 |
9 | import com.lcodecore.twinklingrefreshlayout.R;
10 | import com.lcodecore.twinklingrefreshlayout.adapter.base.CommonHolder;
11 | import com.lcodecore.twinklingrefreshlayout.beans.Card;
12 |
13 | import java.util.ArrayList;
14 | import java.util.Arrays;
15 | import java.util.List;
16 |
17 | import butterknife.Bind;
18 |
19 | public class ViewPagerHolder extends CommonHolder {
20 | private LoopViewPagerAdapter viewPagerAdapter;
21 | private List cards = new ArrayList<>();
22 |
23 | @Bind(R.id.viewPager)
24 | ViewPager viewPager;
25 |
26 | @Bind(R.id.indicators)
27 | LinearLayout indicators;
28 |
29 | public ViewPagerHolder(Context context, ViewGroup root) {
30 | super(context, root, R.layout.layout_viewpager);
31 |
32 | // cards.add(new Card("二次元专题", "啊喂,别总想去四维空间啦",R.drawable.card_cover6));
33 | // cards.add(new Card("Music Player", "闻其名,余音绕梁",R.drawable.card_cover7));
34 | // cards.add(new Card("el", "剪纸人の唯美旅程",R.drawable.card_cover8));
35 | // cards.add(new Card("God of Light", "点亮世界之光",R.drawable.card_cover1));
36 | // cards.add(new Card("BlackLight", "做最纯粹的微博客户端",R.drawable.card_cover3));
37 | }
38 |
39 | @Override
40 | public void bindData(Void aVoid) {
41 |
42 | }
43 |
44 | @Override
45 | public void bindHeadData() {
46 | if(viewPager.getAdapter() == null){
47 | viewPagerAdapter = new LoopViewPagerAdapter(viewPager, indicators);
48 | viewPager.setAdapter(viewPagerAdapter);
49 | viewPager.addOnPageChangeListener(viewPagerAdapter);
50 | viewPagerAdapter.setList(cards);
51 | }/*else{
52 | viewPagerAdapter.setList(pics);
53 | }*/
54 | }
55 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/BaseRecyclerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter.base;
2 |
3 | import android.animation.Animator;
4 | import android.animation.AnimatorListenerAdapter;
5 | import android.content.Context;
6 | import android.support.v7.widget.RecyclerView;
7 | import android.util.Log;
8 | import android.view.LayoutInflater;
9 | import android.view.View;
10 | import android.view.ViewGroup;
11 | import android.view.animation.DecelerateInterpolator;
12 |
13 | import com.lcodecore.twinklingrefreshlayout.utils.DensityUtil;
14 |
15 | import java.util.ArrayList;
16 | import java.util.List;
17 | import butterknife.ButterKnife;
18 | /**
19 | * RecyclerView适配器基类
20 | */
21 | public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter implements CommonHolder.OnNotifyChangeListener {
22 | private List dataList = new ArrayList<>();
23 | private boolean enableHead = false;
24 | CommonHolder headHolder;
25 | ViewGroup rootView;
26 | public final static int TYPE_HEAD = 0;
27 | public static final int TYPE_CONTENT = 1;
28 | @Override
29 | public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int position) {
30 | rootView = parent;
31 | //设置ViewHolder
32 | int type = getItemViewType(position);
33 | if (type == TYPE_HEAD) {
34 | return headHolder;
35 | } else {
36 | return setViewHolder(parent);
37 | }
38 | }
39 | @Override
40 | public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
41 | // runEnterAnimation(holder.itemView, position);
42 | //数据绑定
43 | if (enableHead) {
44 | if (position == 0) {
45 | ((CommonHolder) holder).bindHeadData();
46 | } else {
47 | ((CommonHolder) holder).bindData(dataList.get(position - 1));
48 | }
49 | } else {
50 | ((CommonHolder) holder).bindData(dataList.get(position));
51 | }
52 | ((CommonHolder) holder).setOnNotifyChangeListener(this);
53 | }
54 | public ViewGroup getRootView() {
55 | return rootView;
56 | }
57 | @Override
58 | public int getItemCount() {
59 | if (enableHead) {
60 | return dataList.size() + 1;
61 | }
62 | return dataList.size();
63 | }
64 | @Override
65 | public int getItemViewType(int position) {
66 | if (enableHead) {
67 | if (position == 0) {
68 | return TYPE_HEAD;
69 | } else {
70 | return TYPE_CONTENT;
71 | }
72 | } else {
73 | return TYPE_CONTENT;
74 | }
75 | }
76 | private int lastAnimatedPosition = -1;
77 | protected boolean animationsLocked = false;
78 | private boolean delayEnterAnimation = true;
79 | private void runEnterAnimation(View view, int position) {
80 | if (animationsLocked) return;
81 | if (position > lastAnimatedPosition) {
82 | lastAnimatedPosition = position;
83 | view.setTranslationY(DensityUtil.dip2px(view.getContext(), 100));//(position+1)*50f
84 | view.setAlpha(0.f);
85 | view.animate()
86 | .translationY(0).alpha(1.f)
87 | .setStartDelay(delayEnterAnimation ? 20 * (position) : 0)
88 | .setInterpolator(new DecelerateInterpolator(2.f))
89 | .setDuration(500)
90 | .setListener(new AnimatorListenerAdapter() {
91 | @Override
92 | public void onAnimationEnd(Animator animation) {
93 | animationsLocked = true;
94 | }
95 | }).start();
96 | }
97 | }
98 | @Override
99 | public void onNotify() {
100 | //提供给CommonHolder方便刷新视图
101 | notifyDataSetChanged();
102 | }
103 | public void setDataList(List datas) {
104 | dataList.clear();
105 | if (null != datas) {
106 | dataList.addAll(datas);
107 | }
108 | notifyDataSetChanged();
109 | }
110 | public void clearDatas() {
111 | dataList.clear();
112 | notifyDataSetChanged();
113 | }
114 | /**
115 | * 添加数据到前面
116 | */
117 | public void addItemsAtFront(List datas) {
118 | if (null == datas) return;
119 | dataList.addAll(0, datas);
120 | notifyDataSetChanged();
121 | }
122 | /**
123 | * 添加数据到尾部
124 | */
125 | public void addItems(List datas) {
126 | if (null == datas) return;
127 | dataList.addAll(datas);
128 | notifyDataSetChanged();
129 | }
130 | /**
131 | * 添加单条数据
132 | */
133 | public void addItem(T data) {
134 | if (null == data) return;
135 | dataList.add(data);
136 | notifyDataSetChanged();
137 | }
138 | /**
139 | * 删除单条数据
140 | */
141 | public void deletItem(T data) {
142 | dataList.remove(data);
143 | Log.d("deletItem: ", dataList.remove(data) + "");
144 | notifyDataSetChanged();
145 | }
146 | /**
147 | * 设置是否显示head
148 | *
149 | * @param ifEnable 是否显示头部
150 | */
151 | public void setEnableHead(boolean ifEnable) {
152 | enableHead = ifEnable;
153 | }
154 | public void setHeadHolder(CommonHolder headHolder1) {
155 | enableHead = true;
156 | headHolder = headHolder1;
157 | }
158 | public void setHeadHolder(View itemView) {
159 | enableHead = true;
160 | headHolder = new HeadHolder(itemView);
161 | notifyItemInserted(0);
162 | }
163 | public CommonHolder getHeadHolder() {
164 | return headHolder;
165 | }
166 | /**
167 | * 子类重写实现自定义ViewHolder
168 | */
169 | public abstract CommonHolder setViewHolder(ViewGroup parent);
170 |
171 | public class HeadHolder extends CommonHolder {
172 | public HeadHolder(View itemView) {
173 | super(itemView);
174 | }
175 |
176 | public HeadHolder(Context context, ViewGroup root, int layoutRes) {
177 | super(context,root,layoutRes);
178 | }
179 |
180 | @Override
181 | public void bindData(Void aVoid) {//不用实现
182 | }
183 | }
184 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter.base;
2 |
3 | import android.database.DataSetObservable;
4 | import android.database.DataSetObserver;
5 | import android.support.v7.widget.RecyclerView;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.widget.ListAdapter;
9 |
10 | /**
11 | * Created by lcodecore on 2016/10/22.
12 | */
13 |
14 | public abstract class CommonAdapter implements ListAdapter {
15 | private final DataSetObservable mDataSetObservable = new DataSetObservable();
16 |
17 | public boolean hasStableIds() {
18 | return false;
19 | }
20 |
21 | public void registerDataSetObserver(DataSetObserver observer) {
22 | mDataSetObservable.registerObserver(observer);
23 | }
24 |
25 | public void unregisterDataSetObserver(DataSetObserver observer) {
26 | mDataSetObservable.unregisterObserver(observer);
27 | }
28 |
29 | /**
30 | * Notifies the attached observers that the underlying data has been changed
31 | * and any View reflecting the data set should refresh itself.
32 | */
33 | public void notifyDataSetChanged() {
34 | mDataSetObservable.notifyChanged();
35 | }
36 |
37 | /**
38 | * Notifies the attached observers that the underlying data is no longer valid
39 | * or available. Once invoked this adapter is no longer valid and should
40 | * not report further data set changes.
41 | */
42 | public void notifyDataSetInvalidated() {
43 | mDataSetObservable.notifyInvalidated();
44 | }
45 |
46 | public boolean areAllItemsEnabled() {
47 | return true;
48 | }
49 |
50 | public boolean isEnabled(int position) {
51 | return true;
52 | }
53 |
54 | public View getDropDownView(int position, View convertView, ViewGroup parent) {
55 | return getView(position, convertView, parent);
56 | }
57 |
58 | public int getItemViewType(int position) {
59 | return 0;
60 | }
61 |
62 | public int getViewTypeCount() {
63 | return 1;
64 | }
65 |
66 | public boolean isEmpty() {
67 | return getCount() == 0;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/adapter/base/CommonHolder.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.adapter.base;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import butterknife.ButterKnife;
9 | /**
10 | * 聊天消息条目的基类
11 | * ViewHolder 与 Adapter 解耦
12 | */
13 | public abstract class CommonHolder extends RecyclerView.ViewHolder {
14 | public CommonHolder(Context context, ViewGroup root, int layoutRes) {
15 | super(LayoutInflater.from(context).inflate(layoutRes, root, false));
16 | ButterKnife.bind(this, itemView);
17 | }
18 | /**
19 | * 此适配器是为了能让详情页共用列表页的ViewHolder,一般情况无需重写该构造器
20 | */
21 | public CommonHolder(View itemView) {
22 | super(itemView);
23 | ButterKnife.bind(this, itemView);
24 | }
25 | public Context getContext() {
26 | return itemView.getContext();
27 | }
28 | /**
29 | * 用给定的 data 对 holder 的 view 进行赋值
30 | */
31 | public abstract void bindData(T t);
32 |
33 | public void bindHeadData(){}
34 | /**
35 | * 通知适配器更新布局
36 | */
37 | public interface OnNotifyChangeListener {
38 | void onNotify();
39 | }
40 | OnNotifyChangeListener listener;
41 | public void setOnNotifyChangeListener(OnNotifyChangeListener listener) {
42 | this.listener = listener;
43 | }
44 | public void notifyChange() {
45 | listener.onNotify();
46 | }
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Card.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.beans;
2 |
3 | import java.io.Serializable;
4 |
5 | public class Card implements Serializable {
6 | private static final long serialVersionUID = -5376313495678563362L;
7 |
8 | public String title;
9 | public String info;
10 | public int imageSrc;
11 |
12 | public Card(){}
13 |
14 | public Card(String title,String info,int imageSrc){
15 | this.title = title;
16 | this.info = info;
17 | this.imageSrc = imageSrc;
18 | }
19 |
20 | public void setTitle(String title,String info){
21 | this.title = title;
22 | this.info = info;
23 | }
24 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Food.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.beans;
2 |
3 | /**
4 | * Created by lcodecore on 2016/12/6.
5 | */
6 |
7 | public class Food {
8 | public String title;
9 | public String info;
10 | public int imageSrc;
11 | public int avatar_id;
12 |
13 | public Food(String title, String info, int imageSrc, int avatar_id) {
14 | this.title = title;
15 | this.info = info;
16 | this.imageSrc = imageSrc;
17 | this.avatar_id = avatar_id;
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/beans/Photo.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.beans;
2 |
3 | /**
4 | * Created by lcodecore on 2016/12/7.
5 | */
6 |
7 | public class Photo {
8 | public String name;
9 | public int imgSrc;
10 |
11 | public Photo(String name, int imgSrc) {
12 | this.name = name;
13 | this.imgSrc = imgSrc;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/DensityUtil.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.Point;
5 | import android.view.Display;
6 | import android.view.WindowManager;
7 |
8 | public class DensityUtil {
9 | private static int screenWidth = 0;
10 | private static int screenHeight = 0;
11 | public static int dip2px(Context var0, float var1) {
12 | float var2 = var0.getResources().getDisplayMetrics().density;
13 | return (int)(var1 * var2 + 0.5F);
14 | }
15 | public static int px2dip(Context var0, float var1) {
16 | float var2 = var0.getResources().getDisplayMetrics().density;
17 | return (int)(var1 / var2 + 0.5F);
18 | }
19 | public static int sp2px(Context var0, float var1) {
20 | float var2 = var0.getResources().getDisplayMetrics().scaledDensity;
21 | return (int)(var1 * var2 + 0.5F);
22 | }
23 | public static int px2sp(Context var0, float var1) {
24 | float var2 = var0.getResources().getDisplayMetrics().scaledDensity;
25 | return (int)(var1 / var2 + 0.5F);
26 | }
27 | public static int getScreenWidth(Context c) {
28 | if (screenWidth == 0) {
29 | WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
30 | Display display = wm.getDefaultDisplay();
31 | Point size = new Point();
32 | display.getSize(size);
33 | screenWidth = size.x;
34 | }
35 | return screenWidth;
36 | }
37 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/lcodecore/twinklingrefreshlayout/utils/ToastUtil.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.twinklingrefreshlayout.utils;
2 |
3 | import android.widget.Toast;
4 |
5 | import com.lcodecore.twinklingrefreshlayout.TkApplication;
6 |
7 | /**
8 | * Created by lcodecore on 2017/2/28.
9 | */
10 |
11 | public class ToastUtil {
12 | public static void show(String msg){
13 | Toast.makeText(TkApplication.appContext, msg, Toast.LENGTH_SHORT).show();
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/arrow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar0.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar4.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar5.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar6.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar7.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar8.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/avatar9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/avatar9.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/back.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/back_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/back_dark.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/back_pink.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/back_pink.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/back_white.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/food1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/food1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/food2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/food2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/food3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/food3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/food4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/food4.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/food5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/food5.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/map.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/map.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/pager_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/pager_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo1.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo10.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo2.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo3.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo4.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo5.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo6.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo7.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo8.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/photo9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/photo9.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/play.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/play_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/play_white.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science1.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science10.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science2.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science3.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science4.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science5.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science6.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science7.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science8.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/science9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/science9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/wave.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xhdpi/wave.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_create_white_36dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable-xxhdpi/ic_create_white_36dp.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/bg_wood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/drawable/bg_wood.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_indicator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | -
4 |
5 |
6 |
7 |
8 |
9 | -
10 |
11 |
12 |
13 |
14 |
15 | -
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_coordinate.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
20 |
21 |
30 |
31 |
37 |
38 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_food.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
18 |
19 |
22 |
23 |
31 |
32 |
41 |
42 |
50 |
51 |
52 |
56 |
57 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
21 |
22 |
23 |
24 |
25 |
26 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_music.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
16 |
17 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_nested_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
24 |
25 |
34 |
35 |
43 |
44 |
45 |
49 |
50 |
54 |
57 |
58 |
62 |
67 |
68 |
69 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_normalview.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
17 |
18 |
22 |
23 |
34 |
35 |
44 |
45 |
51 |
52 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_photo.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
24 |
25 |
34 |
35 |
44 |
45 |
46 |
50 |
51 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_science.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
12 |
13 |
21 |
22 |
31 |
32 |
40 |
41 |
42 |
46 |
47 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_web.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
18 |
19 |
26 |
27 |
34 |
35 |
42 |
43 |
50 |
51 |
58 |
59 |
66 |
67 |
74 |
75 |
82 |
83 |
84 |
92 |
93 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/header_music.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
31 |
39 |
40 |
41 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/header_tv.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/inc_toolbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_food.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
25 |
26 |
30 |
31 |
38 |
39 |
46 |
47 |
48 |
58 |
59 |
60 |
68 |
69 |
70 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_music.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
21 |
30 |
38 |
39 |
40 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_photo.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
23 |
24 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_science.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
26 |
27 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_viewpager.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
18 |
19 |
29 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/layout_viewpager.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #353536
4 | #262626
5 | #e75946
6 |
7 | #ffffff
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 | 240dp
7 | 6dp
8 | 6dp
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | TwinklingRefreshView
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/art/alipay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/alipay.jpg
--------------------------------------------------------------------------------
/art/app-debug.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/app-debug.apk
--------------------------------------------------------------------------------
/art/gif2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif2.gif
--------------------------------------------------------------------------------
/art/gif_gridview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_gridview.gif
--------------------------------------------------------------------------------
/art/gif_gridview.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_gridview.mp4
--------------------------------------------------------------------------------
/art/gif_listview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_listview.gif
--------------------------------------------------------------------------------
/art/gif_listview.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_listview.mp4
--------------------------------------------------------------------------------
/art/gif_recyclerview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_recyclerview.gif
--------------------------------------------------------------------------------
/art/gif_recyclerview.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_recyclerview.mp4
--------------------------------------------------------------------------------
/art/gif_recyclerview2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_recyclerview2.gif
--------------------------------------------------------------------------------
/art/gif_recyclerview2.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_recyclerview2.mp4
--------------------------------------------------------------------------------
/art/gif_scrollview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_scrollview.gif
--------------------------------------------------------------------------------
/art/gif_scrollview.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_scrollview.mp4
--------------------------------------------------------------------------------
/art/gif_webview.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_webview.gif
--------------------------------------------------------------------------------
/art/gif_webview.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/gif_webview.mp4
--------------------------------------------------------------------------------
/art/pic_large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/pic_large.png
--------------------------------------------------------------------------------
/art/structure_v1.0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/structure_v1.0.png
--------------------------------------------------------------------------------
/art/wepay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/art/wepay.png
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.0'
9 | classpath 'com.novoda:bintray-release:0.3.4'
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | tasks.withType(Javadoc) {
20 | options.addStringOption('Xdoclint:none', '-quiet')
21 | options.addStringOption('encoding', 'UTF-8')
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/library/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/library/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'
3 |
4 | publish{
5 | userOrg = 'lcodecorex'
6 | groupId = 'com.lcodecorex'
7 | artifactId = 'tkrefreshlayout'
8 | publishVersion = '1.0.7'
9 | website = 'https://github.com/lcodecorex/TwinklingRefreshLayout/'
10 | }
11 |
12 | android {
13 | compileSdkVersion 25
14 | buildToolsVersion '25.0.1'
15 |
16 | defaultConfig {
17 | minSdkVersion 14
18 | targetSdkVersion 25
19 | versionCode 7
20 | versionName "1.07"
21 | }
22 | buildTypes {
23 | release {
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 |
29 | lintOptions {
30 | abortOnError false
31 | }
32 | }
33 |
34 | dependencies {
35 | compile fileTree(include: ['*.jar'], dir: 'libs')
36 | compile 'com.android.support:recyclerview-v7:25.2.0'
37 | compile 'com.android.support:support-v4:25.2.0'
38 | }
39 |
--------------------------------------------------------------------------------
/library/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/lcodecore/Documents/android_sdk_macosx/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 |
--------------------------------------------------------------------------------
/library/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/BallPulseView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.footer;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.support.annotation.ColorInt;
9 | import android.util.AttributeSet;
10 | import android.view.Gravity;
11 | import android.view.View;
12 | import android.widget.FrameLayout.LayoutParams;
13 |
14 | import com.lcodecore.tkrefreshlayout.IBottomView;
15 | import com.lcodecore.tkrefreshlayout.utils.DensityUtil;
16 |
17 | import java.util.ArrayList;
18 | import java.util.HashMap;
19 | import java.util.Map;
20 |
21 | /**
22 | * Created by lcodecore on 2017/3/7.
23 | */
24 |
25 | public class BallPulseView extends View implements IBottomView {
26 |
27 | public static final int DEFAULT_SIZE = 50; //dp
28 | private float circleSpacing;
29 |
30 | private float[] scaleFloats = new float[]{1f, 1f, 1f};
31 |
32 | private ArrayList mAnimators;
33 | private Map mUpdateListeners = new HashMap<>();
34 | private Paint mPaint;
35 |
36 | public BallPulseView(Context context) {
37 | this(context, null);
38 | }
39 |
40 | public BallPulseView(Context context, AttributeSet attrs) {
41 | this(context, attrs, 0);
42 | }
43 |
44 | public BallPulseView(Context context, AttributeSet attrs, int defStyleAttr) {
45 | super(context, attrs, defStyleAttr);
46 |
47 | int default_size = DensityUtil.dp2px(context, DEFAULT_SIZE);
48 | LayoutParams params = new LayoutParams(default_size, default_size, Gravity.CENTER);
49 | setLayoutParams(params);
50 |
51 | circleSpacing = DensityUtil.dp2px(context, 4);
52 |
53 | mPaint = new Paint();
54 | mPaint.setColor(Color.WHITE);
55 | mPaint.setStyle(Paint.Style.FILL);
56 | mPaint.setAntiAlias(true);
57 | }
58 |
59 | public void setIndicatorColor(int color) {
60 | mPaint.setColor(color);
61 | }
62 |
63 | private int normalColor = 0xffeeeeee;
64 | private int animatingColor = 0xffe75946;
65 |
66 | public void setNormalColor(@ColorInt int color) {
67 | normalColor = color;
68 | }
69 |
70 | public void setAnimatingColor(@ColorInt int color) {
71 | animatingColor = color;
72 | }
73 |
74 | @Override
75 | protected void onDraw(Canvas canvas) {
76 | float radius = (Math.min(getWidth(), getHeight()) - circleSpacing * 2) / 6;
77 | float x = getWidth() / 2 - (radius * 2 + circleSpacing);
78 | float y = getHeight() / 2;
79 | for (int i = 0; i < 3; i++) {
80 | canvas.save();
81 | float translateX = x + (radius * 2) * i + circleSpacing * i;
82 | canvas.translate(translateX, y);
83 | canvas.scale(scaleFloats[i], scaleFloats[i]);
84 | canvas.drawCircle(0, 0, radius, mPaint);
85 | canvas.restore();
86 | }
87 | }
88 |
89 | @Override
90 | protected void onDetachedFromWindow() {
91 | super.onDetachedFromWindow();
92 | if (mAnimators != null) for (int i = 0; i < mAnimators.size(); i++) {
93 | mAnimators.get(i).cancel();
94 | }
95 | }
96 |
97 | public void startAnim() {
98 | if (mAnimators == null) createAnimators();
99 | if (mAnimators == null) return;
100 | if (isStarted()) return;
101 |
102 | for (int i = 0; i < mAnimators.size(); i++) {
103 | ValueAnimator animator = mAnimators.get(i);
104 |
105 | //when the animator restart , add the updateListener again because they was removed by animator stop .
106 | ValueAnimator.AnimatorUpdateListener updateListener = mUpdateListeners.get(animator);
107 | if (updateListener != null) {
108 | animator.addUpdateListener(updateListener);
109 | }
110 | animator.start();
111 | }
112 | setIndicatorColor(animatingColor);
113 | }
114 |
115 | public void stopAnim() {
116 | if (mAnimators != null) {
117 | for (ValueAnimator animator : mAnimators) {
118 | if (animator != null && animator.isStarted()) {
119 | animator.removeAllUpdateListeners();
120 | animator.end();
121 | }
122 | }
123 | }
124 | setIndicatorColor(normalColor);
125 | }
126 |
127 | private boolean isStarted() {
128 | for (ValueAnimator animator : mAnimators) {
129 | return animator.isStarted();
130 | }
131 | return false;
132 | }
133 |
134 | private void createAnimators() {
135 | mAnimators = new ArrayList<>();
136 | int[] delays = new int[]{120, 240, 360};
137 | for (int i = 0; i < 3; i++) {
138 | final int index = i;
139 |
140 | ValueAnimator scaleAnim = ValueAnimator.ofFloat(1, 0.3f, 1);
141 |
142 | scaleAnim.setDuration(750);
143 | scaleAnim.setRepeatCount(ValueAnimator.INFINITE);
144 | scaleAnim.setStartDelay(delays[i]);
145 |
146 | mUpdateListeners.put(scaleAnim, new ValueAnimator.AnimatorUpdateListener() {
147 | @Override
148 | public void onAnimationUpdate(ValueAnimator animation) {
149 | scaleFloats[index] = (float) animation.getAnimatedValue();
150 | postInvalidate();
151 | }
152 | });
153 | mAnimators.add(scaleAnim);
154 | }
155 | }
156 |
157 | @Override
158 | public View getView() {
159 | return this;
160 | }
161 |
162 | @Override
163 | public void onPullingUp(float fraction, float maxHeadHeight, float headHeight) {
164 | stopAnim();
165 | }
166 |
167 | @Override
168 | public void startAnim(float maxHeadHeight, float headHeight) {
169 | startAnim();
170 | }
171 |
172 | @Override
173 | public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
174 | stopAnim();
175 | }
176 |
177 | @Override
178 | public void onFinish() {
179 | stopAnim();
180 | }
181 |
182 | @Override
183 | public void reset() {
184 | stopAnim();
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/Footer/LoadingView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.footer;
2 |
3 | import android.content.Context;
4 | import android.graphics.drawable.AnimationDrawable;
5 | import android.util.AttributeSet;
6 | import android.view.Gravity;
7 | import android.view.View;
8 | import android.widget.FrameLayout;
9 | import android.widget.ImageView;
10 |
11 | import com.lcodecore.tkrefreshlayout.IBottomView;
12 | import com.lcodecore.tkrefreshlayout.R;
13 | import com.lcodecore.tkrefreshlayout.utils.DensityUtil;
14 |
15 | /**
16 | * Created by lcodecore on 2016/10/3.
17 | */
18 |
19 | public class LoadingView extends ImageView implements IBottomView {
20 | public LoadingView(Context context) {
21 | this(context, null);
22 | }
23 |
24 | public LoadingView(Context context, AttributeSet attrs) {
25 | this(context, attrs, 0);
26 | }
27 |
28 | public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
29 | super(context, attrs, defStyleAttr);
30 |
31 | int size = DensityUtil.dp2px(context,34);
32 | FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(size,size);
33 | params.gravity = Gravity.CENTER;
34 | setLayoutParams(params);
35 | setImageResource(R.drawable.anim_loading_view);
36 | }
37 |
38 | @Override
39 | public View getView() {
40 | return this;
41 | }
42 |
43 | @Override
44 | public void onPullingUp(float fraction, float maxHeadHeight, float headHeight) {
45 |
46 | }
47 |
48 | @Override
49 | public void startAnim(float maxHeadHeight, float headHeight) {
50 | ((AnimationDrawable)getDrawable()).start();
51 | }
52 |
53 | @Override
54 | public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
55 |
56 | }
57 |
58 | @Override
59 | public void onFinish() {
60 |
61 | }
62 |
63 | @Override
64 | public void reset() {
65 |
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/IBottomView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * Created by lcodecore on 2016/10/1.
7 | */
8 |
9 | public interface IBottomView {
10 | View getView();
11 |
12 | /**
13 | * 上拉准备加载更多的动作
14 | *
15 | * @param fraction 上拉高度与Bottom总高度之比
16 | * @param maxBottomHeight 底部部可拉伸最大高度
17 | * @param bottomHeight 底部高度
18 | */
19 | void onPullingUp(float fraction, float maxBottomHeight, float bottomHeight);
20 |
21 | void startAnim(float maxBottomHeight, float bottomHeight);
22 |
23 | /**
24 | * 上拉释放过程
25 | */
26 | void onPullReleasing(float fraction, float maxBottomHeight, float bottomHeight);
27 |
28 | void onFinish();
29 |
30 | void reset();
31 | }
32 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/IHeaderView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout;
2 |
3 | import android.view.View;
4 |
5 | /**
6 | * Created by lcodecore on 2016/10/1.
7 | */
8 |
9 | public interface IHeaderView {
10 | View getView();
11 |
12 | /**
13 | * 下拉准备刷新动作
14 | *
15 | * @param fraction 当前下拉高度与总高度的比
16 | * @param maxHeadHeight
17 | * @param headHeight
18 | */
19 | void onPullingDown(float fraction, float maxHeadHeight, float headHeight);
20 |
21 | /**
22 | * 下拉释放过程
23 | *
24 | * @param fraction
25 | * @param maxHeadHeight
26 | * @param headHeight
27 | */
28 | void onPullReleasing(float fraction, float maxHeadHeight, float headHeight);
29 |
30 | void startAnim(float maxHeadHeight, float headHeight);
31 |
32 | void onFinish(OnAnimEndListener animEndListener);
33 |
34 | /**
35 | * 用于在必要情况下复位View,清除动画
36 | */
37 | void reset();
38 | }
39 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/OnAnimEndListener.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout;
2 |
3 | /**
4 | * Created by lcodecore on 2016/11/26.
5 | */
6 |
7 | public interface OnAnimEndListener {
8 |
9 | public void onAnimEnd();
10 | }
11 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/OnGestureListener.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout;
2 |
3 | import android.view.MotionEvent;
4 |
5 | public interface OnGestureListener {
6 | void onDown(MotionEvent ev);
7 |
8 | void onScroll(MotionEvent downEvent, MotionEvent currentEvent, float distanceX, float distanceY);
9 |
10 | void onUp(MotionEvent ev, boolean isFling);
11 |
12 | void onFling(MotionEvent downEvent, MotionEvent upEvent, float velocityX, float velocityY);
13 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/PullListener.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout;
2 |
3 | public interface PullListener {
4 | /**
5 | * 下拉中
6 | *
7 | * @param refreshLayout
8 | * @param fraction
9 | */
10 | void onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction);
11 |
12 | /**
13 | * 上拉
14 | */
15 | void onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction);
16 |
17 | /**
18 | * 下拉松开
19 | *
20 | * @param refreshLayout
21 | * @param fraction
22 | */
23 | void onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction);
24 |
25 | /**
26 | * 上拉松开
27 | */
28 | void onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction);
29 |
30 | /**
31 | * 刷新中。。。
32 | */
33 | void onRefresh(TwinklingRefreshLayout refreshLayout);
34 |
35 | /**
36 | * 加载更多中
37 | */
38 | void onLoadMore(TwinklingRefreshLayout refreshLayout);
39 |
40 | /**
41 | * 手动调用finishRefresh或者finishLoadmore之后的回调
42 | */
43 | void onFinishRefresh();
44 |
45 | void onFinishLoadMore();
46 |
47 | /**
48 | * 正在刷新时向上滑动屏幕,刷新被取消
49 | */
50 | void onRefreshCanceled();
51 |
52 | /**
53 | * 正在加载更多时向下滑动屏幕,加载更多被取消
54 | */
55 | void onLoadmoreCanceled();
56 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/RefreshListenerAdapter.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout;
2 |
3 | public abstract class RefreshListenerAdapter implements PullListener {
4 | @Override
5 | public void onPullingDown(TwinklingRefreshLayout refreshLayout, float fraction) {
6 | }
7 |
8 | @Override
9 | public void onPullingUp(TwinklingRefreshLayout refreshLayout, float fraction) {
10 | }
11 |
12 | @Override
13 | public void onPullDownReleasing(TwinklingRefreshLayout refreshLayout, float fraction) {
14 | }
15 |
16 | @Override
17 | public void onPullUpReleasing(TwinklingRefreshLayout refreshLayout, float fraction) {
18 | }
19 |
20 | @Override
21 | public void onRefresh(TwinklingRefreshLayout refreshLayout) {
22 | }
23 |
24 | @Override
25 | public void onLoadMore(TwinklingRefreshLayout refreshLayout) {
26 | }
27 |
28 | @Override
29 | public void onFinishRefresh() {
30 |
31 | }
32 |
33 | @Override
34 | public void onFinishLoadMore() {
35 |
36 | }
37 |
38 | @Override
39 | public void onRefreshCanceled() {
40 |
41 | }
42 |
43 | @Override
44 | public void onLoadmoreCanceled() {
45 |
46 | }
47 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/header/SinaRefreshView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.header;
2 |
3 | import android.content.Context;
4 | import android.graphics.drawable.AnimationDrawable;
5 | import android.support.annotation.ColorInt;
6 | import android.support.annotation.DrawableRes;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 | import android.widget.FrameLayout;
10 | import android.widget.ImageView;
11 | import android.widget.TextView;
12 |
13 | import com.lcodecore.tkrefreshlayout.IHeaderView;
14 | import com.lcodecore.tkrefreshlayout.OnAnimEndListener;
15 | import com.lcodecore.tkrefreshlayout.R;
16 |
17 | /**
18 | * Created by lcodecore on 2016/10/2.
19 | */
20 |
21 | public class SinaRefreshView extends FrameLayout implements IHeaderView {
22 |
23 | private ImageView refreshArrow;
24 | private ImageView loadingView;
25 | private TextView refreshTextView;
26 |
27 | public SinaRefreshView(Context context) {
28 | this(context, null);
29 | }
30 |
31 | public SinaRefreshView(Context context, AttributeSet attrs) {
32 | this(context, attrs, 0);
33 | }
34 |
35 | public SinaRefreshView(Context context, AttributeSet attrs, int defStyleAttr) {
36 | super(context, attrs, defStyleAttr);
37 | init();
38 | }
39 |
40 | private void init() {
41 | View rootView = View.inflate(getContext(), R.layout.view_sinaheader, null);
42 | refreshArrow = (ImageView) rootView.findViewById(R.id.iv_arrow);
43 | refreshTextView = (TextView) rootView.findViewById(R.id.tv);
44 | loadingView = (ImageView) rootView.findViewById(R.id.iv_loading);
45 | addView(rootView);
46 | }
47 |
48 | public void setArrowResource(@DrawableRes int resId) {
49 | refreshArrow.setImageResource(resId);
50 | }
51 |
52 | public void setTextColor(@ColorInt int color) {
53 | refreshTextView.setTextColor(color);
54 | }
55 |
56 | public void setPullDownStr(String pullDownStr1) {
57 | pullDownStr = pullDownStr1;
58 | }
59 |
60 | public void setReleaseRefreshStr(String releaseRefreshStr1) {
61 | releaseRefreshStr = releaseRefreshStr1;
62 | }
63 |
64 | public void setRefreshingStr(String refreshingStr1) {
65 | refreshingStr = refreshingStr1;
66 | }
67 |
68 | private String pullDownStr = "下拉刷新";
69 | private String releaseRefreshStr = "释放刷新";
70 | private String refreshingStr = "正在刷新";
71 |
72 | @Override
73 | public View getView() {
74 | return this;
75 | }
76 |
77 | @Override
78 | public void onPullingDown(float fraction, float maxHeadHeight, float headHeight) {
79 | if (fraction < 1f) refreshTextView.setText(pullDownStr);
80 | if (fraction > 1f) refreshTextView.setText(releaseRefreshStr);
81 | refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
82 | }
83 |
84 | @Override
85 | public void onPullReleasing(float fraction, float maxHeadHeight, float headHeight) {
86 | if (fraction < 1f) {
87 | refreshTextView.setText(pullDownStr);
88 | refreshArrow.setRotation(fraction * headHeight / maxHeadHeight * 180);
89 | if (refreshArrow.getVisibility() == GONE) {
90 | refreshArrow.setVisibility(VISIBLE);
91 | loadingView.setVisibility(GONE);
92 | }
93 | }
94 | }
95 |
96 | @Override
97 | public void startAnim(float maxHeadHeight, float headHeight) {
98 | refreshTextView.setText(refreshingStr);
99 | refreshArrow.setVisibility(GONE);
100 | loadingView.setVisibility(VISIBLE);
101 | ((AnimationDrawable) loadingView.getDrawable()).start();
102 | }
103 |
104 | @Override
105 | public void onFinish(OnAnimEndListener listener) {
106 | listener.onAnimEnd();
107 | }
108 |
109 | @Override
110 | public void reset() {
111 | refreshArrow.setVisibility(VISIBLE);
112 | loadingView.setVisibility(GONE);
113 | refreshTextView.setText(pullDownStr);
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RippleView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.header.bezierlayout;
2 |
3 |
4 | import android.animation.Animator;
5 | import android.animation.AnimatorListenerAdapter;
6 | import android.animation.ValueAnimator;
7 | import android.content.Context;
8 | import android.graphics.Canvas;
9 | import android.graphics.Paint;
10 | import android.support.annotation.ColorInt;
11 | import android.util.AttributeSet;
12 | import android.view.View;
13 |
14 | /**
15 | * cjj
16 | */
17 | public class RippleView extends View {
18 | private Paint mPaint;
19 | private int r;
20 | private OnRippleEndListener listener;
21 |
22 | public int getR() {
23 | return r;
24 | }
25 |
26 | public void setR(int r) {
27 | this.r = r;
28 | }
29 |
30 | public RippleView(Context context) {
31 | this(context, null, 0);
32 | }
33 |
34 | public RippleView(Context context, AttributeSet attrs) {
35 | this(context, attrs, 0);
36 | }
37 |
38 | public RippleView(Context context, AttributeSet attrs, int defStyleAttr) {
39 | super(context, attrs, defStyleAttr);
40 | init();
41 | }
42 |
43 | ValueAnimator va;
44 |
45 | private void init() {
46 | mPaint = new Paint();
47 | mPaint.setAntiAlias(true);
48 | mPaint.setColor(0xffffffff);
49 | mPaint.setStyle(Paint.Style.FILL);
50 | }
51 |
52 | public void setRippleColor(@ColorInt int color) {
53 | if (mPaint != null) mPaint.setColor(color);
54 | }
55 |
56 | public void startReveal() {
57 | setVisibility(VISIBLE);
58 | if (va == null) {
59 | int bigRadius = (int) (Math.sqrt(Math.pow(getHeight(), 2) + Math.pow(getWidth(), 2)));
60 | va = ValueAnimator.ofInt(0, bigRadius / 2);
61 | va.setDuration(bigRadius);
62 | va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
63 | @Override
64 | public void onAnimationUpdate(ValueAnimator animation) {
65 | r = (int) animation.getAnimatedValue() * 2;
66 | invalidate();
67 | }
68 | });
69 | va.addListener(new AnimatorListenerAdapter() {
70 | @Override
71 | public void onAnimationEnd(Animator animation) {
72 | if (listener != null) {
73 | listener.onRippleEnd();
74 | }
75 | }
76 | });
77 | }
78 | va.start();
79 | }
80 |
81 | public void stopAnim() {
82 | if (va != null && va.isRunning()) va.cancel();
83 | }
84 |
85 | @Override
86 | protected void onDraw(Canvas canvas) {
87 | super.onDraw(canvas);
88 | canvas.drawCircle(getWidth() / 2, getHeight() / 2, r, mPaint);
89 | }
90 |
91 | @Override
92 | protected void onDetachedFromWindow() {
93 | super.onDetachedFromWindow();
94 | if (va != null) va.cancel();
95 | }
96 |
97 | public void setRippleEndListener(OnRippleEndListener listener) {
98 | this.listener = listener;
99 | }
100 |
101 | public interface OnRippleEndListener {
102 | void onRippleEnd();
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundDotView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.header.bezierlayout;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.util.AttributeSet;
8 | import android.view.View;
9 |
10 | /**
11 | * Created by cjj on 2015/8/27.
12 | */
13 | public class RoundDotView extends View {
14 | private Paint mPath;
15 | private float r=15;
16 | private int num = 7;
17 |
18 | public void setCir_x(int cir_x) {
19 | this.cir_x = cir_x;
20 | }
21 |
22 | private int cir_x;
23 |
24 | public RoundDotView(Context context) {
25 | this(context, null, 0);
26 | }
27 |
28 | public RoundDotView(Context context, AttributeSet attrs) {
29 | this(context, attrs, 0);
30 | }
31 |
32 | public RoundDotView(Context context, AttributeSet attrs, int defStyleAttr) {
33 | super(context, attrs, defStyleAttr);
34 | init();
35 | }
36 |
37 | private void init() {
38 | mPath = new Paint();
39 | mPath.setAntiAlias(true);
40 | mPath.setColor(Color.rgb(114,114,114));
41 | }
42 |
43 | @Override
44 | protected void onDraw(Canvas canvas) {
45 | super.onDraw(canvas);
46 | int w = getMeasuredWidth()/num-10;
47 | for (int i = 0;i < num; i++)
48 | {
49 | switch (i)
50 | {
51 | case 0:
52 | mPath.setAlpha(35);
53 | canvas.drawCircle(getMeasuredWidth() / 2-cir_x*3 -3*w/3*2,getMeasuredHeight()/2,r,mPath);
54 | break;
55 | case 1:
56 | mPath.setAlpha(105);
57 | canvas.drawCircle(getMeasuredWidth() / 2-cir_x*2 -2*w/3*2,getMeasuredHeight()/2,r,mPath);
58 | break;
59 | case 2:
60 | mPath.setAlpha(145);
61 | canvas.drawCircle(getMeasuredWidth() / 2 -cir_x*1-w/3*2,getMeasuredHeight()/2,r,mPath);
62 | break;
63 | case 3:
64 | mPath.setAlpha(255);
65 | canvas.drawCircle(getMeasuredWidth() / 2 ,getMeasuredHeight()/2,r,mPath);
66 | break;
67 | case 4:
68 | mPath.setAlpha(145);
69 | canvas.drawCircle(getMeasuredWidth() / 2 +cir_x*1+w/3*2,getMeasuredHeight()/2,r,mPath);
70 | break;
71 | case 5:
72 | mPath.setAlpha(105);
73 | canvas.drawCircle(getMeasuredWidth() / 2 +cir_x*2+2*w/3*2,getMeasuredHeight()/2,r,mPath);
74 | break;
75 | case 6:
76 | mPath.setAlpha(35);
77 | canvas.drawCircle(getMeasuredWidth() / 2 +cir_x*3+3*w/3*2,getMeasuredHeight()/2,r,mPath);
78 | break;
79 | }
80 |
81 | }
82 | }
83 |
84 |
85 | }
86 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/RoundProgressView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.header.bezierlayout;
2 |
3 | import android.animation.ValueAnimator;
4 | import android.content.Context;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.RectF;
9 | import android.util.AttributeSet;
10 | import android.view.View;
11 | import android.view.animation.AccelerateDecelerateInterpolator;
12 |
13 | /**
14 | * Created by Administrator on 2015/8/27.
15 | */
16 | public class RoundProgressView extends View {
17 | private Paint mPath;
18 | private Paint mPantR;
19 | private float r = 40;
20 | private int num = 7;
21 | private int stratAngle = 270;
22 | private int endAngle = 0;
23 | private int outCir_value = 15;
24 |
25 | public void setCir_x(int cir_x) {
26 | this.cir_x = cir_x;
27 | }
28 |
29 | private int cir_x;
30 |
31 | public RoundProgressView(Context context) {
32 | this(context, null, 0);
33 | }
34 |
35 | public RoundProgressView(Context context, AttributeSet attrs) {
36 | this(context, attrs, 0);
37 | }
38 |
39 | public RoundProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
40 | super(context, attrs, defStyleAttr);
41 | init();
42 |
43 | }
44 |
45 | ValueAnimator va;
46 |
47 | private void init() {
48 | mPath = new Paint();
49 | mPantR = new Paint();
50 | mPantR.setColor(Color.WHITE);
51 | mPantR.setAntiAlias(true);
52 | mPath.setAntiAlias(true);
53 | mPath.setColor(Color.rgb(114, 114, 114));
54 |
55 | va = ValueAnimator.ofInt(0, 360);
56 | va.setDuration(720);
57 | va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
58 | @Override
59 | public void onAnimationUpdate(ValueAnimator animation) {
60 | endAngle = (int) animation.getAnimatedValue();
61 | postInvalidate();
62 | }
63 | });
64 | va.setRepeatCount(ValueAnimator.INFINITE);
65 | va.setInterpolator(new AccelerateDecelerateInterpolator());
66 | }
67 |
68 | private RectF oval, oval2;
69 |
70 | @Override
71 | protected void onDraw(Canvas canvas) {
72 | super.onDraw(canvas);
73 | int w = getMeasuredWidth() / num - 10;
74 | mPath.setStyle(Paint.Style.FILL);
75 | canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r, mPath);
76 | canvas.save();
77 | mPath.setStyle(Paint.Style.STROKE);//设置为空心
78 | mPath.setStrokeWidth(6);
79 | canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, r + 15, mPath);
80 | canvas.restore();
81 |
82 | mPantR.setStyle(Paint.Style.FILL);
83 | if (oval == null) oval = new RectF();
84 | oval.set(getMeasuredWidth() / 2 - r, getMeasuredHeight() / 2 - r, getMeasuredWidth() / 2 + r, getMeasuredHeight() / 2 + r);// 设置个新的长方形,扫描测量
85 | canvas.drawArc(oval, stratAngle, endAngle, true, mPantR);
86 | canvas.save();
87 | mPantR.setStrokeWidth(6);
88 | mPantR.setStyle(Paint.Style.STROKE);
89 | if (oval2 == null) oval2 = new RectF();
90 | oval2.set(getMeasuredWidth() / 2 - r - outCir_value, getMeasuredHeight() / 2 - r - outCir_value, getMeasuredWidth() / 2 + r + outCir_value, getMeasuredHeight() / 2 + r + outCir_value);// 设置个新的长方形,扫描测量
91 | canvas.drawArc(oval2, stratAngle, endAngle, false, mPantR);
92 | canvas.restore();
93 | }
94 |
95 | @Override
96 | protected void onDetachedFromWindow() {
97 | super.onDetachedFromWindow();
98 | if (va != null) va.cancel();
99 | }
100 |
101 | public void startAnim() {
102 | if (va != null) va.start();
103 | }
104 |
105 | public void stopAnim() {
106 | if (va != null && va.isRunning()) va.cancel();
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/header/bezierlayout/WaveView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.header.bezierlayout;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Paint;
7 | import android.graphics.Path;
8 | import android.graphics.PixelFormat;
9 | import android.graphics.drawable.Drawable;
10 | import android.support.annotation.ColorInt;
11 | import android.util.AttributeSet;
12 | import android.view.View;
13 |
14 | /**
15 | * Created by cjj on 2015/8/5.
16 | * 绘制贝塞尔来绘制波浪形
17 | */
18 | public class WaveView extends View {
19 | private int waveHeight;
20 | private int headHeight;
21 | Path path;
22 | Paint paint;
23 |
24 | public WaveView(Context context) {
25 | this(context, null, 0);
26 | }
27 |
28 | public WaveView(Context context, AttributeSet attrs) {
29 | this(context, attrs, 0);
30 | }
31 |
32 | public WaveView(Context context, AttributeSet attrs, int defStyleAttr) {
33 | super(context, attrs, defStyleAttr);
34 | init();
35 | }
36 |
37 | private void init() {
38 | path = new Path();
39 | paint = new Paint();
40 | paint.setColor(0xff1F2426);
41 | paint.setAntiAlias(true);
42 | }
43 |
44 | public int getHeadHeight() {
45 | return headHeight;
46 | }
47 |
48 | public void setHeadHeight(int headHeight) {
49 | this.headHeight = headHeight;
50 | }
51 |
52 | public int getWaveHeight() {
53 | return waveHeight;
54 | }
55 |
56 | public void setWaveHeight(int waveHeight) {
57 | this.waveHeight = waveHeight;
58 | }
59 |
60 | public void setWaveColor(@ColorInt int color) {
61 | if (paint != null) paint.setColor(color);
62 | }
63 |
64 | @Override
65 | protected void onDraw(Canvas canvas) {
66 | super.onDraw(canvas);
67 | //重置画笔
68 | path.reset();
69 | path.lineTo(0, headHeight);
70 | //绘制贝塞尔曲线
71 | path.quadTo(getMeasuredWidth() / 2, headHeight + waveHeight, getMeasuredWidth(), headHeight);
72 | path.lineTo(getMeasuredWidth(), 0);
73 | canvas.drawPath(path, paint);
74 | }
75 |
76 |
77 | static Bitmap drawableToBitmap(Drawable drawable) // drawable 转换成bitmap
78 | {
79 | int width = drawable.getIntrinsicWidth();// 取drawable的长宽
80 | int height = drawable.getIntrinsicHeight();
81 | Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;// 取drawable的颜色格式
82 | Bitmap bitmap = Bitmap.createBitmap(width, height, config);// 建立对应bitmap
83 | Canvas canvas = new Canvas(bitmap);// 建立对应bitmap的画布
84 | drawable.setBounds(0, 0, width, height);
85 | drawable.draw(canvas);// 把drawable内容画到画布中
86 | return bitmap;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/header/progresslayout/CircleImageView.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.header.progresslayout;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.graphics.Color;
6 | import android.graphics.Paint;
7 | import android.graphics.RadialGradient;
8 | import android.graphics.Shader;
9 | import android.graphics.drawable.ShapeDrawable;
10 | import android.graphics.drawable.shapes.OvalShape;
11 | import android.support.v4.view.ViewCompat;
12 | import android.view.animation.Animation;
13 | import android.widget.ImageView;
14 |
15 | /**
16 | * Private class created to work around issues with AnimationListeners being
17 | * called before the animation is actually complete and support shadows on older
18 | * platforms.
19 | *
20 | */
21 | public class CircleImageView extends ImageView {
22 |
23 | private static final int KEY_SHADOW_COLOR = 0x1E000000;
24 | private static final int FILL_SHADOW_COLOR = 0x3D000000;
25 | // PX
26 | private static final float X_OFFSET = 0f;
27 | private static final float Y_OFFSET = 1.75f;
28 | private static final float SHADOW_RADIUS = 3.5f;
29 | private static final int SHADOW_ELEVATION = 4;
30 |
31 | private Animation.AnimationListener mListener;
32 | private int mShadowRadius;
33 |
34 | public CircleImageView(Context context, int color, final float radius) {
35 | super(context);
36 | final float density = getContext().getResources().getDisplayMetrics().density;
37 | final int diameter = (int) (radius * density * 2);
38 | final int shadowYOffset = (int) (density * Y_OFFSET);
39 | final int shadowXOffset = (int) (density * X_OFFSET);
40 |
41 | mShadowRadius = (int) (density * SHADOW_RADIUS);
42 |
43 | ShapeDrawable circle;
44 | if (elevationSupported()) {
45 | circle = new ShapeDrawable(new OvalShape());
46 | ViewCompat.setElevation(this, SHADOW_ELEVATION * density);
47 | } else {
48 | OvalShape oval = new OvalShadow(mShadowRadius, diameter);
49 | circle = new ShapeDrawable(oval);
50 | ViewCompat.setLayerType(this, ViewCompat.LAYER_TYPE_SOFTWARE, circle.getPaint());
51 | circle.getPaint().setShadowLayer(mShadowRadius, shadowXOffset, shadowYOffset,
52 | KEY_SHADOW_COLOR);
53 | final int padding = mShadowRadius;
54 | // set padding so the inner image sits correctly within the shadow.
55 | setPadding(padding, padding, padding, padding);
56 | }
57 | circle.getPaint().setColor(color);
58 | setBackgroundDrawable(circle);
59 | }
60 |
61 | private boolean elevationSupported() {
62 | return android.os.Build.VERSION.SDK_INT >= 21;
63 | }
64 |
65 | @Override
66 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
67 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
68 | if (!elevationSupported()) {
69 | setMeasuredDimension(getMeasuredWidth() + mShadowRadius*2, getMeasuredHeight()
70 | + mShadowRadius*2);
71 | }
72 | }
73 |
74 | public void setAnimationListener(Animation.AnimationListener listener) {
75 | mListener = listener;
76 | }
77 |
78 | @Override
79 | public void onAnimationStart() {
80 | super.onAnimationStart();
81 | if (mListener != null) {
82 | mListener.onAnimationStart(getAnimation());
83 | }
84 | }
85 |
86 | @Override
87 | public void onAnimationEnd() {
88 | super.onAnimationEnd();
89 | if (mListener != null) {
90 | mListener.onAnimationEnd(getAnimation());
91 | }
92 | }
93 |
94 | /**
95 | * Update the background color of the circle image view.
96 | *
97 | * @param colorRes Id of a color resource.
98 | */
99 | public void setBackgroundColorRes(int colorRes) {
100 | setBackgroundColor(getContext().getResources().getColor(colorRes));
101 | }
102 |
103 | @Override
104 | public void setBackgroundColor(int color) {
105 | if (getBackground() instanceof ShapeDrawable) {
106 | ((ShapeDrawable) getBackground()).getPaint().setColor(color);
107 | }
108 | }
109 |
110 | private class OvalShadow extends OvalShape {
111 | private RadialGradient mRadialGradient;
112 | private Paint mShadowPaint;
113 | private int mCircleDiameter;
114 |
115 | public OvalShadow(int shadowRadius, int circleDiameter) {
116 | super();
117 | mShadowPaint = new Paint();
118 | mShadowRadius = shadowRadius;
119 | mCircleDiameter = circleDiameter;
120 | mRadialGradient = new RadialGradient(mCircleDiameter / 2, mCircleDiameter / 2,
121 | mShadowRadius, new int[] {
122 | FILL_SHADOW_COLOR, Color.TRANSPARENT
123 | }, null, Shader.TileMode.CLAMP);
124 | mShadowPaint.setShader(mRadialGradient);
125 | }
126 |
127 | @Override
128 | public void draw(Canvas canvas, Paint paint) {
129 | final int viewWidth = CircleImageView.this.getWidth();
130 | final int viewHeight = CircleImageView.this.getHeight();
131 | canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2 + mShadowRadius),
132 | mShadowPaint);
133 | canvas.drawCircle(viewWidth / 2, viewHeight / 2, (mCircleDiameter / 2), paint);
134 | }
135 | }
136 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/Decorator.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.processor;
2 |
3 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
4 |
5 | /**
6 | * Created by lcodecore on 2017/3/3.
7 | */
8 |
9 | public abstract class Decorator implements IDecorator {
10 | protected IDecorator decorator;
11 | protected TwinklingRefreshLayout.CoContext cp;
12 |
13 | public Decorator(TwinklingRefreshLayout.CoContext processor, IDecorator decorator1) {
14 | cp = processor;
15 | decorator = decorator1;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/IAnimOverScroll.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.processor;
2 |
3 | /**
4 | * Created by lcodecore on 2017/3/3.
5 | */
6 |
7 | public interface IAnimOverScroll {
8 | void animOverScrollTop(float vy, int computeTimes);
9 | void animOverScrollBottom(float vy, int computeTimes);
10 | }
11 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/IAnimRefresh.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.processor;
2 |
3 | /**
4 | * Created by lcodecore on 2017/3/3.
5 | */
6 |
7 | public interface IAnimRefresh {
8 | void scrollHeadByMove(float moveY);
9 | void scrollBottomByMove(float moveY);
10 | void animHeadToRefresh();
11 | void animHeadBack(boolean isFinishRefresh);
12 | void animHeadHideByVy(int vy);
13 | void animBottomToLoad();
14 | void animBottomBack(boolean isFinishRefresh);
15 | void animBottomHideByVy(int vy);
16 | }
17 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/IDecorator.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.processor;
2 |
3 | import android.view.MotionEvent;
4 |
5 | /**
6 | * Created by lcodecore on 2017/3/1.
7 | */
8 |
9 | public interface IDecorator {
10 | boolean dispatchTouchEvent(MotionEvent ev);
11 |
12 | boolean interceptTouchEvent(MotionEvent ev);
13 |
14 | boolean dealTouchEvent(MotionEvent ev);
15 |
16 | void onFingerDown(MotionEvent ev);
17 |
18 | void onFingerUp(MotionEvent ev, boolean isFling);
19 |
20 | void onFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY, float velocityX, float velocityY);
21 |
22 | void onFingerFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
23 | }
24 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/OverScrollDecorator.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.processor;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 | import android.view.MotionEvent;
6 | import android.view.View;
7 |
8 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
9 | import com.lcodecore.tkrefreshlayout.utils.ScrollingUtil;
10 |
11 | /**
12 | * Created by lcodecore on 2017/3/1.
13 | */
14 | //TODO FullOverScrollDecorator、VerticalDecorator
15 | public class OverScrollDecorator extends Decorator {
16 |
17 | //主要为了监测Fling的动作,实现越界回弹
18 | private float mVelocityY;
19 |
20 | //满足越界的手势的最低速度(默认3000)
21 | private static final int OVER_SCROLL_MIN_VX = 3000;
22 |
23 | //针对View的延时策略
24 | private static final int MSG_START_COMPUTE_SCROLL = 0; //开始计算
25 | private static final int MSG_CONTINUE_COMPUTE_SCROLL = 1;//继续计算
26 | private static final int MSG_STOP_COMPUTE_SCROLL = 2; //停止计算
27 |
28 | private int cur_delay_times = 0; //当前计算次数
29 | private static final int ALL_DELAY_TIMES = 60; //10ms计算一次,总共计算20次
30 |
31 | public OverScrollDecorator(TwinklingRefreshLayout.CoContext processor, IDecorator decorator1) {
32 | super(processor, decorator1);
33 | }
34 |
35 |
36 | @Override
37 | public boolean dispatchTouchEvent(MotionEvent ev) {
38 | return decorator != null && decorator.dispatchTouchEvent(ev);
39 | }
40 |
41 | @Override
42 | public boolean interceptTouchEvent(MotionEvent ev) {
43 | return decorator != null && decorator.interceptTouchEvent(ev);
44 | }
45 |
46 | @Override
47 | public boolean dealTouchEvent(MotionEvent e) {
48 | return decorator != null && decorator.dealTouchEvent(e);
49 | }
50 |
51 | private boolean preventTopOverScroll = false;
52 | private boolean preventBottomOverScroll = false;
53 | private boolean checkOverScroll = false;
54 |
55 | @Override
56 | public void onFingerDown(MotionEvent ev) {
57 | if (decorator != null) decorator.onFingerDown(ev);
58 | preventTopOverScroll = ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop());
59 | preventBottomOverScroll = ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop());
60 | }
61 |
62 | @Override
63 | public void onFingerUp(MotionEvent ev, boolean isFling) {
64 |
65 | if (decorator != null) {
66 | decorator.onFingerUp(ev, checkOverScroll && isFling);
67 | }
68 | checkOverScroll = false;
69 | }
70 |
71 | @Override
72 | public void onFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY, float velocityX, float velocityY) {
73 | if (decorator != null)
74 | decorator.onFingerScroll(e1, e2, distanceX, distanceY, velocityX, velocityY);
75 | }
76 |
77 | @Override
78 | public void onFingerFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
79 | if (decorator != null) decorator.onFingerFling(e1, e2, velocityX, velocityY);
80 | //fling时才触发OverScroll,获取速度并采用演示策略估算View是否滚动到边界
81 | if (!cp.enableOverScroll()) return;
82 |
83 | int dy = (int) (e2.getY() - e1.getY());
84 | if (dy < -cp.getTouchSlop() && preventBottomOverScroll) return;//控件滚动在底部且向上fling
85 | if (dy > cp.getTouchSlop() && preventTopOverScroll) return;//控件滚动在顶部且向下fling
86 |
87 | mVelocityY = velocityY;
88 | if (Math.abs(mVelocityY) >= OVER_SCROLL_MIN_VX) {
89 | mHandler.sendEmptyMessage(MSG_START_COMPUTE_SCROLL);
90 | checkOverScroll = true;
91 | } else {
92 | mVelocityY = 0;
93 | cur_delay_times = ALL_DELAY_TIMES;
94 | }
95 | }
96 |
97 | private Handler mHandler = new Handler() {
98 |
99 | @Override
100 | public void handleMessage(Message msg) {
101 | int mTouchSlop = cp.getTouchSlop();
102 | switch (msg.what) {
103 | case MSG_START_COMPUTE_SCROLL:
104 | cur_delay_times = -1; //这里没有break,写作-1方便计数
105 | case MSG_CONTINUE_COMPUTE_SCROLL:
106 | cur_delay_times++;
107 |
108 | View mChildView = cp.getTargetView();
109 |
110 | if (cp.allowOverScroll()) {
111 | if (mVelocityY >= OVER_SCROLL_MIN_VX) {
112 | if (ScrollingUtil.isViewToTop(mChildView, mTouchSlop)) {
113 | cp.getAnimProcessor().animOverScrollTop(mVelocityY, cur_delay_times);
114 | mVelocityY = 0;
115 | cur_delay_times = ALL_DELAY_TIMES;
116 | }
117 | } else if (mVelocityY <= -OVER_SCROLL_MIN_VX) {
118 | if (ScrollingUtil.isViewToBottom(mChildView, mTouchSlop)) {
119 | cp.getAnimProcessor().animOverScrollBottom(mVelocityY, cur_delay_times);
120 | mVelocityY = 0;
121 | cur_delay_times = ALL_DELAY_TIMES;
122 | }
123 | }
124 | }
125 |
126 | //计算未超时,继续发送消息并循环计算
127 | if (cur_delay_times < ALL_DELAY_TIMES)
128 | mHandler.sendEmptyMessageDelayed(MSG_CONTINUE_COMPUTE_SCROLL, 10);
129 | break;
130 | case MSG_STOP_COMPUTE_SCROLL:
131 | cur_delay_times = ALL_DELAY_TIMES;
132 | break;
133 | }
134 | }
135 | };
136 | }
137 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/processor/RefreshProcessor.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.processor;
2 |
3 | import android.view.MotionEvent;
4 | import android.view.ViewConfiguration;
5 |
6 | import com.lcodecore.tkrefreshlayout.TwinklingRefreshLayout;
7 | import com.lcodecore.tkrefreshlayout.utils.ScrollingUtil;
8 |
9 | /**
10 | * Created by lcodecore on 2017/3/1.
11 | */
12 |
13 | public class RefreshProcessor implements IDecorator {
14 |
15 | protected TwinklingRefreshLayout.CoContext cp;
16 |
17 | public RefreshProcessor(TwinklingRefreshLayout.CoContext processor) {
18 | if (processor == null) throw new NullPointerException("The coprocessor can not be null.");
19 | cp = processor;
20 | }
21 |
22 | private float mTouchX, mTouchY;
23 | private boolean intercepted = false;
24 | private boolean willAnimHead = false;
25 | private boolean willAnimBottom = false;
26 | private boolean downEventSent = false;
27 |
28 | @Override
29 | public boolean dispatchTouchEvent(MotionEvent ev) {
30 | switch (ev.getAction()) {
31 | case MotionEvent.ACTION_DOWN:
32 | downEventSent = false;
33 | intercepted = false;
34 | mTouchX = ev.getX();
35 | mTouchY = ev.getY();
36 |
37 | if (cp.isEnableKeepIView()) {
38 | if (!cp.isRefreshing()) {
39 | cp.setPrepareFinishRefresh(false);
40 | }
41 | if (!cp.isLoadingMore()) {
42 | cp.setPrepareFinishLoadMore(false);
43 | }
44 | }
45 |
46 | cp.dispatchTouchEventSuper(ev);
47 | return true;
48 | case MotionEvent.ACTION_MOVE:
49 | mLastMoveEvent = ev;
50 | float dx = ev.getX() - mTouchX;
51 | float dy = ev.getY() - mTouchY;
52 | if (!intercepted && Math.abs(dx) <= Math.abs(dy) && Math.abs(dy) > cp.getTouchSlop()) {//滑动允许最大角度为45度
53 | if (dy > 0 && ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop()) && cp.allowPullDown()) {
54 | cp.setStatePTD();
55 | mTouchX = ev.getX();
56 | mTouchY = ev.getY();
57 | sendCancelEvent();
58 | intercepted = true;
59 | return true;
60 | } else if (dy < 0 && ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop()) && cp.allowPullUp()) {
61 | cp.setStatePBU();
62 | mTouchX = ev.getX();
63 | mTouchY = ev.getY();
64 | intercepted = true;
65 | sendCancelEvent();
66 | return true;
67 | }
68 | }
69 | if (intercepted) {
70 | if (cp.isRefreshVisible() || cp.isLoadingVisible()) {
71 | return cp.dispatchTouchEventSuper(ev);
72 | }
73 | if (!cp.isPrepareFinishRefresh() && cp.isStatePTD()) {
74 | if (dy < -cp.getTouchSlop() || !ScrollingUtil.isViewToTop(cp.getTargetView(), cp.getTouchSlop())) {
75 | cp.dispatchTouchEventSuper(ev);
76 | }
77 | dy = Math.min(cp.getMaxHeadHeight() * 2, dy);
78 | dy = Math.max(0, dy);
79 | cp.getAnimProcessor().scrollHeadByMove(dy);
80 | } else if (!cp.isPrepareFinishLoadMore() && cp.isStatePBU()) {
81 | //加载更多的动作
82 | if (dy > cp.getTouchSlop() || !ScrollingUtil.isViewToBottom(cp.getTargetView(), cp.getTouchSlop())) {
83 | cp.dispatchTouchEventSuper(ev);
84 | }
85 | dy = Math.max(-cp.getMaxBottomHeight() * 2, dy);
86 | dy = Math.min(0, dy);
87 | cp.getAnimProcessor().scrollBottomByMove(Math.abs(dy));
88 | }
89 | if (dy == 0 && !downEventSent) {
90 | downEventSent = true;
91 | sendDownEvent();
92 | }
93 | return true;
94 | }
95 | break;
96 | case MotionEvent.ACTION_CANCEL:
97 | case MotionEvent.ACTION_UP:
98 | if (intercepted) {
99 | if (cp.isStatePTD()) {
100 | willAnimHead = true;
101 | } else if (cp.isStatePBU()) {
102 | willAnimBottom = true;
103 | }
104 | intercepted = false;
105 | return true;
106 | }
107 | break;
108 | }
109 | return cp.dispatchTouchEventSuper(ev);
110 | }
111 |
112 | private MotionEvent mLastMoveEvent;
113 |
114 | //发送cancel事件解决selection问题
115 | private void sendCancelEvent() {
116 | if (mLastMoveEvent == null) {
117 | return;
118 | }
119 | MotionEvent last = mLastMoveEvent;
120 | MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime() + ViewConfiguration.getLongPressTimeout(), MotionEvent.ACTION_CANCEL, last.getX(), last.getY(), last.getMetaState());
121 | cp.dispatchTouchEventSuper(e);
122 | }
123 |
124 | private void sendDownEvent() {
125 | final MotionEvent last = mLastMoveEvent;
126 | MotionEvent e = MotionEvent.obtain(last.getDownTime(), last.getEventTime(), MotionEvent.ACTION_DOWN, last.getX(), last.getY(), last.getMetaState());
127 | cp.dispatchTouchEventSuper(e);
128 | }
129 |
130 | @Override
131 | public boolean interceptTouchEvent(MotionEvent ev) {
132 | return false;
133 | }
134 |
135 | @Override
136 | public boolean dealTouchEvent(MotionEvent e) {
137 | return false;
138 | }
139 |
140 | @Override
141 | public void onFingerDown(MotionEvent ev) {
142 | }
143 |
144 | @Override
145 | public void onFingerUp(MotionEvent ev, boolean isFling) {
146 | if (!isFling && willAnimHead) {
147 | cp.getAnimProcessor().dealPullDownRelease();
148 | }
149 | if (!isFling && willAnimBottom) {
150 | cp.getAnimProcessor().dealPullUpRelease();
151 | }
152 | willAnimHead = false;
153 | willAnimBottom = false;
154 | }
155 |
156 | @Override
157 | public void onFingerScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY, float velocityX, float velocityY) {
158 | //手指在屏幕上滚动,如果此时正处在刷新状态,可隐藏
159 | int mTouchSlop = cp.getTouchSlop();
160 | if (cp.isRefreshVisible() && distanceY >= mTouchSlop && !cp.isOpenFloatRefresh()) {
161 | cp.getAnimProcessor().animHeadHideByVy((int) velocityY);
162 | }
163 | if (cp.isLoadingVisible() && distanceY <= -mTouchSlop) {
164 | cp.getAnimProcessor().animBottomHideByVy((int) velocityY);
165 | }
166 | }
167 |
168 | @Override
169 | public void onFingerFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
170 | }
171 | }
172 |
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/DensityUtil.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.utils;
2 |
3 | import android.content.Context;
4 |
5 | public class DensityUtil {
6 |
7 | /**
8 | * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
9 | */
10 | public static int dp2px(Context context, float dpValue) {
11 | final float scale = context.getResources().getDisplayMetrics().density;
12 | return (int) (dpValue * scale + 0.5f);
13 | }
14 |
15 | /**
16 | * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
17 | */
18 | public static int px2dp(Context context, float pxValue) {
19 | final float scale = context.getResources().getDisplayMetrics().density;
20 | return (int) (pxValue / scale + 0.5f);
21 | }
22 | }
--------------------------------------------------------------------------------
/library/src/main/java/com/lcodecore/tkrefreshlayout/utils/LogUtil.java:
--------------------------------------------------------------------------------
1 | package com.lcodecore.tkrefreshlayout.utils;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Created by lcodecore on 2017/4/1.
7 | */
8 |
9 | public class LogUtil {
10 | private static final boolean DEBUG = false;
11 |
12 | public static void i(String msg) {
13 | if (!DEBUG) return;
14 | Log.i("TwinklingRefreshLayout", msg);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/library/src/main/res/drawable-xhdpi/ic_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/drawable-xhdpi/ic_arrow.png
--------------------------------------------------------------------------------
/library/src/main/res/drawable/anim_loading_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
11 |
14 |
17 |
20 |
23 |
26 |
29 |
32 |
35 |
38 |
41 |
42 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/view_bezier.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
11 |
12 |
13 |
19 |
20 |
21 |
27 |
28 |
32 |
33 |
--------------------------------------------------------------------------------
/library/src/main/res/layout/view_sinaheader.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
12 |
18 |
19 |
26 |
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_head_arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_head_arrow.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading01.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading02.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading03.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading04.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading04.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading05.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading06.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading06.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading07.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading07.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading08.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading09.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading09.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading10.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading11.png
--------------------------------------------------------------------------------
/library/src/main/res/mipmap-hdpi/refresh_loading12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lcodecorex/TwinklingRefreshLayout/e3091242898af87ddc6e7452576ab99e94a81ef1/library/src/main/res/mipmap-hdpi/refresh_loading12.png
--------------------------------------------------------------------------------
/library/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/library/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #e75946
4 | #f4d227
5 | #4674e7
6 | #0ba62c
7 |
--------------------------------------------------------------------------------
/library/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/library/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Library
3 |
4 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':library'
2 |
--------------------------------------------------------------------------------