diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..7387295f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,5 @@ +# These are supported funding model platforms + +custom: https://www.paypal.me/scwang90 + + diff --git a/.gitignore b/.gitignore index 07487450..9816f370 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,8 @@ *.iml -.gradle -gradle +*.txt +.* +repo +release +build /local.properties -/.idea -/build -/gradlew -/gradlew.bat \ No newline at end of file +/bintrayUpload-key.bat diff --git a/README.md b/README.md index 9ba9d230..0c8affca 100644 --- a/README.md +++ b/README.md @@ -1,157 +1,241 @@ -# Android Smart Refresh Layout Framework -[![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) -[![Download](https://api.bintray.com/packages/scwang90/maven/SmartRefreshLayout/images/download.svg) ](https://bintray.com/scwang90/maven/SmartRefreshLayout/_latestVersion) -[![API](https://img.shields.io/badge/API-12%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=12) -[![Author](https://img.shields.io/badge/Author-scwang90-11bbff.svg)](https://github.com/scwang90) - -## English | [中文](README_CN.md) - -As the name says, SmartRefreshLayout is a "smart" refresh layout,Because of its "smart", it does not just support all the View as other refresh layouts said, but also support multi-layered nested view structures. -In addition to "smart", SmartRefreshLayout also has a lot of features. -It extends from ViewGroup rather than the other FrameLayout or LinearLayout, improving performance. -It absorbs the advantages of various refresh layout in fashion now,Including Google official [SwipeRefreshLayout](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html)、[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout) 、[Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh)。Also integrates various cool Header and Footer. -SmartRefreshLayout's goal is to build a strong, stable and mature refresh layout framework, and integrate all kinds of cool and diverse, practical, beautiful Header and Footer. - -## Features - - - Support all of the View (AbsListView RecyclerView WebView... View) and multi-layered nested view structures. - - Support custom Header and Footer, and has integrated a lot of cool Header and Footer. - - Support synchronous scrolling with ListView and NestedScrolling width RecyclerView、AppBarLayout、CoordinatorLayout. - - Support preview in the Android Studio xml editor. - - Support three ways (default、xml、java) to set the Header and Footer. - - Support automatic refresh, automatic loading (automatic detection list, scroll to the bottom without having to manually pull). - - Support generic refresh listener (OnRefreshListener) and more detailed scrolling listener (OnMultiPurposeListener). - - Support custom rebound animation interpolator, to achieve a variety of cool animation effects. - - Support set the theme to fit any scene of App, won't appear cool but very awkward situation. - - Support for setting a variety of transformations (Translation, stretching, behind the fixed, top fixed, full screen) for Header and Footer. - - Support content size adaptation (wrap_content). - - Support rewrite and extension, internal implementation without private methods and fields. - - Support cross-border rebound (Listview、RecyclerView、ScrollView、WebView...View). - -## Gateway - - - [Smart place](art/md_smart.md) - - [Update log](art/md_update.md) - - [Attribute method](art/md_property.md) - - [Blog posts](https://segmentfault.com/a/1190000010066071) - +# Android智能下拉刷新框架-SmartRefreshLayout + +[![License](https://img.shields.io/badge/License%20-Apache%202-337ab7.svg)](https://www.apache.org/licenses/LICENSE-2.0) +[![Arsenal](https://img.shields.io/badge/Arsenal%20-%20SmartRefresh-4cae4c.svg)](https://android-arsenal.com/details/1/6001) +[![JCenter](https://img.shields.io/badge/%20JCenter%20-2.0.3-5bc0de.svg)](https://bintray.com/scwang90/maven/refresh-layout-kernel/_latestVersion) +[![MinSdk](https://img.shields.io/badge/%20MinSdk%20-%2012%2B%20-f0ad4e.svg)](https://android-arsenal.com/api?level=12) +[![Methods](https://img.shields.io/badge/Methods%20%7C%20Size%20-%20784%20%7C%20121%20KB-d9534f.svg)](http://www.methodscount.com/?lib=com.scwang.smartrefresh%3ASmartRefreshLayout%3A1.0.4) + +## [English](README_EN.md) | 中文 + +SmartRefreshLayout以打造一个强大,稳定,成熟的下拉刷新框架为目标,并集成各种的炫酷、多样、实用、美观的Header和Footer。 +正如名字所说,SmartRefreshLayout是一个“聪明”或者“智能”的下拉刷新布局,由于它的“智能”,它不只是支持所有的View,还支持多层嵌套的视图结构。 +它继承自ViewGroup 而不是FrameLayout或LinearLayout,提高了性能。 +也吸取了现在流行的各种刷新布局的优点,包括谷歌官方的 [SwipeRefreshLayout](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html), +其他第三方的 [Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh)、[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout) 。 +还集成了各种炫酷的 Header 和 Footer。 + +## 国内加速 + +github 由于你懂的原因,下载速度缓慢,图片也无法查看,可以跳转 [国内镜像](https://gitee.com/scwang90/SmartRefreshLayout) + +## 特点功能: + + - 支持多点触摸 + - 支持淘宝二楼和二级刷新 + - 支持嵌套多层的视图结构 Layout (LinearLayout,FrameLayout...) + - 支持所有的 View(AbsListView、RecyclerView、WebView....View) + - 支持自定义并且已经集成了很多炫酷的 Header 和 Footer. + - 支持和 ListView 的无缝同步滚动 和 CoordinatorLayout 的嵌套滚动 . + - 支持自动刷新、自动上拉加载(自动检测列表惯性滚动到底部,而不用手动上拉). + - 支持自定义回弹动画的插值器,实现各种炫酷的动画效果. + - 支持设置主题来适配任何场景的 App,不会出现炫酷但很尴尬的情况. + - 支持设多种滑动方式:平移、拉伸、背后固定、顶层固定、全屏 + - 支持所有可滚动视图的越界回弹 + - 支持 Header 和 Footer 交换混用 + - 支持 AndroidX + - 支持[横向刷新](https://github.com/scwang90/SmartRefreshHorizontal) + +## 传送门 + + - [属性文档](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_property.md) + - [常见问题](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_faq.md) + - [智能之处](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_smart.md) + - [更新日志](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_update.md) + - [博客文章](https://segmentfault.com/a/1190000010066071) + - [源码下载](https://github.com/scwang90/SmartRefreshLayout/releases) + - [多点触摸](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_multitouch.md) + - [自定义Header](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_custom.md) + ## Demo -[Download APK-Demo](art/app-debug.apk) +[下载 APK-Demo](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/app-debug.apk) + +![](https://scwang90.github.io/assets/refresh-layout/png_apk_rqcode.png) + +#### 项目演示 +|个人首页|微博列表| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_practive_weibo_new.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_practive_feedlist_new.gif)| -![](art/png_apk_rqcode.png) +|餐饮美食|个人中心| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_practive_repast_new.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_practive_profile.gif)| -#### Practical -![](art/gif_practive_weibo.gif) ![](art/gif_practive_feedlist.gif) +#### 样式演示 Style +|Delivery|DropBox| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_Delivery.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_Dropbox.gif)| +|[Refresh-your-delivery](https://dribbble.com/shots/2753803-Refresh-your-delivery)|[Dropbox-Refresh](https://dribbble.com/shots/3470499-DropBox-Refresh)| -![](art/gif_practive_repast.gif) ![](art/gif_practive_profile.gif) +上面这两个是我自己实现的,下面的是我把github上其它优秀的Header进行的整理和集合还有优化: -#### Style -![](art/gif_Delivery.gif) ![](art/gif_Dropbox.gif) +|BezierRadar|BezierCircle| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_BezierRadar.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_BezierCircle.gif)| +|[Pull To Refresh](https://dribbble.com/shots/1936194-Pull-To-Refresh)|[Pull Down To Refresh](https://dribbble.com/shots/1797373-Pull-Down-To-Refresh)| -The two above is my own implementation of the Header, the design comes from: [Refresh-your-delivery](https://dribbble.com/shots/2753803-Refresh-your-delivery),[Dropbox-Refresh](https://dribbble.com/shots/3470499-Dropbox-Refresh) +|FlyRefresh|Classics| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_FlyRefresh.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_Classics.gif)| +|[FlyRefresh](https://github.com/race604/FlyRefresh)|[ClassicsHeader](#1)| -![](art/gif_BezierRadar.gif) ![](art/gif_Circle.gif) +|Phoenix|Taurus| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_Phoenix.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_Taurus.gif)| +|[Yalantis/Phoenix](https://github.com/Yalantis/Phoenix)|[Yalantis/Taurus](https://github.com/Yalantis/Taurus) -[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout/blob/master/art/gif_recyclerview2.gif),[Pull Down To Refresh](https://dribbble.com/shots/1797373-Pull-Down-To-Refresh) +|BattleCity|HitBlock| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_BattleCity.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_HitBlock.gif)| +|[FunGame/BattleCity](https://github.com/Hitomis/FunGameRefresh)|[FunGame/HitBlock](https://github.com/Hitomis/FunGameRefresh) -![](art/gif_FlyRefresh.gif) ![](art/gif_Classics.gif) +|WaveSwipe|Material| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_WaveSwipe.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_Material.gif)| +|[WaveSwipeRefreshLayout](https://github.com/recruit-lifestyle/WaveSwipeRefreshLayout)|[MaterialHeader](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html) -[FlyRefresh](https://github.com/race604/FlyRefresh),[ClassicsHeader](#1) +|StoreHouse|WaterDrop| +|:---:|:---:| +|![](https://scwang90.github.io/assets/refresh-layout/gif_StoreHouse.gif)|![](https://scwang90.github.io/assets/refresh-layout/gif_WaterDrop.gif)| +|[CRefreshLayout](https://github.com/cloay/CRefreshLayout)|[WaterDrop](https://github.com/THEONE10211024/WaterDropListView) -![](art/gif_Phoenix.gif) ![](art/gif_Taurus.gif) -[Yalantis/Phoenix](https://github.com/Yalantis/Phoenix),[Yalantis/Taurus](https://github.com/Yalantis/Taurus) +看到这么多炫酷的Header,是不是觉得很棒?这时你或许会担心这么多的Header集成在一起,但是平时只会用到一个,是不是要引入很多无用的代码和资源? +V2.x 版本已经把依赖库拆分成8个包啦,用到的时候自行引用就可以啦! -![](art/gif_BattleCity.gif) ![](art/gif_HitBlock.gif) + - refresh-layout-kernel 核心必须依赖 + - refresh-header-classics 经典刷新头 + - refresh-header-radar 雷达刷新头 + - refresh-header-falsify 虚拟刷新头 + - refresh-header-material 谷歌刷新头 + - refresh-header-two-level 二级刷新头 + - refresh-footer-ball 球脉冲加载 + - refresh-footer-classics 经典加载 -[FunGame/BattleCity](https://github.com/Hitomis/FunGameRefresh),[FunGame/HitBlock](https://github.com/Hitomis/FunGameRefresh) +## 简单用例 +#### 1.在 build.gradle 中添加依赖 -![](art/gif_WaveSwipe.gif) ![](art/gif_Material.gif) +[【V1.1.0】](https://github.com/scwang90/SmartRefreshLayout/tree/1.x#%E7%AE%80%E5%8D%95%E7%94%A8%E4%BE%8B) 如果正在使用1.x 版本请调转,当前2.0 版本已经重定制,不支持升级,请在新项目中使用。 + +V2.x 相对于 V1.x 对包名做了修改如:com.scwang.smartrefresh 改为 com.scwang.smart.refresh。 +建议在新项目中使用,如果项目升级,java,xml 中都需要做包名替换,比较麻烦。 +但主要改动还是对 Smart 进行分包,减小不必要的依赖,比如不使用二级刷新就不依赖,避免代码冗余。 +但是未对 SmartRefreshHeader 分包,里面有十多个Header,建议需要使用哪个就复制哪个的源码到项目中。 +当然:大家也可以在讨论区讨论投票,选出里面使用频率比较高的Header,然后单独分离出来。 + +``` +compile 'com.android.support:appcompat-v7:25.3.1' //必须 25.3.1 以上 -[WaveSwipeRefreshLayout](https://github.com/recruit-lifestyle/WaveSwipeRefreshLayout),[MaterialHeader](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html) +// 注意:分包之后不会有默认的Header和Footer需要手动添加!还是原来的三种方法! +implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' //核心必须依赖 +implementation 'com.scwang.smart:refresh-header-classics:2.0.3' //经典刷新头 +implementation 'com.scwang.smart:refresh-header-radar:2.0.3' //雷达刷新头 +implementation 'com.scwang.smart:refresh-header-falsify:2.0.3' //虚拟刷新头 +implementation 'com.scwang.smart:refresh-header-material:2.0.3' //谷歌刷新头 +implementation 'com.scwang.smart:refresh-header-two-level:2.0.3' //二级刷新头 +implementation 'com.scwang.smart:refresh-footer-ball:2.0.3' //球脉冲加载 +implementation 'com.scwang.smart:refresh-footer-classics:2.0.3' //经典加载 -![](art/gif_StoreHouse.gif) ![](art/gif_WaterDrop.gif) -[Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh),[WaterDrop](https://github.com/THEONE10211024/WaterDropListView) +``` +如果使用 AndroidX 先在 gradle.properties 中添加,两行都不能少噢~ -See so many cool headers, is not it feel great? At this point you may be worried that so many headers together, but usually only use one, is not to introduce a lot of useless code and resources? -Please rest assured that I have divided it into three packages, when used to reference their own it! +``` +android.useAndroidX=true +android.enableJetifier=true - - **SmartRefreshLayout:** The core to realize,Bring ClassicsHeader and BezierRadarHeader. - - **SmartRefreshHeader:** Integration of various kinds of the Header. - - **SmartRefreshFooter:** Integration of various kinds of the Footer. +``` -## Usage -#### 1.Add a gradle dependency. +需要依赖 androidx.appcompat ``` -compile 'com.android.support:appcompat-v7:25.3.1' -compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.2-alpha-8' -compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.2-alpha-8'//If you use the special Header +implementation 'androidx.appcompat:appcompat:1.0.0' //必须 1.0.0 以上 + +implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' //核心必须依赖 +implementation 'com.scwang.smart:refresh-header-classics:2.0.3' //经典刷新头 +implementation 'com.scwang.smart:refresh-header-radar:2.0.3' //雷达刷新头 +implementation 'com.scwang.smart:refresh-header-falsify:2.0.3' //虚拟刷新头 +implementation 'com.scwang.smart:refresh-header-material:2.0.3' //谷歌刷新头 +implementation 'com.scwang.smart:refresh-header-two-level:2.0.3' //二级刷新头 +implementation 'com.scwang.smart:refresh-footer-ball:2.0.3' //球脉冲加载 +implementation 'com.scwang.smart:refresh-footer-classics:2.0.3' //经典加载 + ``` -#### 2.Add SmartRefreshLayout in the layout xml. +#### 2.在XML布局文件中添加 SmartRefreshLayout ```xml - + - + + ``` -#### 3.Coding in the Activity or Fragment. +#### 3.在 Activity 或者 Fragment 中添加代码 ```java RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); +refreshLayout.setRefreshHeader(new ClassicsHeader(this)); +refreshLayout.setRefreshFooter(new ClassicsFooter(this)); refreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override public void onRefresh(RefreshLayout refreshlayout) { - refreshlayout.finishRefresh(2000).setSpinnerStyle(SpinnerStyle.Translate); + refreshlayout.finishRefresh(2000/*,false*/);//传入false表示刷新失败 } }); -refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() { +refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { @Override - public void onLoadmore(RefreshLayout refreshlayout) { - refreshlayout.finishLoadmore(2000).setSpinnerStyle(SpinnerStyle.Translate); + public void onLoadMore(RefreshLayout refreshlayout) { + refreshlayout.finishLoadMore(2000/*,false*/);//传入false表示加载失败 } }); ``` -## Use the specified Header and Footer +## 使用指定的 Header 和 Footer -#### 1.Global settings +#### 1.方法一 全局设置 ```java public class App extends Application { - public void onCreate() { - super.onCreate(); - SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() { + //static 代码段可以防止内存泄露 + static { + //设置全局的Header构建器 + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { @Override public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { - return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate); + layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色 + return new ClassicsHeader(context);//.setTimeFormat(new DynamicTimeFormat("更新于 %s"));//指定为经典Header,默认是 贝塞尔雷达Header } }); - SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() { + //设置全局的Footer构建器 + SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() { @Override public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { - return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate); + //指定为经典Footer,默认是 BallPulseFooter + return new ClassicsFooter(context).setDrawableSize(20); } }); } } ``` -Note: this method is the lowest priority. +注意:方法一 设置的Header和Footer的优先级是最低的,如果同时还使用了方法二、三,将会被其它方法取代 -#### 2.Specified in the XML layout file +#### 2.方法二 XML布局文件指定 ```xml - - - - + + - - + ``` -Note: this method of priority is medium。When using this method, the Android Studio will have preview effect, the following figure: +注意:方法二 XML设置的Header和Footer的优先级是中等的,会被方法三覆盖。而且使用本方法的时候,Android Studio 会有预览效果,如下图: -![](art/jpg_preview_xml_define.jpg) +![](https://scwang90.github.io/assets/refresh-layout/jpg_preview_xml_define.jpg) -But don't worry, just a preview effect, run only the drop-down will appear. +不过不用担心,只是预览效果,运行的时候只有下拉才会出现~ -#### 3.Specified in the java code +#### 3.方法三 Java代码设置 ```java final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); -refreshLayout.setRefreshHeader(new MaterialHeader(this).setShowBezierWave(true)); +//设置 Header 为 贝塞尔雷达 样式 +refreshLayout.setRefreshHeader(new BezierRadarHeader(this).setEnableHorizontalDrag(true)); +//设置 Footer 为 球脉冲 样式 refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale)); ``` -## Proguard - -This library does't use serialization and deserialization, JNI, reflection, so there is no need to add confusing filtering code, and it has been confusing tests pass, if you after the confusion in the use of the project appear problem, please inform me. - -## Donate - -If you like this library's design, feel it help to you, you can point the upper right corner "Star" support Thank you! ^ _ ^ -You can also scan the qr code below to ask the author to drink a cup of coffee. - -![](art/pay_alipay.jpg) ![](art/pay_wxpay.jpg) - -If in the donation message note name, will be record to the list -[Donation list](art/md_donationlist.md) - -## Discuss - -Contact me: scwang90@hotmail.com QQ group: 602537182 -The answers to the join the group can be found in this document~ - -## Thanks +#### 4.更多使用说明 + + - [属性文档](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_property.md) + - [常见问题](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_faq.md) + - [自定义Header](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_custom.md) + +## 混淆 + +SmartRefreshLayout 不需要添加混淆过滤代码,并且已经混淆测试通过,如果你在项目的使用中混淆之后出现问题,请及时通知我。 + +## 赞赏 + +如果你喜欢 SmartRefreshLayout 的设计,感觉 SmartRefreshLayout 帮助到了你,可以点右上角 "Star" 支持一下 谢谢! ^_^ +你也还可以扫描下面的二维码~ 请作者喝一杯咖啡。 + +![](https://scwang90.github.io/assets/refresh-layout/pay_alipay.jpg?raw=true) ![](https://scwang90.github.io/assets/refresh-layout/pay_wxpay.jpg?raw=true) ![](https://scwang90.github.io/assets/refresh-layout/pay_tencent.jpg?raw=true) + +> 如果希望捐赠之后能获得相关的帮助,可以选择加入下面的付费群来取代普通捐赠,付费群可以直接获得作者的直接帮助,与问题反馈。 + +如果在捐赠留言中备注名称,将会被记录到列表中~ 如果你也是github开源作者,捐赠时可以留下github项目地址或者个人主页地址,链接将会被添加到列表中起到互相推广的作用 +[捐赠列表](https://github.com/scwang90/SmartRefreshLayout/blob/master/art/md_donationlist.md) + +#### 友情链接 +[github/afKT/DevUtils](https://github.com/afKT/DevUtils) +[github/Loror](https://github.com/Loror) +[github/faith-hb/WidgetCase](https://github.com/faith-hb/WidgetCase) +[github/Bamboy120315/Freedom](https://github.com/Bamboy120315/Freedom) +[github/TommyLemon/APIJSON](https://github.com/TommyLemon/APIJSON) +[github/dengyuhan](https://github.com/dengyuhan) +[github/zrp2017](https://github.com/zrp2017) +[github/fly803/BaseProject](https://github.com/fly803/BaseProject) +[github/razerdp](https://github.com/razerdp) +[github/SuperChenC/s-mvp](https://github.com/SuperChenC/s-mvp) +[github/KingJA/LoadSir](https://github.com/KingJA/LoadSir) +[github/jianshijiuyou](https://github.com/jianshijiuyou) +[github/zxy198717](https://github.com/zxy198717) +[github/addappcn](https://github.com/addappcn) +[github/RainliFu](https://github.com/RainliFu) +[github/sugarya](https://github.com/sugarya) +[github/stormzhang](https://github.com/stormzhang) + +## 讨论 + +### QQ解决群 - 602537182 (付费) +#### 进群须知 +自开群以来,还是有很多的朋友提出了很多问题,我也解决了很多问题,其中有大半问题是本库的Bug导致,也有些是使用者项目本 +身的环境问题,这花费了我大量的时间,经过我的观察和测试,到目前为止,本库的bug已经越来越少,当然不能说完全没有,但是 +已经能满足很大部分项目的需求。所以从现在起,我做出一个决定:把之前的讨论群改成解决群,并开启付费入群功能,专为解决大 +家在使用本库时遇到的问题,不管是本库bug还是,特殊的项目环境导致(包含项目本身的bug)。 +我也有自己的工作和娱乐时间,只有大家理解和支持我,我才能专心的为大家解决问题。不过用担心,我已经建立了另一个可以免费 +进入的QQ讨论群。 + +### QQ讨论群 - 914275312 (新) 477963933 (满) 538979188 (满) +#### 进群须知 +这个群,免费进入,大家可以相互讨论本库的相关使用和出现的问题,群主也会在里面解决问题,如果提出的问题,群成员不能帮助 +解决,需要群主解决,但是要花费群主五分钟以上的时间(本库Bug除外),群主将不会解决这个问题,如果项目紧急,请付费进入解 +决群解决(不过注意,付费群中群主会很认真很努力的解决问题,但也不能保证已经能完美解决)或者转换使用其他的刷新库。 + + +#### 温馨提示 +加入群的答案在本文档中可以找到~ + +## 其他作品 +[MultiWaveHeader](https://github.com/scwang90/MultiWaveHeader) +[SmartRefreshHorizontal](https://github.com/scwang90/SmartRefreshHorizontal) +[诗和远方](http://android.myapp.com/myapp/detail.htm?apkName=com.poetry.kernel) + +## 感谢 [SwipeRefreshLayout](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html) +[Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh) [TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout) -[android-Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh) +[BeautifulRefreshLayout](https://github.com/android-cjj/BeautifulRefreshLayout) License ------- @@ -229,4 +364,4 @@ License distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file + limitations under the License. diff --git a/README_CN.md b/README_CN.md deleted file mode 100644 index c4a1cc2d..00000000 --- a/README_CN.md +++ /dev/null @@ -1,259 +0,0 @@ -# Android智能下拉刷新框架-SmartRefreshLayout -[![License](https://img.shields.io/badge/license-Apache%202-green.svg)](https://www.apache.org/licenses/LICENSE-2.0) -[![Download](https://api.bintray.com/packages/scwang90/maven/SmartRefreshLayout/images/download.svg) ](https://bintray.com/scwang90/maven/SmartRefreshLayout/_latestVersion) -[![API](https://img.shields.io/badge/API-12%2B-brightgreen.svg?style=flat)](https://android-arsenal.com/api?level=12) -[![Author](https://img.shields.io/badge/Author-scwang90-11bbff.svg)](https://github.com/scwang90) - - -## [English](README.md) | 中文 - -正如名字所说,SmartRefreshLayout是一个“聪明”或者说“智能”的下拉刷新布局,由于它的“智能”,它不只是如其它的刷新布局所说的支持所有的View,还支持多层嵌套的视图结构。 除了“聪明”之外,SmartRefreshLayout还具备了很多的特点。 -它继承自ViewGroup 而不是其它的FrameLayout或者LinearLayout,提高了性能。 -吸取了现在流行的各种刷新布局的优点,包括谷歌官方的 SwipeRefreshLayout,现在非常流行的 [TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout) 、[Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh)。还集成了各种炫酷的 Header 和 Footer。 -SmartRefreshLayout的目标是打造一个强大,稳定,成熟的下拉刷新框架,并集成各种的炫酷、多样、实用、美观的Header和Footer。 - -## 特点功能: - - - 支持所有的 View(AbsListView、RecyclerView、WebView....View) 和多层嵌套的视图结构 - - 支持自定义并且已经集成了很多炫酷的 Header 和 Footer (图). - - 支持和ListView的同步滚动 和 RecyclerView、AppBarLayout、CoordinatorLayout 的嵌套滚动 NestedScrolling. - - 支持在Android Studio Xml 编辑器中预览 效果(图) - - 支持分别在 Default(默认)、Xml、JavaCode 三个中设置 Header 和 Footer. - - 支持自动刷新、自动上拉加载(自动检测列表滚动到底部,而不用手动上拉). - - 支持通用的刷新监听器 OnRefreshListener 和更详细的滚动监听 OnMultiPurposeListener. - - 支持自定义回弹动画的插值器,实现各种炫酷的动画效果. - - 支持设置主题来适配任何场景的App,不会出现炫酷但很尴尬的情况. - - 支持设置多种滑动方式来适配各种效果的Header和Footer:平移、拉伸、背后固定、顶层固定、全屏 - - 支持内容尺寸自适应 Content-wrap_content - - 支持继承重写和扩展功能,内部实现没有 private 方法和字段,继承之后都可以重写覆盖 - - 支持越界回弹(Listview、RecyclerView、ScrollView、WebView...View) - -## 传送门 - - - [智能之处](art/md_smart.md) - - [更新日志](art/md_update.md) - - [属性方法](art/md_property.md) - - [博客文章](https://segmentfault.com/a/1190000010066071) - - [自定义Header](art/md_custom.md) - -## Demo -[下载 APK-Demo](art/app-debug.apk) - -![](art/png_apk_rqcode.png) - -#### 项目演示 -![](art/gif_practive_weibo.gif) ![](art/gif_practive_feedlist.gif) - -![](art/gif_practive_repast.gif) ![](art/gif_practive_profile.gif) - -#### 风格演示 -![](art/gif_Delivery.gif) ![](art/gif_Dropbox.gif) - -上面这两个是我自己实现的Header,设计来自:[Refresh-your-delivery](https://dribbble.com/shots/2753803-Refresh-your-delivery),[Dropbox-Refresh](https://dribbble.com/shots/3470499-Dropbox-Refresh) - -下面的Header是我把github上其它优秀的Header进行的整理和集合还有优化: - -![](art/gif_BezierRadar.gif) ![](art/gif_Circle.gif) - -整理来自:[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout/blob/master/art/gif_recyclerview2.gif),[Pull Down To Refresh](https://dribbble.com/shots/1797373-Pull-Down-To-Refresh) - -![](art/gif_FlyRefresh.gif) ![](art/gif_Classics.gif) - -整理来自:[FlyRefresh](https://github.com/race604/FlyRefresh),[ClassicsHeader](#1) - -![](art/gif_Phoenix.gif) ![](art/gif_Taurus.gif) - -整理来自:[Yalantis/Phoenix](https://github.com/Yalantis/Phoenix),[Yalantis/Taurus](https://github.com/Yalantis/Taurus) - -![](art/gif_BattleCity.gif) ![](art/gif_HitBlock.gif) - -整理来自:[FunGame/BattleCity](https://github.com/Hitomis/FunGameRefresh),[FunGame/HitBlock](https://github.com/Hitomis/FunGameRefresh) - -![](art/gif_WaveSwipe.gif) ![](art/gif_Material.gif) - -整理来自:[WaveSwipeRefreshLayout](https://github.com/recruit-lifestyle/WaveSwipeRefreshLayout),[MaterialHeader](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html) - -![](art/gif_StoreHouse.gif) ![](art/gif_WaterDrop.gif) - -整理来自:[Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh),[WaterDrop](https://github.com/THEONE10211024/WaterDropListView) - - -看到这么多炫酷的Header,是不是觉得很棒?这时你或许会担心这么多的Header集成在一起,但是平时只会用到一个,是不是要引入很多无用的代码和资源? -请放心,我已经把刷新布局分成三个包啦,用到的时候自行引用就可以啦! - - - SmartRefreshLayout 刷新布局核心实现,自带ClassicsHeader(经典)、BezierRadarHeader(贝塞尔雷达)两个 Header. - - SmartRefreshHeader 各种Header的集成,除了Layout自带的Header,其它都在这个包中. - - SmartRefreshFooter 各种Footer的集成,除了Layout自带的Footer,其它都在这个包中. - -## 简单用例 -#### 1.在 buld.gradle 中添加依赖 -``` -compile 'com.android.support:appcompat-v7:25.3.1' -compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.2-alpha-8' -compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.2-alpha-8'//如果使用了特殊的Header -``` - -#### 2.在XML布局文件中添加 SmartRefreshLayout -```xml - - - - -``` - -#### 3.在 Activity 或者 Fragment 中添加代码 -```java -RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); -refreshLayout.setOnRefreshListener(new OnRefreshListener() { - @Override - public void onRefresh(RefreshLayout refreshlayout) { - refreshlayout.finishRefresh(2000); - } -}); -refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() { - @Override - public void onLoadmore(RefreshLayout refreshlayout) { - refreshlayout.finishLoadmore(2000); - } -}); -``` - -## 使用指定的 Header 和 Footer - -#### 1.方法一 全局设置 -```java -public class App extends Application { - public void onCreate() { - super.onCreate(); - //设置全局的Header构建器 - SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() { - @Override - public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { - //指定为经典Header,默认是 贝塞尔雷达Header - return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate); - } - }); - //设置全局的Footer构建器 - SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() { - @Override - public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { - //指定为经典Footer,默认是 BallPulseFooter - return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate); - } - }); - } -} -``` - -注意:方法一 设置的Header和Footer的优先级是最低的,如果同时还使用了方法二、三,将会被其它方法取代 - - -#### 2.方法二 XML布局文件指定 -```xml - - - - - - - -``` - -注意:方法二 XML设置的Header和Footer的优先级是中等的,会被方法三覆盖。而且使用本方法的时候,Android Studio 会有预览效果,如下图: - -![](art/jpg_preview_xml_define.jpg) - -不过不用担心,只是预览效果,运行的时候只有下拉才会出现~ - -#### 3.方法三 Java代码设置 -```java -final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); -//设置 Header 为 Material风格 -refreshLayout.setRefreshHeader(new MaterialHeader(this).setShowBezierWave(true)); -//设置 Footer 为 球脉冲 -refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale)); -``` - -## 混淆 - -SmartRefreshLayout 没有使用到:序列化、反序列化、JNI、反射,所以并不需要添加混淆过滤代码,并且已经混淆测试通过,如果你在项目的使用中混淆之后出现问题,请及时通知我。 - -## 赞赏 - -如果你喜欢 SmartRefreshLayout 的设计,感觉 SmartRefreshLayout 帮助到了你,可以点右上角 "Star" 支持一下 谢谢! ^_^ -你也还可以扫描下面的二维码~ 请作者喝一杯咖啡。 - -![](art/pay_alipay.jpg) ![](art/pay_wxpay.jpg) - -如果在捐赠留言中备注名称,将会被记录到列表中~ 如果你也是github开源作者,捐赠时可以留下github项目地址或者个人主页地址,链接将会被添加到列表中起到互相推广的作用 -[捐赠列表](art/md_donationlist.md) - -## 讨论 - - - - - - - - - - -### QQ讨论群 - 602537182 -#### 进群须知 - - - - - - -本群专为 【Android智能下拉刷新框架-SmartRefreshLayout】开设,请不要讨论安卓和下拉刷新之外的内容。本群中后期会改为收费咨询群,并再开启免费讨论群,还没进群的童鞋赶紧~ -#### 温馨提示 -加入群的答案在本文档中可以找到~ - -## 感谢 -[SwipeRefreshLayout](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html) -[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout) -[android-Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh) - -License -------- - - Copyright 2017 scwang90 - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/README_EN.md b/README_EN.md new file mode 100644 index 00000000..accfcd69 --- /dev/null +++ b/README_EN.md @@ -0,0 +1,308 @@ +# SmartRefreshLayout + +[![License](https://img.shields.io/badge/License%20-Apache%202-337ab7.svg)](https://www.apache.org/licenses/LICENSE-2.0) +[![Arsenal](https://img.shields.io/badge/Arsenal%20-%20SmartRefresh-4cae4c.svg)](https://android-arsenal.com/details/1/6001) +[![JCenter](https://img.shields.io/badge/%20Jcenter%20-2.0.3-5bc0de.svg)](https://bintray.com/scwang90/maven/refresh-layout-kernel/_latestVersion) +[![MinSdk](https://img.shields.io/badge/%20MinSdk%20-%2012%2B%20-f0ad4e.svg)](https://android-arsenal.com/api?level=12) +[![Methods](https://img.shields.io/badge/Methods%20%7C%20Size%20-%20784%20%7C%20122%20KB-d9534f.svg)](http://www.methodscount.com/?lib=com.scwang.smartrefresh%3ASmartRefreshLayout%3A1.1.0) + +## English | [中文](README.md) + +SmartRefreshLayout's goal is to build a strong, stable and mature pull-down refresh layout framework, and to integrate all kinds of cool, diverse, practical and beautiful Headers and Footers. + +## Features + + - Support multi-touch. + - Support multi-layered nested view structures. + - Support all the Views(AbsListView、RecyclerView、WebView....View) + - Support customizing Headers and Footers, and has integrated a lot of cool Headers and Footers. + - Support synchronous scrolling with ListView and NestedScrolling with CoordinatorLayout. + - Support automatically refresh, automatically pull-up loading (automatically detect list inertance and scroll to the bottom without having to manually pull). + - Support customizing rebound animation interpolator, to achieve a variety of cool animation effects. + - Support setting a theme to fit any scene of App, it won't appear a cool but very awkward situation. + - Support setting a variety of transformations (Translation, stretching, behind fixed, top fixed, full screen view) for Headers and Footers. + - Support rewrite and extension, internal implementation without private methods and fields. + - Support automatically cross-border rebound for all rolling Views (ListView、RecyclerView、ScrollView、WebView...View). + - Support the interchange of Header and Footer + - Support AndroidX + - Support [HorizontalRefresh](https://github.com/scwang90/SmartRefreshHorizontal) + +## Gateway + + - [Smart place](art/md_smart.md) + - [Update log](art/md_update.md) + - [Attribute method](art/md_property.md) + - [Blog posts](https://segmentfault.com/a/1190000010066071) + - [Download the source code](https://github.com/scwang90/SmartRefreshLayout/releases) + - [Multi-touch](art/md_multitouch.md) +## Demo +[Download APK-Demo](art/app-debug.apk) + +![](art/png_apk_rqcode.png) + +#### Practical +|Weibo|FeedList| +|:---:|:---:| +|![](art/gif_practive_weibo.gif)|![](art/gif_practive_feedlist.gif)| + +|Repast|Profile| +|:---:|:---:| +|![](art/gif_practive_repast.gif)|![](art/gif_practive_profile.gif)| + +#### Style + +|Style|Delivery|DropBox| +|:---:|:---:|:---:| +|Demo|![](art/gif_Delivery.gif)|![](art/gif_Dropbox.gif)| +|Design|[Refresh-your-delivery](https://dribbble.com/shots/2753803-Refresh-your-delivery)|[DropBox-Refresh](https://dribbble.com/shots/3470499-DropBox-Refresh)| + +The two above headers are implemented by myself, The following headers are collected and optimized from excellent Headers on github + +|Style|BezierRadar|BezierCircle| +|:---:|:---:|:---:| +|Demo|![](art/gif_BezierRadar.gif)|![](art/gif_BezierCircle.gif)| +|From|[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout/blob/master/art/gif_recyclerview2.gif)|[Pull Down To Refresh](https://dribbble.com/shots/1797373-Pull-Down-To-Refresh)| + +|Style|FlyRefresh|Classics| +|:---:|:---:|:---:| +|Demo|![](art/gif_FlyRefresh.gif)|![](art/gif_Classics.gif)| +|From|[FlyRefresh](https://github.com/race604/FlyRefresh)|[ClassicsHeader](#1)| + +|Style|Phoenix|Taurus| +|:---:|:---:|:---:| +|Demo|![](art/gif_Phoenix.gif)|![](art/gif_Taurus.gif)| +|From|[Yalantis/Phoenix](https://github.com/Yalantis/Phoenix)|[Yalantis/Taurus](https://github.com/Yalantis/Taurus) + +|Style|BattleCity|HitBlock| +|:---:|:---:|:---:| +|Demo|![](art/gif_BattleCity.gif)|![](art/gif_HitBlock.gif)| +|From|[FunGame/BattleCity](https://github.com/Hitomis/FunGameRefresh)|[FunGame/HitBlock](https://github.com/Hitomis/FunGameRefresh) + +|Style|WaveSwipe|Material| +|:---:|:---:|:---:| +|Demo|![](art/gif_WaveSwipe.gif)|![](art/gif_Material.gif)| +|From|[WaveSwipeRefreshLayout](https://github.com/recruit-lifestyle/WaveSwipeRefreshLayout)|[MaterialHeader](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html) + +|Style|StoreHouse|WaterDrop| +|:---:|:---:|:---:| +|Demo|![](art/gif_StoreHouse.gif)|![](art/gif_WaterDrop.gif)| +|From|[Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh)|[WaterDrop](https://github.com/THEONE10211024/WaterDropListView) + + +See so many cool headers, is not it feel great? At this point you may be worried that so many headers together, but usually only use one, is not to introduce a lot of useless code and resources? +Please rest assured that I have divided it into eight packages, when used to reference their own it! + + - refresh-layout-kernel core + - refresh-header-classics ClassicsHeader + - refresh-header-radar BezierRadarHeader + - refresh-header-falsify FalsifyHeader + - refresh-header-material MaterialHeader + - refresh-header-two-level TwoLevelHeader + - refresh-footer-ball BallPulseFooter + - refresh-footer-classics ClassicsFooter + +## Usage +#### 1.Add a gradle dependency. + +V 2.x changed the package name relative to 1.x, such as `com.scwang.smartrefresh` to `com.scwang.smart.refresh`. +It is suggested that in the new project, if the old project is upgraded, +the package name should be replaced, which is more troublesome. +But the main change is to subcontract SmartRefreshLayout to reduce unnecessary dependencies and avoid code redundancy. +However, there is no subcontracting to SmartRefreshHeader. +There are more than ten headers in it. +It is recommended that you copy the source code into the project whenever you need to use it. + +``` +// Note: There will be no default Header and Footer after subcontracting. It needs to be added manually! +implementation 'com.scwang.smart:refresh-layout-kernel:2.0.3' //core +implementation 'com.scwang.smart:refresh-header-classics:2.0.3' //ClassicsHeader +implementation 'com.scwang.smart:refresh-header-radar:2.0.3' //BezierRadarHeader +implementation 'com.scwang.smart:refresh-header-falsify:2.0.3' //FalsifyHeader +implementation 'com.scwang.smart:refresh-header-material:2.0.3' //MaterialHeader +implementation 'com.scwang.smart:refresh-header-two-level:2.0.3' //TwoLevelHeader +implementation 'com.scwang.smart:refresh-footer-ball:2.0.3' //BallPulseFooter +implementation 'com.scwang.smart:refresh-footer-classics:2.0.3' //ClassicsFooter + +``` + + + + + +If you use AndroidX, add it to gradle.properties + +``` +android.useAndroidX=true +android.enableJetifier=true +``` + +#### 2.Add SmartRefreshLayout in the layout xml. +```xml + + + + + + +``` + +#### 3.Coding in the Activity or Fragment. +```java +RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); +refreshLayout.setRefreshHeader(new ClassicsHeader(this)); +refreshLayout.setRefreshFooter(new ClassicsFooter(this)); +refreshLayout.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(RefreshLayout refreshlayout) { + refreshlayout.finishRefresh(2000/*,false*/);//传入false表示刷新失败 + } +}); +refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(RefreshLayout refreshlayout) { + refreshlayout.finishLoadMore(2000/*,false*/);//传入false表示加载失败 + } +}); +``` + +## Use the specified Header and Footer + +#### 1.Global settings +```java +public class App extends Application { + public void onCreate() { + super.onCreate(); + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { + @Override + public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { + return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate); + } + }); + SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() { + @Override + public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { + return new ClassicsFooter(context).setSpinnerStyle(SpinnerStyle.Translate); + } + }); + } +} +``` + +Note: this method is the lowest priority. + + +#### 2.Specified in the XML layout file +```xml + + + + + + + +``` + +Note: this method of priority is medium。When using this method, the Android Studio will have preview effect, the following figure: + +![](art/jpg_preview_xml_define.jpg) + +But don't worry, just a preview effect, run only the drop-down will appear. + +#### 3.Specified in the java code +```java +final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); +refreshLayout.setRefreshHeader(new MaterialHeader(this).setShowBezierWave(true)); +refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale)); +``` + +## ProGuard + +This library does't use serialization and deserialization, JNI, reflection, so there is no need to add confusing filtering code, and it has been confusing tests pass, if you after the confusion in the use of the project appear problem, please inform me. + +## Donate + +If you like this library's design, feel it help to you, you can point the upper right corner "Star" support Thank you! ^ _ ^ +You can also click the PayPal below to ask the author to drink a cup of coffee. + +[![](https://www.paypalobjects.com/webstatic/i/logo/rebrand/ppcom.svg 'click to donate')](https://www.paypal.me/scwang90) + +If in the donation message note name, it will be record to the list +[Donation list](art/md_donationlist.md) + +#### blogroll +[github/Loror](https://github.com/Loror) +[github/faith-hb/WidgetCase](https://github.com/faith-hb/WidgetCase) +[github/Bamboy120315/Freedom](https://github.com/Bamboy120315/Freedom) +[github/TommyLemon/APIJSON](https://github.com/TommyLemon/APIJSON) +[github/dengyuhan](https://github.com/dengyuhan) +[github/zrp2017](https://github.com/zrp2017) +[github/fly803/BaseProject](https://github.com/fly803/BaseProject) +[github/razerdp](https://github.com/razerdp) +[github/SuperChenC/s-mvp](https://github.com/SuperChenC/s-mvp) +[github/KingJA/LoadSir](https://github.com/KingJA/LoadSir) +[github/jianshijiuyou](https://github.com/jianshijiuyou) +[github/zxy198717](https://github.com/zxy198717) +[github/addappcn](https://github.com/addappcn) +[github/RainliFu](https://github.com/RainliFu) +[github/sugarya](https://github.com/sugarya) +[github/stormzhang](https://github.com/stormzhang) + +## Discuss + +Contact me: scwang90@hotmail.com + +## Thanks +[SwipeRefreshLayout](https://developer.android.com/reference/android/support/v4/widget/SwipeRefreshLayout.html) +[Ultra-Pull-To-Refresh](https://github.com/liaohuqiu/android-Ultra-Pull-To-Refresh) +[TwinklingRefreshLayout](https://github.com/lcodecorex/TwinklingRefreshLayout) +[BeautifulRefreshLayout](https://github.com/android-cjj/BeautifulRefreshLayout) + +## Other Works +[MultiWaveHeader](https://github.com/scwang90/MultiWaveHeader) +[SmartRefreshHorizontal](https://github.com/scwang90/SmartRefreshHorizontal) + +License +------- + + Copyright 2017 scwang90 + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/app/build.gradle b/app/build.gradle index 4c497cbf..a1c7abce 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,12 +1,14 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + + compileSdkVersion 28 + buildToolsVersion '28.0.3' + defaultConfig { - applicationId "com.scwang.refreshlayout" - minSdkVersion 15 - targetSdkVersion 25 + applicationId "com.scwang.refreshlayout.app" + minSdkVersion 16 + targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" @@ -14,6 +16,7 @@ android { renderscriptTargetApi 25 renderscriptSupportModeEnabled true // Enable RS support + } signingConfigs { debug { @@ -23,42 +26,83 @@ android { keyPassword "android" } } + buildTypes { + debug { + signingConfig = signingConfigs.debug + } release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig = signingConfigs.debug } } + lintOptions { abortOnError false } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } + +repositories { + maven { url "https://jitpack.io" } +} dependencies { - compile fileTree(include: ['*.jar'], dir: 'libs') - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation 'com.android.support:support-v4:28.0.0' + androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - compile project(':refresh-footer') - compile project(':refresh-header') - compile project(':refresh-layout') - // compile 'com.android.support:support-v4:25.3.1' -// compile 'com.android.support:support-vector-drawable:25.3.1' -// compile 'com.android.support:recyclerview-v7:25.3.1' -// compile 'com.android.support.constraint:constraint-layout:1.0.2' - compile 'com.android.support:appcompat-v7:25.3.1' - compile 'com.android.support:cardview-v7:25.3.1' - compile 'com.android.support:design:25.3.1' - compile 'com.flyco.roundview:FlycoRoundView_Lib:1.1.4@aar' - compile 'com.github.mmin18:realtimeblurview:1.0.6' - compile 'cn.carbs.android:AvatarImageView:1.0.4' - compile 'de.hdodenhof:circleimageview:2.1.0' - compile 'jp.wasabeef:recyclerview-animators:2.2.6' - compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.3' - compile 'in.srain.cube:ultra-ptr:1.0.11' - compile 'com.github.cpoopc:scrollablelayoutlib:1.0.1' -// compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.2-alpha-6' -// compile 'com.scwang.smartrefresh:SmartRefreshHeader:1.0.2-alpha-6' - testCompile 'junit:junit:4.12' + + debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3' + releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3' + testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3' + + implementation project(':refresh-footer') + implementation project(':refresh-header') + implementation project(':refresh-layout') + implementation project(':refresh-drawable-path') + + implementation project(':refresh-layout-kernel') + implementation project(':refresh-header-classics') + implementation project(':refresh-header-radar') + implementation project(':refresh-header-falsify') + implementation project(':refresh-header-material') + implementation project(':refresh-header-two-level') + implementation project(':refresh-footer-ball') + +// implementation 'com.scwang.smart:refresh-layout-kernel:2.0.0-alpha-1' //核心必须依赖 +// implementation 'com.scwang.smart:refresh-header-classics:2.0.0-alpha-1' //经典刷新头 +// implementation 'com.scwang.smart:refresh-header-radar:2.0.0-alpha-1' //雷达刷新头 +// implementation 'com.scwang.smart:refresh-header-falsify:2.0.0-alpha-1' //虚拟刷新头 +// implementation 'com.scwang.smart:refresh-header-material:2.0.0-alpha-1' //谷歌刷新头 +// implementation 'com.scwang.smart:refresh-header-two-level:2.0.0-alpha-1' //二级刷新头 +// implementation 'com.scwang.smart:refresh-footer-ball:2.0.0-alpha-1' //球脉冲加载 +// implementation 'com.scwang.smart:refresh-footer-classics:2.0.0-alpha-1' //经典加载 + + + implementation 'com.android.support:design:28.0.0' + implementation 'com.android.support:cardview-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + + implementation 'com.flyco.roundview:FlycoRoundView_Lib:1.1.4@aar' + implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50' + implementation 'com.github.czy1121:loadinglayout:1.0.1' + implementation 'com.github.mmin18:realtimeblurview:1.0.6' + implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.google.android:flexbox:1.0.0' + implementation 'com.wang.avi:library:2.1.3' + implementation 'com.youth.banner:banner:1.4.10' //最新版本 + implementation 'de.hdodenhof:circleimageview:2.2.0' + implementation 'jp.wasabeef:recyclerview-animators:2.2.6' + implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.3' + testImplementation 'junit:junit:4.12' + + implementation 'com.github.bumptech.glide:glide:4.9.0' + annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0' } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 1ccdbfb6..a0a48efb 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -31,4 +31,9 @@ -keepclassmembers class android.support.v8.renderscript.RenderScript { native *** rsn*(...); native *** n*(...); -} \ No newline at end of file +} + +-keep class com.wang.avi.** { *; } +-keep class com.wang.avi.indicators.** { *; } + +-keep class com.scwang.refreshlayout.activity.practice.BannerPracticeActivity$Movie {*;} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 42a22688..c9292d84 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,8 +1,20 @@ + + + + + + + + + + - + - + + + + + diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png index f34d7e7f..9af9a7a2 100644 Binary files a/app/src/main/ic_launcher-web.png and b/app/src/main/ic_launcher-web.png differ diff --git a/app/src/main/java/com/scwang/refreshlayout/App.java b/app/src/main/java/com/scwang/refreshlayout/App.java index 477334e4..6cd64651 100644 --- a/app/src/main/java/com/scwang/refreshlayout/App.java +++ b/app/src/main/java/com/scwang/refreshlayout/App.java @@ -3,30 +3,70 @@ import android.app.Application; import android.content.Context; import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatDelegate; +import com.scwang.refreshlayout.util.DynamicTimeFormat; import com.scwang.smartrefresh.layout.SmartRefreshLayout; -import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreater; +import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator; +import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator; +import com.scwang.smartrefresh.layout.api.DefaultRefreshInitializer; +import com.scwang.smartrefresh.layout.api.RefreshFooter; import com.scwang.smartrefresh.layout.api.RefreshHeader; import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.footer.ClassicsFooter; import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.squareup.leakcanary.LeakCanary; /** * - * Created by SCWANG on 2017/6/11. + * Created by scwang on 2017/6/11. */ - public class App extends Application { - @Override - public void onCreate() { - super.onCreate(); - SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() { + static { + //启用矢量图兼容 + AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); + //设置全局默认配置(优先级最低,会被其他设置覆盖) + SmartRefreshLayout.setDefaultRefreshInitializer(new DefaultRefreshInitializer() { + @Override + public void initialize(@NonNull Context context, @NonNull RefreshLayout layout) { + //全局设置(优先级最低) + layout.setEnableAutoLoadMore(true); + layout.setEnableOverScrollDrag(false); + layout.setEnableOverScrollBounce(true); + layout.setEnableLoadMoreWhenContentNotFull(true); + layout.setEnableScrollContentWhenRefreshed(true); + layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white); + layout.setFooterMaxDragRate(4.0F); + layout.setFooterHeight(45); + } + }); + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { + @NonNull + @Override + public RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull RefreshLayout layout) { + //全局设置主题颜色(优先级第二低,可以覆盖 DefaultRefreshInitializer 的配置,与下面的ClassicsHeader绑定) + layout.setEnableHeaderTranslationContent(true); + return new ClassicsHeader(context).setTimeFormat(new DynamicTimeFormat("更新于 %s")); + } + }); + SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() { @NonNull @Override - public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { - return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.Translate); + public RefreshFooter createRefreshFooter(@NonNull Context context, @NonNull RefreshLayout layout) { + return new ClassicsFooter(context); } }); } + + @Override + public void onCreate() { + super.onCreate(); + if (LeakCanary.isInAnalyzerProcess(this)) { + // This process is dedicated to LeakCanary for heap analysis. + // You should not init your app in this process. + return; + } + LeakCanary.install(this); + } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/ExperimentActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/ExperimentActivity.java deleted file mode 100644 index 8c52c277..00000000 --- a/app/src/main/java/com/scwang/refreshlayout/activity/ExperimentActivity.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.scwang.refreshlayout.activity; - -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; - -import com.scwang.refreshlayout.R; - -public class ExperimentActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_experiment); - } -} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/FragmentActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/FragmentActivity.java new file mode 100644 index 00000000..2a5346c9 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/FragmentActivity.java @@ -0,0 +1,98 @@ +package com.scwang.refreshlayout.activity; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; +import android.support.v7.app.AppCompatActivity; +import android.widget.FrameLayout; + +import java.util.HashMap; +import java.util.Map; + +import static android.R.id.widget_frame; + +/** + * Fragment 容器页面 + * Created by scwang on 2017/10/10. + */ +@SuppressWarnings({"UnusedParameters", "unused"}) +public class FragmentActivity extends AppCompatActivity { + + protected static final String EXTRA_FRAGMENT = "EXTRA_FRAGMENT"; + private Fragment mFragment; + + // + private static void start(Context context, Class clazz, Object... params){ + if (context != null && Fragment.class.isAssignableFrom(clazz)) { + context.startActivity(newIntent(clazz, context, params)); + } + } + + public static void start(Activity activity, Class clazz, Object... params){ + start((Context) activity, clazz, params); + } + + public static void start(Fragment fragment, Class clazz, Object... params){ + if (fragment != null) { + start((Context) fragment.getActivity(), clazz, params); + } + } + + private static Intent newIntent(Class clazz, Context context, Object... params) { + Intent intent = new Intent(context, FragmentActivity.class); + intent.putExtra(EXTRA_FRAGMENT, clazz.getName()); + return intent; + } + // + + // + + //@InjectExtra(value = EXTRA_FRAGMENT,remark = "Fragment类名") + protected String mFragmentClazz = null; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mFragmentClazz = getIntent().getStringExtra(EXTRA_FRAGMENT); + FrameLayout frameLayout = new FrameLayout(this); + frameLayout.setId(widget_frame); + setContentView(frameLayout); + replaceFragment(); + } + + protected void replaceFragment() { + try { + mFragment = (Fragment) getFragmentClass().newInstance(); + FragmentManager manager = getSupportFragmentManager(); + FragmentTransaction transaction = manager.beginTransaction(); + transaction.replace(widget_frame, mFragment); + transaction.commit(); + } catch (Exception e) { + e.printStackTrace(); +// AfExceptionHandler.handle(e, "AfFragmentActivity Fragment 类型错误:" + mFragmentClazz); + } + } + + // + private static Map typeCache = new HashMap<>(); + private Class getFragmentClass() throws ClassNotFoundException { + Class type = typeCache.get(mFragmentClazz); + if (type == null) { + typeCache.put(mFragmentClazz, type = Class.forName(mFragmentClazz)); + } + return type; + } + // + + public Fragment getFragment() { + return mFragment; + } + // + + +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/IndexMainActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/IndexMainActivity.java index 7b92995a..70ce8d49 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/IndexMainActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/IndexMainActivity.java @@ -1,5 +1,6 @@ package com.scwang.refreshlayout.activity; +import android.animation.ValueAnimator; import android.os.Bundle; import android.support.annotation.IdRes; import android.support.annotation.NonNull; @@ -12,21 +13,24 @@ import android.view.MenuItem; import com.scwang.refreshlayout.R; -import com.scwang.refreshlayout.fragment.RefreshPractiveFragment; -import com.scwang.refreshlayout.fragment.RefreshStylesFragment; -import com.scwang.refreshlayout.fragment.RefreshUsingFragment; +import com.scwang.refreshlayout.fragment.index.RefreshExampleFragment; +import com.scwang.refreshlayout.fragment.index.RefreshPracticeFragment; +import com.scwang.refreshlayout.fragment.index.RefreshStylesFragment; +import com.scwang.refreshlayout.util.StatusBarUtil; + +import java.lang.reflect.Field; public class IndexMainActivity extends AppCompatActivity implements OnNavigationItemSelectedListener { private enum TabFragment { - practice(R.id.navigation_practice,RefreshPractiveFragment.class), - styles(R.id.navigation_style,RefreshStylesFragment.class), - using(R.id.navigation_using,RefreshUsingFragment.class) + practice(R.id.navigation_practice, RefreshPracticeFragment.class), + styles(R.id.navigation_style, RefreshStylesFragment.class), + using(R.id.navigation_example, RefreshExampleFragment.class), ; + private Fragment fragment; private final int menuId; private final Class clazz; - private Fragment fragment; TabFragment(@IdRes int menuId, Class clazz) { this.menuId = menuId; @@ -62,35 +66,45 @@ public static void onDestroy() { } } - ViewPager mViewPager; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_index_main); - final BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation); + final BottomNavigationView navigation = findViewById(R.id.navigation); navigation.setOnNavigationItemSelectedListener(this); - mViewPager = (ViewPager) findViewById(R.id.viewPager); - mViewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) { - @Override - public Fragment getItem(int position) { - return TabFragment.values()[position].fragment(); - } + ViewPager viewPager = findViewById(R.id.content); + viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) { @Override public int getCount() { return TabFragment.values().length; } + @Override + public Fragment getItem(int position) { + return TabFragment.values()[position].fragment(); + } }); - mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){ + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener(){ @Override public void onPageSelected(int position) { navigation.setSelectedItemId(TabFragment.values()[position].menuId); } }); - navigation.setSelectedItemId(R.id.navigation_style); + //状态栏透明和间距处理 + StatusBarUtil.immersive(this, 0xff000000, 0.1f); + + try { + /*重置动画倍率-防止部分模拟器对动画速度的控制*/ + Field field = ValueAnimator.class.getDeclaredField("sDurationScale"); + field.setAccessible(true); + field.set(ValueAnimator.class, 1); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } } @Override @@ -101,11 +115,13 @@ protected void onDestroy() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { + ((ViewPager)findViewById(R.id.content)).setCurrentItem(TabFragment.from(item.getItemId()).ordinal()); // getSupportFragmentManager() // .beginTransaction() +// .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN) // .replace(R.id.content,TabFragment.from(item.getItemId()).fragment()) // .commit(); - mViewPager.setCurrentItem(TabFragment.from(item.getItemId()).ordinal()); return true; } + } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/using/AssignCodeUsingActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/AssignCodeExampleActivity.java similarity index 60% rename from app/src/main/java/com/scwang/refreshlayout/activity/using/AssignCodeUsingActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/example/AssignCodeExampleActivity.java index 02328190..26144f84 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/using/AssignCodeUsingActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/AssignCodeExampleActivity.java @@ -1,6 +1,7 @@ -package com.scwang.refreshlayout.activity.using; +package com.scwang.refreshlayout.activity.example; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; @@ -16,16 +17,16 @@ /** * 在Java代码中指定Header和Footer */ -public class AssignCodeUsingActivity extends AppCompatActivity { +public class AssignCodeExampleActivity extends AppCompatActivity { - private static boolean isFirstEnter = true; + private static boolean isFirstEnter = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_using_assign_code); + setContentView(R.layout.activity_example_assign_code); - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -34,13 +35,13 @@ public void onClick(View v) { }); - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); //设置 Header 为 Material风格 refreshLayout.setRefreshHeader(new MaterialHeader(this).setShowBezierWave(true)); //设置 Footer 为 球脉冲 - refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.Scale)); + refreshLayout.setRefreshFooter(new BallPulseFooter(this).setSpinnerStyle(SpinnerStyle.FixedBehind)); - /** + /* * 以下代码仅仅为了演示效果而已,不是必须的 */ //设置主题颜色 @@ -48,17 +49,25 @@ public void onClick(View v) { if (isFirstEnter) { isFirstEnter = false; - //触发上啦加载 - refreshLayout.autoLoadmore(); +// //触发上拉加载 +// mRefreshLayout.autoLoadMore(250, 250, 1.5f); //通过多功能监听接口实现 在第一次加载完成之后 自动刷新 refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener(){ @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - if (oldState == RefreshState.LoadingFinish && newState == RefreshState.None) { + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + if (oldState == RefreshState.LoadFinish && newState == RefreshState.None) { refreshLayout.autoRefresh(); refreshLayout.setOnMultiPurposeListener(null); } } + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); + } + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishRefresh(3000); + } }); } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/example/AssignDefaultExampleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/AssignDefaultExampleActivity.java new file mode 100644 index 00000000..6df3964c --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/AssignDefaultExampleActivity.java @@ -0,0 +1,123 @@ +package com.scwang.refreshlayout.activity.example; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.util.DynamicTimeFormat; +import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator; +import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator; +import com.scwang.smartrefresh.layout.api.RefreshFooter; +import com.scwang.smartrefresh.layout.api.RefreshHeader; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.footer.ClassicsFooter; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; + +/** + * 全局指定默认的Header和Footer + */ +public class AssignDefaultExampleActivity extends AppCompatActivity { + + private static boolean isFirstEnter = true; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + install(); + + setContentView(R.layout.activity_example_assign_default); + + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + /* + * 以下代码仅仅为了演示效果而已,不是必须的 + * 关键代码在构造函数中 + */ + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + if (isFirstEnter) { + isFirstEnter = false; +// //触发上拉加载 +// mRefreshLayout.autoLoadMore(); + //通过多功能监听接口实现 在第一次加载完成之后 自动刷新 + refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener(){ + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + if (oldState == RefreshState.LoadFinish + && newState == RefreshState.None) { + refreshLayout.autoRefresh(); + refreshLayout.setOnMultiPurposeListener(null); + } + } + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); + } + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishRefresh(3000); + } + }); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + restore(); + } + + /* + * 关键代码,需要在布局生成之前设置,建议代码放在 Application 中 + */ + private static void install() { + //设置全局的Header构建器 + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { + @NonNull + @Override + public RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull RefreshLayout layout) { + ClassicsHeader header = new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.FixedBehind); + header.setPrimaryColorId(R.color.colorPrimary); + header.setAccentColorId(android.R.color.white); + return header;//指定为经典Header,默认是 贝塞尔雷达Header + } + }); + //设置全局的Footer构建器 + SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() { + @NonNull + @Override + public RefreshFooter createRefreshFooter(@NonNull Context context, @NonNull RefreshLayout layout) { + layout.setEnableLoadMoreWhenContentNotFull(true);//内容不满一页时候启用加载更多 + ClassicsFooter footer = new ClassicsFooter(context); + footer.setBackgroundResource(android.R.color.white); + footer.setSpinnerStyle(SpinnerStyle.FixedBehind);//设置为拉伸模式 + return footer;//指定为经典Footer,默认是 BallPulseFooter + } + }); + } + + //还原默认 Header + private static void restore() { + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() { + @NonNull + @Override + public RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull RefreshLayout layout) { + layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//全局设置主题颜色 + return new ClassicsHeader(context).setTimeFormat(new DynamicTimeFormat("更新于 %s")); + } + }); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/using/AssignXmlUsingActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/AssignXmlExampleActivity.java similarity index 54% rename from app/src/main/java/com/scwang/refreshlayout/activity/using/AssignXmlUsingActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/example/AssignXmlExampleActivity.java index be125570..f7b70e71 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/using/AssignXmlUsingActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/AssignXmlExampleActivity.java @@ -1,6 +1,7 @@ -package com.scwang.refreshlayout.activity.using; +package com.scwang.refreshlayout.activity.example; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; @@ -13,16 +14,16 @@ /** * 在XML中指定Header和Footer */ -public class AssignXmlUsingActivity extends AppCompatActivity { +public class AssignXmlExampleActivity extends AppCompatActivity { private static boolean isFirstEnter = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_using_assign_xml); + setContentView(R.layout.activity_example_assign_xml); - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -30,25 +31,32 @@ public void onClick(View v) { } }); - - /** + /* * 以下代码仅仅为了演示效果而已,不是必须的 - * 关键代码在 activity_using_assign_xml 中 + * 关键代码在 activity_example_assign_xml 中 */ - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; - //触发上啦加载 - refreshLayout.autoLoadmore(); +// //触发上拉加载 +// mRefreshLayout.autoLoadMore(250, 250, 1.5f); //通过多功能监听接口实现 在第一次加载完成之后 自动刷新 refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener(){ @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - if (oldState == RefreshState.LoadingFinish && newState == RefreshState.None) { + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + if (oldState == RefreshState.LoadFinish && newState == RefreshState.None) { refreshLayout.autoRefresh(); refreshLayout.setOnMultiPurposeListener(null); } } + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); + } + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishRefresh(3000); + } }); } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/example/BasicExampleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/BasicExampleActivity.java new file mode 100644 index 00000000..aa5ceb2d --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/BasicExampleActivity.java @@ -0,0 +1,170 @@ +package com.scwang.refreshlayout.activity.example; + +import android.os.Bundle; +import android.support.design.widget.BottomSheetDialog; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.widget.AbsListView; +import android.widget.ListView; +import android.widget.Toast; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshFooter; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.footer.ClassicsFooter; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Random; + +import ezy.ui.layout.LoadingLayout; + +import static android.R.layout.simple_list_item_2; + +/** + * 基本的功能使用 + */ +public class BasicExampleActivity extends AppCompatActivity { + + + private Random random = new Random(); + private BaseRecyclerAdapter mAdapter; + private LoadingLayout mLoadingLayout; + private com.scwang.smartrefresh.layout.api.RefreshLayout mRefreshLayout; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_example_basic); + + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(v -> finish()); + + ListView listView = findViewById(R.id.listView); + listView.setAdapter(mAdapter = new BaseRecyclerAdapter(simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + //todo SCROLL_STATE_IDLE + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + int SCROLL_STATE_IDLE = 0; + int SCROLL_STATE_TOUCH_SCROLL = 1; + int SCROLL_STATE_FLING = 2; + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + if (scrollState == SCROLL_STATE_IDLE) { + System.out.println("SCROLL_STATE_IDLE"); + } else if (scrollState == SCROLL_STATE_TOUCH_SCROLL) { + System.out.println("SCROLL_STATE_TOUCH_SCROLL"); + } else if (scrollState == SCROLL_STATE_FLING) { + System.out.println("SCROLL_STATE_FLING"); + } + } + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + + } + }); + + mLoadingLayout = findViewById(R.id.loading); + mRefreshLayout = findViewById(R.id.refreshLayout); + mRefreshLayout.setEnableAutoLoadMore(true);//开启自动加载功能(非必须) + mRefreshLayout.setOnRefreshListener(this::refresh); + mRefreshLayout.setOnLoadMoreListener(this::loadMore); + mLoadingLayout.setRetryListener(v -> { + mLoadingLayout.showContent(); + mRefreshLayout.autoRefresh(); + }); + + //触发自动刷新 + mLoadingLayout.showContent(); + mRefreshLayout.autoRefresh(); + //item 点击测试 + mAdapter.setOnItemClickListener((parent, view, position, id) -> { + BottomSheetDialog dialog=new BottomSheetDialog(BasicExampleActivity.this); + View dialogView = View.inflate(getBaseContext(), R.layout.activity_example_basic, null); + com.scwang.smartrefresh.layout.api.RefreshLayout refreshLayout1 = dialogView.findViewById(R.id.refreshLayout); + RecyclerView recyclerView = new RecyclerView(getBaseContext()); + recyclerView.setLayoutManager(new LinearLayoutManager(getBaseContext())); + recyclerView.setAdapter(mAdapter); + refreshLayout1.setEnableRefresh(false); + refreshLayout1.setEnableNestedScroll(false); + refreshLayout1.setRefreshContent(recyclerView); + dialog.setContentView(dialogView); + dialog.show(); + }); + + //点击测试 + RefreshFooter footer = mRefreshLayout.getRefreshFooter(); + if (footer instanceof com.scwang.smartrefresh.layout.footer.ClassicsFooter) { + mRefreshLayout.getRefreshFooter().getView().findViewById(ClassicsFooter.ID_TEXT_TITLE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(getBaseContext(), "点击测试", Toast.LENGTH_SHORT).show(); + } + }); + } + } + + private void loadMore(com.scwang.smartrefresh.layout.api.RefreshLayout layout) { + layout.getLayout().postDelayed(() -> { + if (random.nextBoolean()) { + //如果刷新成功 + mAdapter.loadMore(initData(10)); + if (mAdapter.getItemCount() <= 30) { + //还有多的数据 + layout.finishLoadMore(); + } else { + //没有更多数据(上拉加载功能将显示没有更多数据) + Toast.makeText(getApplication(), "数据全部加载完毕", Toast.LENGTH_SHORT).show(); + layout.finishLoadMoreWithNoMoreData();//将不会再次触发加载更多事件 + } + } else { + //刷新失败 + layout.finishLoadMore(false); + } + }, 2000); + } + + private void refresh(RefreshLayout refresh) { + refresh.getLayout().postDelayed(() -> { + if (random.nextBoolean()) { + //如果刷新成功 + mAdapter.refresh(initData(40)); + if (mAdapter.getItemCount() <= 30) { + //还有多的数据 + refresh.finishRefresh(); + } else { + //没有更多数据(上拉加载功能将显示没有更多数据) + refresh.finishRefreshWithNoMoreData(); + } + } else { + //刷新失败 + refresh.finishRefresh(false); + if (mAdapter.isEmpty()) { + mLoadingLayout.showError(); + mLoadingLayout.setErrorText("随机触发刷新失败演示!"); + } + } + }, 2000); + } + + private Collection initData(int max) { + int min = Math.min(10, max); + max = Math.max(0, max); + if (max > min) { + return Arrays.asList(new Void[min + random.nextInt(max - min)]); + } else { + return Arrays.asList(new Void[min]); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/example/CustomExampleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/CustomExampleActivity.java new file mode 100644 index 00000000..5fbbaaa8 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/CustomExampleActivity.java @@ -0,0 +1,211 @@ +package com.scwang.refreshlayout.activity.example; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.Space; +import android.widget.TextView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smart.drawable.ProgressDrawable; +import com.scwang.smart.refresh.classics.ArrowDrawable; +import com.scwang.smart.refresh.layout.api.RefreshHeader; +import com.scwang.smart.refresh.layout.api.RefreshKernel; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.constant.RefreshState; +import com.scwang.smart.refresh.layout.constant.SpinnerStyle; +import com.scwang.smart.refresh.layout.listener.OnRefreshListener; +import com.scwang.smart.refresh.layout.util.SmartUtil; + +import java.util.Arrays; +import java.util.Collection; + +import static android.R.layout.simple_list_item_2; + +/** + * 自定义Header功能使用 + */ +public class CustomExampleActivity extends AppCompatActivity { + + private BaseRecyclerAdapter mAdapter; + + private static boolean isFirstEnter = true; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_example_custom); + + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + ListView listView = findViewById(R.id.listView); + listView.setAdapter(mAdapter = new BaseRecyclerAdapter(simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + refreshLayout.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.refresh(initData()); + refreshLayout.finishRefresh(); + } + }, 2000); + } + }); + + refreshLayout.setRefreshHeader(new ClassicsHeader(this)); + refreshLayout.setHeaderHeight(60); + + //触发自动刷新 + if (isFirstEnter) { + isFirstEnter = false; + refreshLayout.autoRefresh(); + } else { + mAdapter.refresh(initData()); + } + + } + + private Collection initData() { + return Arrays.asList(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); + } + + public static class ClassicsHeader extends LinearLayout implements RefreshHeader { + + private TextView mHeaderText;//标题文本 + private ImageView mArrowView;//下拉箭头 + private ImageView mProgressView;//刷新动画视图 + private ProgressDrawable mProgressDrawable;//刷新动画 + + public ClassicsHeader(Context context) { + this(context, null); + } + public ClassicsHeader(Context context, AttributeSet attrs) { + super(context, attrs, 0); + setGravity(Gravity.CENTER); + mHeaderText = new TextView(context); + mProgressDrawable = new ProgressDrawable(); + mArrowView = new ImageView(context); + mProgressView = new ImageView(context); + mProgressView.setImageDrawable(mProgressDrawable); + mArrowView.setImageDrawable(new ArrowDrawable()); + addView(mProgressView, SmartUtil.dp2px(20), SmartUtil.dp2px(20)); + addView(mArrowView, SmartUtil.dp2px(20), SmartUtil.dp2px(20)); + addView(new Space(context), SmartUtil.dp2px(20), SmartUtil.dp2px(20)); + addView(mHeaderText, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); + setMinimumHeight(SmartUtil.dp2px(60)); + } + @NonNull + public View getView() { + return this;//真实的视图就是自己,不能返回null + } + @NonNull + @Override + public SpinnerStyle getSpinnerStyle() { + return SpinnerStyle.Translate;//指定为平移,不能null + } + + @Override + public void onStartAnimator(@NonNull RefreshLayout layout, int height, int maxDragHeight) { + mProgressDrawable.start();//开始动画 + } + + @Override + public int onFinish(@NonNull RefreshLayout layout, boolean success) { + mProgressDrawable.stop();//停止动画 + mProgressView.setVisibility(GONE);//隐藏动画 + if (success){ + mHeaderText.setText("刷新完成"); + } else { + mHeaderText.setText("刷新失败"); + } + return 500;//延迟500毫秒之后再弹回 + } + + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + switch (newState) { + case None: + case PullDownToRefresh: + mHeaderText.setText("下拉开始刷新"); + mArrowView.setVisibility(VISIBLE);//显示下拉箭头 + mProgressView.setVisibility(GONE);//隐藏动画 + mArrowView.animate().rotation(0);//还原箭头方向 + break; + case Refreshing: + mHeaderText.setText("正在刷新"); + mProgressView.setVisibility(VISIBLE);//显示加载动画 + mArrowView.setVisibility(GONE);//隐藏箭头 + break; + case ReleaseToRefresh: + mHeaderText.setText("释放立即刷新"); + mArrowView.animate().rotation(180);//显示箭头改为朝上 + break; + } + } + + @Override + public void setPrimaryColors(int... colors) { + + } + + @Override + public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) { + + } + + @Override + public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) { + + } + +// @Override +// public void onPulling(float percent, int offset, int height, int maxDragHeight) { +// +// } +// @Override +// public void onReleasing(float percent, int offset, int height, int maxDragHeight) { +// +// } + + @Override + public void onReleased(@NonNull RefreshLayout refreshLayout, int height, int maxDragHeight) { + + } + + @Override + public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) { + + } + + @Override + public boolean isSupportHorizontalDrag() { + return false; + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/example/I18nExampleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/I18nExampleActivity.java new file mode 100644 index 00000000..b12967a1 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/I18nExampleActivity.java @@ -0,0 +1,106 @@ +package com.scwang.refreshlayout.activity.example; + +import android.content.Intent; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.DisplayMetrics; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; + +import static android.R.layout.simple_list_item_2; + +public class I18nExampleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { + + private enum Item { + i1(R.string.item_example_i18n_system), + i2(R.string.item_example_i18n_chinese), + i3(R.string.item_example_i18n_english), + ; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; + } + } + + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_example_i18n); + + Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(v -> finish()); + + RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + if (refreshLayout != null) { + refreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 + refreshLayout.setRefreshHeader(new ClassicsHeader(this)); + refreshLayout.setOnRefreshListener((OnRefreshListener) layout -> layout.finishRefresh(1000)); + } + + View view = findViewById(R.id.listView); + if (view instanceof ListView) { + ListView listView = ((ListView) view); + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + listView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2, this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.nameId); + holder.text(android.R.id.text2, getString(R.string.item_example_i18n_click, getString(model.nameId))); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + switch (Item.values()[position % Item.values().length].nameId) { + case R.string.item_example_i18n_system: + changeAppLanguage(Locale.getDefault()); + break; + case R.string.item_example_i18n_chinese: + changeAppLanguage(Locale.CHINESE); + break; + case R.string.item_example_i18n_english: + changeAppLanguage(Locale.ENGLISH); + break; + } + } + + private void changeAppLanguage(Locale locale) { + Resources res = getResources(); + DisplayMetrics dm = res.getDisplayMetrics(); + Configuration conf = res.getConfiguration(); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { + conf.locale = locale; + } else { + conf.setLocale(locale); + } + res.updateConfiguration(conf, dm); + startActivity(new Intent(this, getClass())); + overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out); + finish(); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/example/ListenerExampleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/ListenerExampleActivity.java new file mode 100644 index 00000000..def013dd --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/ListenerExampleActivity.java @@ -0,0 +1,205 @@ +package com.scwang.refreshlayout.activity.example; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.text.method.ScrollingMovementMethod; +import android.view.View; +import android.widget.TextView; + +import com.scwang.refreshlayout.R; +import com.scwang.smartrefresh.layout.api.RefreshFooter; +import com.scwang.smartrefresh.layout.api.RefreshHeader; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; + +/** + * 多功能监听器的使用 + */ +public class ListenerExampleActivity extends AppCompatActivity { + + private static DateFormat FORMAT = new SimpleDateFormat("HH:mm sss", Locale.CHINA); + + private TextView mTvContent; + private String mHeaderMoving; +// private String mHeaderPulling; +// private String mHeaderReleasing; + private String mFooterMoving; +// private String mFooterPulling; +// private String mFooterReleasing; + private String mFooterStartAnimator; + private String mHeaderStartAnimator; + private String mFooterFinish; + private String mHeaderFinish; + private String mRefresh; + private String mLoadMore; + private String mStateChanged; + + private static boolean isFirstEnter = true; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_example_listener); + + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + mTvContent = findViewById(R.id.content); + mTvContent.setMovementMethod(ScrollingMovementMethod.getInstance()); + + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { + + @Override + public void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) { + mHeaderMoving = String.format(Locale.CHINA, "%s\nisDragging=%b,percent=%.02f offset=%03d\nheight=%03d extend=%03d", + FORMAT.format(new Date()),isDragging, + percent,offset,headerHeight,maxDragHeight); + updateContent(); + } + +// @Override +// public void onHeaderPulling(@NonNull RefreshHeader header, float percent, int offset, int headerHeight, int maxDragHeight) { +// mHeaderPulling = String.format(Locale.CHINA, "%s\npercent=%.02f offset=%03d\nheight=%03d extend=%03d", +// FORMAT.format(new Date()), +// percent,offset,headerHeight,maxDragHeight); +// updateContent(); +// } +// +// @Override +// public void onHeaderReleasing(@NonNull RefreshHeader header, float percent, int offset, int headerHeight, int maxDragHeight) { +// mHeaderReleasing = String.format(Locale.CHINA, "%s\npercent=%.02f offset=%03d\nheight=%03d extend=%03d", +// FORMAT.format(new Date()), +// percent,offset,headerHeight,maxDragHeight); +// updateContent(); +// } + + @Override + public void onHeaderStartAnimator(@NonNull RefreshHeader header, int headerHeight, int maxDragHeight) { + mHeaderStartAnimator = String.format(Locale.CHINA, "%s\nheight=%03d extend=%03d", + FORMAT.format(new Date()), + headerHeight,maxDragHeight); + updateContent(); + } + + @Override + public void onHeaderFinish(@NonNull RefreshHeader header, boolean success) { + mHeaderFinish = String.format(Locale.CHINA, "%s - " + success,FORMAT.format(new Date())); + updateContent(); + } + + @Override + public void onFooterMoving(RefreshFooter footer, boolean isDragging, float percent, int offset, int footerHeight, int maxDragHeight) { + mFooterMoving = String.format(Locale.CHINA, "%s\nisDragging=%b,percent=%.02f offset=%03d\nheight=%03d extend=%03d", + FORMAT.format(new Date()),isDragging, + percent,offset,footerHeight,maxDragHeight); + updateContent(); + } + +// @Override +// public void onFooterPulling(@NonNull RefreshFooter footer, float percent, int offset, int footerHeight, int maxDragHeight) { +// mFooterPulling = String.format(Locale.CHINA, "%s\npercent=%.02f\noffset=%03d height=%03d\nextend=%03d", +// FORMAT.format(new Date()), +// percent,offset,footerHeight,maxDragHeight); +// updateContent(); +// } +// +// @Override +// public void onFooterReleasing(@NonNull RefreshFooter footer, float percent, int offset, int footerHeight, int maxDragHeight) { +// mFooterReleasing = String.format(Locale.CHINA, "%s\npercent=%.02f\noffset=%03d height=%03d\nextend=%03d", +// FORMAT.format(new Date()), +// percent,offset,footerHeight,maxDragHeight); +// updateContent(); +// } + + @Override + public void onFooterStartAnimator(@NonNull RefreshFooter footer, int footerHeight, int maxDragHeight) { + mFooterStartAnimator = String.format(Locale.CHINA, "%s\nheight=%03d extend=%03d", + FORMAT.format(new Date()), + footerHeight,maxDragHeight); + updateContent(); + } + + @Override + public void onFooterFinish(@NonNull RefreshFooter footer, boolean success) { + mFooterFinish = String.format(Locale.CHINA, "%s - " + success,FORMAT.format(new Date())); + updateContent(); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mRefresh = String.format(Locale.CHINA, "%s",FORMAT.format(new Date())); + updateContent(); + refreshLayout.finishRefresh(2000); + } + + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + mLoadMore = String.format(Locale.CHINA, "%s",FORMAT.format(new Date())); + updateContent(); + refreshLayout.finishLoadMore(1000); + } + + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + mStateChanged = String.format(Locale.CHINA, "%s\nnew=%s\nold=%s", + FORMAT.format(new Date()), + newState.name(), + oldState.name()); + updateContent(); + } + }); + + if (isFirstEnter) { + isFirstEnter = false; + //触发自动刷新 + refreshLayout.autoRefresh(); + } else { + updateContent(); + } + } + + private void updateContent() { + mTvContent.setText(String.format(Locale.CHINA, + "onStateChanged:%s\n\n" + + "onHeaderMoving:%s\n\n" + +// "onHeaderPulling:%s\n\n" + +// "onHeaderReleasing:%s\n\n" + + "onHeaderStartAnimator:%s\n\n" + + "onHeaderFinish:%s\n\n" + + "onFooterMoving:%s\n\n" + +// "onFooterPulling:%s\n\n" + +// "onFooterReleasing:%s\n\n" + + "onFooterStartAnimator:%s\n\n" + + "onFooterFinish:%s\n\n" + + "onRefresh:%s\n\n" + + "onLoadMore:%s\n\n", + mStateChanged, + mHeaderMoving, +// mHeaderPulling, +// mHeaderReleasing, + mHeaderStartAnimator, + mHeaderFinish, + mFooterMoving, +// mFooterPulling, +// mFooterReleasing, + mFooterStartAnimator, + mFooterFinish, + mRefresh, + mLoadMore)); + } + +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/using/NestLayoutUsingActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/NestedLayoutExampleActivity.java similarity index 68% rename from app/src/main/java/com/scwang/refreshlayout/activity/using/NestLayoutUsingActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/example/NestedLayoutExampleActivity.java index d2f96c78..e0da5429 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/using/NestLayoutUsingActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/NestedLayoutExampleActivity.java @@ -1,4 +1,4 @@ -package com.scwang.refreshlayout.activity.using; +package com.scwang.refreshlayout.activity.example; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; @@ -7,6 +7,7 @@ import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.TextView; @@ -16,9 +17,13 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; +import java.util.Locale; -public class NestLayoutUsingActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { +public class NestedLayoutExampleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private static String[] provinces = new String[]{ "北京","天津","上海","重庆", @@ -32,9 +37,9 @@ public class NestLayoutUsingActivity extends AppCompatActivity implements Adapte @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_using_region); + setContentView(R.layout.activity_example_region); - final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); if (toolbar != null) { toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override @@ -56,15 +61,28 @@ protected void onBindViewHolder(SmartViewHolder holder, String model, int positi holder.text(android.R.id.text1, model); } }.setOnItemClickListener(this)); + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + DateFormat dateFormat = new SimpleDateFormat("hh:mm:ss SSS", Locale.CHINA); + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + Log.e("recyclerView", dateFormat.format(new Date()) + " - onScrollStateChanged - " + newState); + super.onScrollStateChanged(recyclerView, newState); + } + + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + } + }); } - /** + /* * 以下代码仅仅为了演示效果而已,不是必须的 - * 关键代码在 activity_using_assign_xml 中 + * 关键代码在 activity_example_assign_xml 中 */ - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter && refreshLayout != null) { isFirstEnter = false; - //触发上啦加载 + //触发上拉加载 refreshLayout.autoRefresh(); } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/using/OverScrollUsingActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/OverScrollExampleActivity.java similarity index 70% rename from app/src/main/java/com/scwang/refreshlayout/activity/using/OverScrollUsingActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/example/OverScrollExampleActivity.java index fe9238f0..0870bde9 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/using/OverScrollUsingActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/OverScrollExampleActivity.java @@ -1,6 +1,7 @@ -package com.scwang.refreshlayout.activity.using; +package com.scwang.refreshlayout.activity.example; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; @@ -14,14 +15,14 @@ /** * 越界回弹使用演示 */ -public class OverScrollUsingActivity extends AppCompatActivity { +public class OverScrollExampleActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_using_overscroll); + setContentView(R.layout.activity_example_overscroll); - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -29,11 +30,11 @@ public void onClick(View v) { } }); - final WebView webView = (WebView) findViewById(R.id.webView); - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); + final WebView webView = findViewById(R.id.webView); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); refreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override - public void onRefresh(RefreshLayout refreshlayout) { + public void onRefresh(@NonNull RefreshLayout refreshLayout) { webView.loadUrl("http://github.com"); } }); @@ -42,16 +43,18 @@ public void onRefresh(RefreshLayout refreshlayout) { webView.setWebViewClient(new WebViewClient(){ @Override + @SuppressWarnings("deprecation") public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } + @Override public void onPageCommitVisible(WebView view, String url) { refreshLayout.finishRefresh(); } }); -// TextView textView = (TextView) findViewById(R.id.textView); +// TextView textView = findViewById(R.id.textView); // textView.setMovementMethod(new ScrollingMovementMethod()); } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/example/SnapHelperExampleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/example/SnapHelperExampleActivity.java new file mode 100644 index 00000000..a35c1649 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/example/SnapHelperExampleActivity.java @@ -0,0 +1,86 @@ +package com.scwang.refreshlayout.activity.example; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.PagerSnapHelper; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.SnapHelper; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.widget.Switch; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; + +import java.util.Arrays; +import java.util.Collection; + +/** + * 结合 SnapHelper 使用 + * Created by scwang on 2017/8/4. + */ +public class SnapHelperExampleActivity extends AppCompatActivity { + + private BaseRecyclerAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_example_snaphelper); + + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(v -> finish()); + + //初始化列表和监听 + View view = findViewById(R.id.recyclerView); + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(loadModels(), R.layout.item_example_snap_helper) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Integer model, int position) { + holder.image(R.id.imageView, model); + } + }); + SnapHelper snapHelper = new PagerSnapHelper(); + snapHelper.attachToRecyclerView(recyclerView); + } + + RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + refreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(() -> { + mAdapter.refresh(loadModels()); + refreshLayout.finishRefresh(); + }, 2000); + } + + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(() -> { + mAdapter.loadMore(loadModels()); + refreshLayout.finishLoadMore(); + }, 2000); + } + }); + + Switch switcher = findViewById(R.id.switch_scroll_content); + if (switcher != null) { + refreshLayout.setEnableScrollContentWhenLoaded(switcher.isChecked()); + switcher.setOnCheckedChangeListener((buttonView, isChecked) -> refreshLayout.setEnableScrollContentWhenLoaded(isChecked)); + } + } + + private Collection loadModels() { + return Arrays.asList( R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2); + } + +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/practice/BannerPracticeActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/practice/BannerPracticeActivity.java new file mode 100644 index 00000000..752b3f5a --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/practice/BannerPracticeActivity.java @@ -0,0 +1,208 @@ +package com.scwang.refreshlayout.activity.practice; + +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.Toast; + +import com.bumptech.glide.Glide; +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.util.StatusBarUtil; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; +import com.youth.banner.Banner; +import com.youth.banner.BannerConfig; +import com.youth.banner.listener.OnBannerListener; +import com.youth.banner.loader.ImageLoader; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * 广告轮播-Banner + */ +@SuppressWarnings("ALL") +public class BannerPracticeActivity extends AppCompatActivity { + + private QuickAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_practice_banner); + + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + final RecyclerView recyclerView = findViewById(R.id.recyclerView); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + + mAdapter = new QuickAdapter(); + recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(mAdapter); + final List movies = new Gson().fromJson(JSON_MOVIES, new TypeToken>() {}.getType()); + mAdapter.replaceData(movies); + refreshLayout.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + if (mAdapter.getItemCount() < 2) { + List movies = new Gson().fromJson(JSON_MOVIES, new TypeToken>() {}.getType()); + mAdapter.replaceData(movies); + } + refreshLayout.finishRefresh(); + } + },2000); + } + }); +// refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { +// @Override +// public void onLoadMore(@NonNull RefreshLayout refreshLayout) { +// mAdapter.addData(movies); +// refreshLayout.finishLoadMoreWithNoMoreData(); +// } +// }); + refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout rl) { + mAdapter.addData(movies); + rl.finishLoadMoreWithNoMoreData(); + } + }); + + + //添加Header + View header = LayoutInflater.from(this).inflate(R.layout.item_movie_header, recyclerView, false); + Banner banner = (Banner) header; + banner.setImageLoader(new GlideImageLoader()); + banner.setImages(BANNER_ITEMS); + banner.setOnBannerListener(new OnBannerListener() { + @Override + public void OnBannerClick(int i) { + Toast.makeText(BannerPracticeActivity.this, "点击了第" + i + "页", Toast.LENGTH_SHORT).show(); + } + }); + if (Build.VERSION.SDK_INT > 26) { + Stream stream = BANNER_ITEMS.stream().map(new Function() { + @Override + public String apply(BannerItem bannerItem) { + return bannerItem.title; + } + }); + banner.setBannerStyle(BannerConfig.CIRCLE_INDICATOR_TITLE_INSIDE); + banner.setBannerTitles(stream.collect(Collectors.toList())); + } + banner.start(); + mAdapter.addHeaderView(banner); + mAdapter.openLoadAnimation(); + + //状态栏透明和间距处理 + StatusBarUtil.immersive(this); + StatusBarUtil.setPaddingSmart(this, toolbar); + StatusBarUtil.setPaddingSmart(this, recyclerView); + StatusBarUtil.setMargin(this, findViewById(R.id.header)); + StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurView)); + } + + public class QuickAdapter extends BaseQuickAdapter { + public QuickAdapter() { + super(R.layout.item_movie_item); + } + + @Override + protected void convert(BaseViewHolder viewHolder, Movie item) { + viewHolder.setText(R.id.lmi_title, item.filmName) + .setText(R.id.lmi_actor, item.actors) + .setText(R.id.lmi_grade, item.grade) + .setText(R.id.lmi_describe, item.shortinfo); + Glide.with(mContext).load(item.picaddr).into((ImageView) viewHolder.getView(R.id.lmi_avatar)); + } + } + + public class GlideImageLoader extends ImageLoader { + @Override + public void displayImage(Context context, Object path, ImageView imageView) { + imageView.setImageResource(((BannerItem) path).pic); + } + } + + public static class Movie { + public String actors; + public String filmName; + public String grade; + public String info; + public String picaddr; + public String shortinfo; + } + + public static class BannerItem { + + public int pic; + public String title; + + public BannerItem() { + } + + public BannerItem(String title, int pic) { + this.pic = pic; + this.title = title; + } + } + + public static List BANNER_ITEMS = new ArrayList(){{ + add(new BannerItem("最后的骑士", R.mipmap.image_movie_header_48621499931969370)); + add(new BannerItem("三生三世十里桃花", R.mipmap.image_movie_header_12981501221820220)); + add(new BannerItem("豆福传", R.mipmap.image_movie_header_12231501221682438)); + }}; + + + public static String JSON_MOVIES = "[" + + "{\"actors\":\"丹尼斯·威缇可宁|Emma|Nikki|Jiayao|Wang|Maggie|Mao|Gang-yun|Sa\",\"filmName\":\"神灵寨\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3823.jpg\",\"releasedate\":\"2017-07-31\",\"shortinfo\":\"父亲忽病危 新娘真够黑\",\"type\":\"剧情|喜剧\"}," + + "{\"actors\":\"刘亦菲|杨洋|彭子苏|严屹宽|罗晋\",\"filmName\":\"三生三世十里桃花\",\"grade\":\"9.2\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3566.jpg\",\"releasedate\":\"2017-08-03\",\"shortinfo\":\"虐心姐弟恋 颜值要逆天\",\"type\":\"剧情|爱情|奇幻\"}," + + "{\"actors\":\"尹航|代旭|李晨浩|衣云鹤|张念骅\",\"filmName\":\"谁是球王\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3750.jpg\",\"releasedate\":\"2017-08-03\",\"shortinfo\":\"足球变人生 再战可辉煌\",\"type\":\"剧情|喜剧\"}," + + "{\"actors\":null,\"filmName\":\"大象林旺之一夜成名\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3757.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"大象参二战 一生好伙伴\",\"type\":\"动作|动画|战争|冒险\"}," + + "{\"actors\":\"薛凯琪|陈意涵|张钧甯|迈克·泰森\",\"filmName\":\"闺蜜2:无二不作\",\"grade\":\"8.3\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3776.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"闺蜜团出战 会一会新娘\",\"type\":\"喜剧|爱情\"}," + + "{\"actors\":\"彭禺厶|王萌|周凯文|曹琦|孟子叶\",\"filmName\":\"诡井\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3824.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"午夜深井中 怨魂欲现形\",\"type\":\"恐怖|惊悚\"}," + + "{\"actors\":\"旺卓措|刘承宙|高欣生|段楠|来钰\",\"filmName\":\"荒野加油站\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3821.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"夜半拉乘客 结果遇不测\",\"type\":\"惊悚|悬疑\"}," + + "{\"actors\":\"刘佩琦|曹云金|罗昱焜\",\"filmName\":\"龙之战\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3778.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"持倭刀屹立 抗外敌救国\",\"type\":\"动作|战争|历史\"}," + + "{\"actors\":\"金巴|曲尼次仁|夏诺.扎西敦珠|索朗尼玛|益西旦增\",\"filmName\":\"皮绳上的魂\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3801.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"走完朝圣路 又上降魔旅\",\"type\":\"剧情\"}," + + "{\"actors\":\"严丽祯|李晔|王衡|李传缨|李心仪\",\"filmName\":\"玩偶奇兵\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3779.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"玩偶战数码 一头两个大\",\"type\":\"动画|冒险|奇幻\"}," + + "{\"actors\":\"斯蒂芬·马布里|吴尊|何冰|郑秀妍|王庆祥\",\"filmName\":\"我是马布里\",\"grade\":\"0.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3810.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"吴尊助冠军 热血灌篮魂\",\"type\":\"剧情|运动\"}," + + "{\"actors\":\"周鹏雨|穆建荣|陈泽帆|鹿露|宋星成\",\"filmName\":\"原罪的羔羊\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3802.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"古镇来戏班 往事不一般\",\"type\":\"悬疑\"}," + + "{\"actors\":\"王大陆|张天爱|任达华|盛冠森|王迅\",\"filmName\":\"鲛珠传\",\"grade\":\"7.1\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3777.jpg\",\"releasedate\":\"2017-08-04\",\"shortinfo\":\"改编热IP 杠杠号召力\",\"type\":\"喜剧|动作|奇幻\"}," + + "{\"actors\":\"成龙|罗伯特·雷德福\",\"filmName\":\"地球:神奇的一天\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3803.jpg\",\"releasedate\":\"2017-08-11\",\"shortinfo\":\"史诗纪录片 十年再相见\",\"type\":\"纪录片\"}," + + "{\"actors\":\"刘德华|舒淇|杨祐宁|张静初|让·雷诺|曾志伟|沙溢\",\"filmName\":\"侠盗联盟\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3592.jpg\",\"releasedate\":\"2017-08-11\",\"shortinfo\":\"侠盗三剑客 越洋逃恐吓\",\"type\":\"动作|冒险\"}," + + "{\"actors\":\"廖凡|李易峰|万茜|李纯|张国柱\",\"filmName\":\"心理罪\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3795.jpg\",\"releasedate\":\"2017-08-11\",\"shortinfo\":\"侦探两搭档 真相背后藏\",\"type\":\"悬疑|犯罪\"}," + + "{\"actors\":\"徐瑞阳|赵倩|姜启杨|徐万学|韩靓|韦安\",\"filmName\":\"隐隐惊马槽之绝战女僵尸\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3825.jpg\",\"releasedate\":\"2017-08-11\",\"shortinfo\":\"阴兵来借道 尸占惊马槽\",\"type\":\"惊悚|动作|冒险|悬疑\"}," + + "{\"actors\":\"宋睿|王良|张佳浩|叶常清\",\"filmName\":\"左眼阴阳\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3804.jpg\",\"releasedate\":\"2017-08-11\",\"shortinfo\":\"左眼见到鬼 是诡还是魅\",\"type\":\"恐怖|惊悚|悬疑\"}," + + "{\"actors\":null,\"filmName\":\"二十二\",\"grade\":\"10.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3811.jpg\",\"releasedate\":\"2017-08-14\",\"shortinfo\":\"二战女俘虏 讲述心中苦\",\"type\":\"纪录片\"}," + + "{\"actors\":\"郭富城|王千源|刘涛|余皑磊|冯嘉怡\",\"filmName\":\"破·局\",\"grade\":\"5.0\",\"picaddr\":\"http://app.infunpw.com/commons/images/cinema/cinema_films/3812.jpg\",\"releasedate\":\"2017-08-18\",\"shortinfo\":\"影帝硬碰硬 迷局谁怕谁\",\"type\":\"动作|犯罪\"}" + + "]"; +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/practice/FeedlistPracticeActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/practice/FeedListPracticeActivity.java similarity index 77% rename from app/src/main/java/com/scwang/refreshlayout/activity/practice/FeedlistPracticeActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/practice/FeedListPracticeActivity.java index 8bb52240..c051526d 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/practice/FeedlistPracticeActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/practice/FeedListPracticeActivity.java @@ -9,9 +9,9 @@ import com.scwang.smartrefresh.layout.api.RefreshLayout; /** - * 网页-Github + * 微博列表 */ -public class FeedlistPracticeActivity extends AppCompatActivity { +public class FeedListPracticeActivity extends AppCompatActivity { private static boolean isFirstEnter = true; @@ -20,7 +20,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_practice_feedlist); - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -28,12 +28,11 @@ public void onClick(View v) { } }); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); refreshLayout.autoRefresh(); } - } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/practice/ProfilePracticeActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/practice/ProfilePracticeActivity.java index d8b3fc6d..8ca0c915 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/practice/ProfilePracticeActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/practice/ProfilePracticeActivity.java @@ -13,25 +13,19 @@ */ public class ProfilePracticeActivity extends AppCompatActivity { - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_practice_profile); - final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(v -> finish()); //状态栏透明和间距处理 StatusBarUtil.immersive(this); StatusBarUtil.setPaddingSmart(this, toolbar); StatusBarUtil.setPaddingSmart(this, findViewById(R.id.profile)); - StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurview)); + StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurView)); } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/practice/QQBrowserPracticeActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/practice/QQBrowserPracticeActivity.java new file mode 100644 index 00000000..3b9a6f2d --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/activity/practice/QQBrowserPracticeActivity.java @@ -0,0 +1,59 @@ +package com.scwang.refreshlayout.activity.practice; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.util.StatusBarUtil; + +import ezy.ui.layout.LoadingLayout; + +/** + * QQ浏览器-Github + */ +public class QQBrowserPracticeActivity extends AppCompatActivity { + + @SuppressLint("SetJavaScriptEnabled") + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_practice_qqbrowser); + + final Toolbar toolbar = findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + + final LoadingLayout loading = findViewById(R.id.loading); + + final WebView webView = findViewById(R.id.webView); + webView.loadUrl("https://github.com/scwang90/SmartRefreshLayout"); + webView.getSettings().setJavaScriptEnabled(true); + webView.setWebViewClient(new WebViewClient(){ + @Override + @SuppressWarnings("deprecation") + public boolean shouldOverrideUrlLoading(WebView view, String url) { + view.loadUrl(url); + return true; + } + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + loading.showContent(); + } + }); + + //状态栏透明和间距处理 + StatusBarUtil.immersive(this); + StatusBarUtil.setPaddingSmart(this, toolbar); + } + +} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/practice/RepastPracticeActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/practice/RepastPracticeActivity.java index 11f13303..0654c550 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/practice/RepastPracticeActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/practice/RepastPracticeActivity.java @@ -1,6 +1,7 @@ package com.scwang.refreshlayout.activity.practice; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; @@ -14,7 +15,8 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.refreshlayout.util.StatusBarUtil; import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.listener.OnRefreshLoadmoreListener; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; +import com.scwang.smartrefresh.layout.util.SmartUtil; import java.util.Arrays; import java.util.Collection; @@ -24,7 +26,6 @@ */ public class RepastPracticeActivity extends AppCompatActivity { - private class Model { int imageId; int avatarId; @@ -40,7 +41,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_practice_repast); - final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -48,7 +49,8 @@ public void onClick(View v) { } }); - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + refreshLayout.setEnableFooterFollowWhenNoMoreData(true); //第一次进入演示刷新 if (isFirstEnter) { @@ -62,7 +64,7 @@ public void onClick(View v) { RecyclerView recyclerView = (RecyclerView) view; recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(loadModels(), R.layout.listitem_practive_repast) { + recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(loadModels(), R.layout.item_practice_repast) { @Override protected void onBindViewHolder(SmartViewHolder holder, Model model, int position) { holder.text(R.id.name, model.name); @@ -72,39 +74,48 @@ protected void onBindViewHolder(SmartViewHolder holder, Model model, int positio } }); - refreshLayout.setOnRefreshLoadmoreListener(new OnRefreshLoadmoreListener() { + refreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { @Override - public void onRefresh(final RefreshLayout refreshlayout) { + public void onRefresh(@NonNull final RefreshLayout refreshLayout) { refreshLayout.getLayout().postDelayed(new Runnable() { @Override public void run() { - refreshlayout.finishRefresh(); + refreshLayout.finishRefresh(); + refreshLayout.resetNoMoreData();//setNoMoreData(false);//恢复上拉状态 } }, 2000); } @Override - public void onLoadmore(final RefreshLayout refreshlayout) { + public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { refreshLayout.getLayout().postDelayed(new Runnable() { @Override public void run() { - mAdapter.loadmore(loadModels()); - refreshlayout.finishLoadmore(); if (mAdapter.getCount() > 12) { Toast.makeText(getBaseContext(), "数据全部加载完毕", Toast.LENGTH_SHORT).show(); - refreshlayout.setLoadmoreFinished(true);//设置之后,将不会再触发加载事件 + refreshLayout.finishLoadMoreWithNoMoreData();//设置之后,将不会再触发加载事件 + } else { + mAdapter.loadMore(loadModels()); + refreshLayout.finishLoadMore(); } } }, 1000); } }); + + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + refreshLayout.setHeaderInsetStart(SmartUtil.px2dp(toolbar.getHeight())); + } + }, 500); } //状态栏透明和间距处理 StatusBarUtil.darkMode(this); StatusBarUtil.setPaddingSmart(this, view); StatusBarUtil.setPaddingSmart(this, toolbar); - StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurview)); - StatusBarUtil.setMargin(this, findViewById(R.id.gifview)); + StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurView)); + } /** diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/practice/WebviewPracticeActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/practice/WebViewPracticeActivity.java similarity index 74% rename from app/src/main/java/com/scwang/refreshlayout/activity/practice/WebviewPracticeActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/practice/WebViewPracticeActivity.java index 4b01ab1a..45b07f16 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/practice/WebviewPracticeActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/practice/WebViewPracticeActivity.java @@ -2,6 +2,7 @@ import android.annotation.SuppressLint; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; @@ -12,14 +13,14 @@ import com.scwang.refreshlayout.util.StatusBarUtil; import com.scwang.smartrefresh.layout.api.RefreshLayout; import com.scwang.smartrefresh.layout.listener.OnRefreshListener; -import com.scwang.smartrefresh.layout.util.DensityUtil; +import com.scwang.smartrefresh.layout.util.SmartUtil; import java.util.Locale; /** * 网页-Github */ -public class WebviewPracticeActivity extends AppCompatActivity { +public class WebViewPracticeActivity extends AppCompatActivity { @SuppressLint("SetJavaScriptEnabled") @Override @@ -27,7 +28,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_practice_webview); - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -35,11 +36,11 @@ public void onClick(View v) { } }); - final WebView webView = (WebView) findViewById(R.id.webView); - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); + final WebView webView = findViewById(R.id.webView); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); refreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override - public void onRefresh(RefreshLayout refreshlayout) { + public void onRefresh(@NonNull RefreshLayout refreshLayout) { webView.loadUrl("https://github.com/scwang90/SmartRefreshLayout"); } }); @@ -49,14 +50,17 @@ public void onRefresh(RefreshLayout refreshlayout) { webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new WebViewClient(){ @Override + @SuppressWarnings("deprecation") public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } + @Override - public void onPageCommitVisible(WebView view, String url) { + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); refreshLayout.finishRefresh(); - view.loadUrl(String.format(Locale.CHINA, "javascript:document.body.style.paddingTop='%fpx'; void 0", DensityUtil.px2dp(webView.getPaddingTop()))); + view.loadUrl(String.format(Locale.CHINA, "javascript:document.body.style.paddingTop='%fpx'; void 0", SmartUtil.px2dp(webView.getPaddingTop()))); } }); @@ -65,7 +69,7 @@ public void onPageCommitVisible(WebView view, String url) { StatusBarUtil.setPaddingSmart(this, webView); StatusBarUtil.setPaddingSmart(this, toolbar); StatusBarUtil.setMargin(this, findViewById(R.id.header)); - StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurview)); + StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurView)); } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/practice/WeiboPracticeActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/practice/WeiboPracticeActivity.java index 22ef1e78..cc295ef4 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/practice/WeiboPracticeActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/practice/WeiboPracticeActivity.java @@ -1,21 +1,23 @@ package com.scwang.refreshlayout.activity.practice; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.support.v4.widget.NestedScrollView; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; +import android.widget.Toast; import com.scwang.refreshlayout.R; import com.scwang.refreshlayout.util.StatusBarUtil; import com.scwang.smartrefresh.layout.api.RefreshHeader; import com.scwang.smartrefresh.layout.api.RefreshLayout; import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; -import com.scwang.smartrefresh.layout.util.DensityUtil; +import com.scwang.smartrefresh.layout.util.SmartUtil; /** - * 微博列表 + * 微博主页 */ public class WeiboPracticeActivity extends AppCompatActivity { @@ -27,7 +29,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_practice_weibo); - final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -38,29 +40,58 @@ public void onClick(View v) { //状态栏透明和间距处理 StatusBarUtil.immersive(this); StatusBarUtil.setPaddingSmart(this, toolbar); + StatusBarUtil.setMargin(this, findViewById(R.id.header)); final View parallax = findViewById(R.id.parallax); final View buttonBar = findViewById(R.id.buttonBarLayout); - final NestedScrollView scrollView = (NestedScrollView)findViewById(R.id.scrollView); - final RefreshLayout refreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + final NestedScrollView scrollView = findViewById(R.id.scrollView); + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout); + + findViewById(R.id.attention).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Toast.makeText(view.getContext(),"点击了关注",Toast.LENGTH_SHORT).show(); + } + }); + findViewById(R.id.leaveword).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Toast.makeText(view.getContext(),"点击了留言",Toast.LENGTH_SHORT).show(); + } + }); refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { @Override - public void onHeaderPulling(RefreshHeader header, float percent, int offset, int bottomHeight, int extendHeight) { - mOffset = offset / 2; - parallax.setTranslationY(mOffset - mScrollY); - toolbar.setAlpha(1 - Math.min(percent, 1)); + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishRefresh(3000); + } + + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); } @Override - public void onHeaderReleasing(RefreshHeader header, float percent, int offset, int bottomHeight, int extendHeight) { + public void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) { mOffset = offset / 2; parallax.setTranslationY(mOffset - mScrollY); toolbar.setAlpha(1 - Math.min(percent, 1)); } +// @Override +// public void onHeaderPulling(@NonNull RefreshHeader header, float percent, int offset, int bottomHeight, int maxDragHeight) { +// mOffset = offset / 2; +// parallax.setTranslationY(mOffset - mScrollY); +// toolbar.setAlpha(1 - Math.min(percent, 1)); +// } +// @Override +// public void onHeaderReleasing(@NonNull RefreshHeader header, float percent, int offset, int bottomHeight, int maxDragHeight) { +// mOffset = offset / 2; +// parallax.setTranslationY(mOffset - mScrollY); +// toolbar.setAlpha(1 - Math.min(percent, 1)); +// } }); scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() { private int lastScrollY = 0; - private int h = DensityUtil.dp2px(170); + private int h = SmartUtil.dp2px(170); private int color = ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary)&0x00ffffff; @Override public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/CircleStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/BezierCircleStyleActivity.java similarity index 76% rename from app/src/main/java/com/scwang/refreshlayout/activity/style/CircleStyleActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/style/BezierCircleStyleActivity.java index f07b55ff..9b2bd813 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/CircleStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/BezierCircleStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -17,24 +18,26 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; -public class CircleStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { +public class BezierCircleStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 内容不偏移("下拉的时候列表内容停留在原位不动"), - 内容跟随偏移("下拉的时候列表内容跟随向下偏移"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 内容不偏移(R.string.item_style_content_translation_off), + 内容跟随偏移(R.string.item_style_content_translation_on), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -47,7 +50,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_circle); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -55,7 +58,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -67,11 +70,14 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -80,7 +86,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 内容不偏移: mRefreshLayout.setEnableHeaderTranslationContent(false); break; diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/WaveSwipStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/BezierRadarStyleActivity.java similarity index 67% rename from app/src/main/java/com/scwang/refreshlayout/activity/style/WaveSwipStyleActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/style/BezierRadarStyleActivity.java index 79cbfe6a..400452ce 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/WaveSwipStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/BezierRadarStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -16,38 +17,44 @@ import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.header.BezierRadarHeader; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; -public class WaveSwipStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { +public class BezierRadarStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 内容不偏移("下拉的时候列表内容停留在原位不动"), - 内容跟随偏移("下拉的时候列表内容跟随向下偏移"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 打开左右拖动(R.string.item_style_horizontal_drag_on), + 关闭左右拖动(R.string.item_style_horizontal_drag_off), + 内容不偏移(R.string.item_style_content_translation_off), + 内容跟随偏移(R.string.item_style_content_translation_on), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } private Toolbar mToolbar; private RefreshLayout mRefreshLayout; + private BezierRadarHeader mRefreshHeader; private static boolean isFirstEnter = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_style_wave_swip); + setContentView(R.layout.activity_style_bezier); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -55,7 +62,8 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); + mRefreshHeader = findViewById(R.id.header); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -67,11 +75,14 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -80,7 +91,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 内容不偏移: mRefreshLayout.setEnableHeaderTranslationContent(false); break; @@ -99,6 +110,12 @@ public void onItemClick(AdapterView parent, View view, int position, long id) case 橙色主题: setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark); break; + case 打开左右拖动: + mRefreshHeader.setEnableHorizontalDrag(true); + break; + case 关闭左右拖动: + mRefreshHeader.setEnableHorizontalDrag(false); + break; } mRefreshLayout.autoRefresh(); } @@ -111,4 +128,5 @@ private void setThemeColor(int colorPrimary, int colorPrimaryDark) { } } + } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/ClassicsStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/ClassicsStyleActivity.java index a15b4d36..b274bf98 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/ClassicsStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/ClassicsStyleActivity.java @@ -1,7 +1,11 @@ package com.scwang.refreshlayout.activity.style; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.LayerDrawable; import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; +import android.support.graphics.drawable.VectorDrawableCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -11,20 +15,21 @@ import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.AdapterView; +import android.widget.ImageView; import com.scwang.refreshlayout.R; import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.refreshlayout.util.DynamicTimeFormat; import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; import com.scwang.smartrefresh.layout.constant.SpinnerStyle; import com.scwang.smartrefresh.layout.header.ClassicsHeader; -import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Locale; import java.util.Random; @@ -36,19 +41,21 @@ public class ClassicsStyleActivity extends AppCompatActivity implements AdapterV private BaseRecyclerAdapter mAdpater; private enum Item { - 尺寸拉伸("下拉的时候Header的高度跟随变大"), - 位置平移("下拉的时候Header的位置向下偏移"), - 背后固定("下拉的时候Header固定在背后"), - 默认主题("更改为默认主题颜色"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), - 加载更多("上啦加载更多"), + 尺寸拉伸(R.string.item_style_spinner_scale), + 位置平移(R.string.item_style_spinner_translation), + 背后固定(R.string.item_style_spinner_behind), + 显示时间(R.string.item_style_spinner_update_on), + 隐藏时间(R.string.item_style_spinner_update_off), +// 加载更多(R.string.item_style_load_more), + 默认主题(R.string.item_style_theme_default_abstract), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -56,6 +63,7 @@ private enum Item { private RecyclerView mRecyclerView; private RefreshLayout mRefreshLayout; private ClassicsHeader mClassicsHeader; + private Drawable mDrawableProgress; private static boolean isFirstEnter = true; @Override @@ -63,7 +71,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_classics); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -71,14 +79,19 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); - int deta = new Random().nextInt(7 * 24 * 60 * 60 * 1000); + int delta = new Random().nextInt(7 * 24 * 60 * 60 * 1000); mClassicsHeader = (ClassicsHeader)mRefreshLayout.getRefreshHeader(); - mClassicsHeader.setLastUpdateTime(new Date(System.currentTimeMillis()-deta)); + mClassicsHeader.setLastUpdateTime(new Date(System.currentTimeMillis()-delta)); mClassicsHeader.setTimeFormat(new SimpleDateFormat("更新于 MM-dd HH:mm", Locale.CHINA)); mClassicsHeader.setTimeFormat(new DynamicTimeFormat("更新于 %s")); +// mDrawableProgress = mClassicsHeader.getProgressView().getDrawable(); + mDrawableProgress = ((ImageView)mClassicsHeader.findViewById(ClassicsHeader.ID_IMAGE_PROGRESS)).getDrawable(); + if (mDrawableProgress instanceof LayerDrawable) { + mDrawableProgress = ((LayerDrawable) mDrawableProgress).getDrawable(0); + } View view = findViewById(R.id.recyclerView); if (view instanceof RecyclerView) { @@ -86,11 +99,14 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(mAdpater = new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(mAdpater = new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -99,67 +115,50 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position if (isFirstEnter) { isFirstEnter = false; - //触发上啦加载 - mRefreshLayout.autoLoadmore(); - //通过多功能监听接口实现 在第一次加载完成之后 自动刷新 - mRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener(){ - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - if (oldState == RefreshState.LoadingFinish && newState == RefreshState.None) { - mRefreshLayout.autoRefresh(); - mRefreshLayout.setOnMultiPurposeListener(null);//保准只有第一次关联 - } - } - }); + //触发自动刷新 + mRefreshLayout.autoRefresh(); } -// mRefreshLayout.setOnRefreshLoadmoreListener(new OnRefreshLoadmoreListener() { -// @Override -// public void onRefresh(RefreshLayout refreshlayout) { -// refreshlayout.getLayout().postDelayed(new Runnable() { -// @Override -// public void run() { -// mRefreshLayout.finishRefresh(); -// mAdpater.refresh(Arrays.asList(Item.values())); -// } -// },2000); -// } -// -// @Override -// public void onLoadmore(RefreshLayout refreshlayout) { -// refreshlayout.getLayout().postDelayed(new Runnable() { -// @Override -// public void run() { -// mRefreshLayout.finishLoadmore(); -// mAdpater.loadmore(Arrays.asList(Item.values())); -// } -// },2000); -// } -// }); } @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 背后固定: mClassicsHeader.setSpinnerStyle(SpinnerStyle.FixedBehind); mRefreshLayout.setPrimaryColors(0xff444444, 0xffffffff); - /** + if (Build.VERSION.SDK_INT >= 21) { + mDrawableProgress.setTint(0xffffffff); + } else if (mDrawableProgress instanceof VectorDrawableCompat) { + ((VectorDrawableCompat) mDrawableProgress).setTint(0xffffffff); + } + /* * 由于是后面才设置,需要手动更改视图的位置 * 如果在 onCreate 或者 xml 中设置好[SpinnerStyle] 就不用手动调整位置了 */ mRefreshLayout.getLayout().bringChildToFront(mRecyclerView); break; case 尺寸拉伸: - mClassicsHeader.setSpinnerStyle(SpinnerStyle.Scale); + mClassicsHeader.setSpinnerStyle(SpinnerStyle.values[1]); break; case 位置平移: mClassicsHeader.setSpinnerStyle(SpinnerStyle.Translate); break; + case 显示时间: + mClassicsHeader.setEnableLastTime(true); + break; + case 隐藏时间: + mClassicsHeader.setEnableLastTime(false); + break; case 默认主题: setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark); mRefreshLayout.getLayout().setBackgroundResource(android.R.color.transparent); - mRefreshLayout.setPrimaryColorsId(android.R.color.transparent, android.R.color.tertiary_text_dark); + mRefreshLayout.setPrimaryColors(0, 0xff666666); + if (Build.VERSION.SDK_INT >= 21) { + mDrawableProgress.setTint(0xff666666); + } else if (mDrawableProgress instanceof VectorDrawableCompat) { + ((VectorDrawableCompat) mDrawableProgress).setTint(0xff666666); + } break; case 蓝色主题: setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark); @@ -173,9 +172,9 @@ public void onItemClick(AdapterView parent, View view, int position, long id) case 橙色主题: setThemeColor(android.R.color.holo_orange_light, android.R.color.holo_orange_dark); break; - case 加载更多: - mRefreshLayout.autoLoadmore(); - return; +// case 加载更多: +// mRefreshLayout.autoLoadMore(); +// return; } mRefreshLayout.autoRefresh(); } @@ -185,6 +184,9 @@ private void setThemeColor(int colorPrimary, int colorPrimaryDark) { mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white); if (Build.VERSION.SDK_INT >= 21) { getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark)); + mDrawableProgress.setTint(0xffffffff); + } else if (mDrawableProgress instanceof VectorDrawableCompat) { + ((VectorDrawableCompat) mDrawableProgress).setTint(0xffffffff); } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/DeliveryStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/DeliveryStyleActivity.java index 94240bbf..64688c34 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/DeliveryStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/DeliveryStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -17,22 +18,24 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; -import static com.scwang.refreshlayout.R.layout.listitem_style_delivery; +import static com.scwang.refreshlayout.R.layout.item_style_delivery; public class DeliveryStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 默认主题("更改为默认主题颜色"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 默认主题(R.string.item_style_theme_default_abstract), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -54,7 +57,7 @@ protected void onCreate(Bundle savedInstanceState) { window.getDecorView().setSystemUiVisibility(systemUiVisibility); } - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -62,7 +65,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -73,7 +76,10 @@ public void onClick(View v) { RecyclerView recyclerView = (RecyclerView) view; recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), listitem_style_delivery,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, item_style_delivery,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { } @@ -83,7 +89,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 默认主题: mToolbar.setBackgroundResource(android.R.color.white); mToolbar.setTitleTextColor(0xffbbbbbb); diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/DropboxStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/DropBoxStyleActivity.java similarity index 72% rename from app/src/main/java/com/scwang/refreshlayout/activity/style/DropboxStyleActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/style/DropBoxStyleActivity.java index ee6a86c2..2f718ada 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/DropboxStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/DropBoxStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -22,18 +23,32 @@ import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; -public class DropboxStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { +public class DropBoxStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 默认主题("更改为默认主题颜色"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 默认主题(R.string.item_style_theme_default_abstract), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), + + + 默认1主题(R.string.item_style_theme_default_abstract), + 橙色1主题(R.string.item_style_theme_orange_abstract), + 红色1主题(R.string.item_style_theme_red_abstract), + 绿色1主题(R.string.item_style_theme_green_abstract), + 蓝色1主题(R.string.item_style_theme_blue_abstract), + + + 默认2主题(R.string.item_style_theme_default_abstract), + 橙色2主题(R.string.item_style_theme_orange_abstract), + 红色2主题(R.string.item_style_theme_red_abstract), + 绿色2主题(R.string.item_style_theme_green_abstract), + 蓝色2主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -46,7 +61,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_dropbox); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -54,7 +69,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -70,7 +85,7 @@ public void onClick(View v) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -79,7 +94,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 默认主题: setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark); mRefreshLayout.setPrimaryColors(0xff283645, 0xff6ea9ff); diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/FlyRefreshStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/FlyRefreshStyleActivity.java index ff12f190..4c4b8fd4 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/FlyRefreshStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/FlyRefreshStyleActivity.java @@ -11,6 +11,7 @@ import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.shapes.OvalShape; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.FloatingActionButton; @@ -32,15 +33,16 @@ import com.scwang.refreshlayout.R; import com.scwang.refreshlayout.util.StatusBarUtil; import com.scwang.smartrefresh.header.FlyRefreshHeader; -import com.scwang.smartrefresh.header.flyrefresh.FlyView; -import com.scwang.smartrefresh.header.flyrefresh.MountanScenceView; +import com.scwang.smart.refresh.header.flyrefresh.FlyView; +import com.scwang.smart.refresh.header.flyrefresh.MountainSceneView; import com.scwang.smartrefresh.layout.api.RefreshHeader; import com.scwang.smartrefresh.layout.api.RefreshLayout; import com.scwang.smartrefresh.layout.listener.OnRefreshListener; import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; -import com.scwang.smartrefresh.layout.util.DensityUtil; +import com.scwang.smartrefresh.layout.util.SmartUtil; import java.text.DateFormat; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -51,14 +53,13 @@ public class FlyRefreshStyleActivity extends AppCompatActivity { private RecyclerView mListView; - private RefreshLayout mRefreshlayout; + private RefreshLayout mRefreshLayout; private ItemAdapter mAdapter; private FlyView mFlyView; private ArrayList mDataSet = new ArrayList<>(); - private LinearLayoutManager mLayoutManager; - private MountanScenceView mScenceView; + private LinearLayoutManager mLayoutManager; private FlyRefreshHeader mFlyRefreshHeader; private CollapsingToolbarLayout mToolbarLayout; private FloatingActionButton mActionButton; @@ -69,7 +70,7 @@ public class FlyRefreshStyleActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_fly_refresh); - final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + final Toolbar toolbar = findViewById(R.id.toolbar); setSupportActionBar(toolbar); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override @@ -78,27 +79,27 @@ public void onClick(View v) { } }); - /************************************************************ + /*----------------------------------------------------------- * 关键代码-开始 - ************************************************************/ - - mFlyView = (FlyView) findViewById(R.id.flyview); - mScenceView = (MountanScenceView) findViewById(R.id.mountan); - mFlyRefreshHeader = (FlyRefreshHeader)findViewById(R.id.flyrefresh); - mFlyRefreshHeader.setUp(mScenceView, mFlyView);//绑定场景和纸飞机 - mRefreshlayout = (RefreshLayout) findViewById(R.id.refreshLayout); - mRefreshlayout.setReboundInterpolator(new ElasticOutInterpolator());//设置回弹插值器,会带有弹簧震动效果 - mRefreshlayout.setReboundDuration(800);//设置回弹动画时长 - mRefreshlayout.setOnRefreshListener(new OnRefreshListener() { + *----------------------------------------------------------*/ + + MountainSceneView mSceneView = findViewById(R.id.mountain); + mFlyView = findViewById(R.id.flyView); + mFlyRefreshHeader = findViewById(R.id.flyRefresh); + mFlyRefreshHeader.setUp(mSceneView, mFlyView);//绑定场景和纸飞机 + mRefreshLayout = findViewById(R.id.refreshLayout); + mRefreshLayout.setReboundInterpolator(new ElasticOutInterpolator());//设置回弹插值器,会带有弹簧震动效果 + mRefreshLayout.setReboundDuration(800);//设置回弹动画时长 + mRefreshLayout.setOnRefreshListener(new OnRefreshListener() { @Override - public void onRefresh(RefreshLayout refreshlayout) { + public void onRefresh(@NonNull RefreshLayout refreshLayout) { View child = mListView.getChildAt(0); if (child != null) { //开始刷新的时候个第一个item设置动画效果 bounceAnimateView(child.findViewById(R.id.icon)); } updateTheme();//改变主题颜色 - mListView.postDelayed(new Runnable() { + mRefreshLayout.getLayout().postDelayed(new Runnable() { @Override public void run() { //通知刷新完成,这里改为通知Header,让纸飞机飞回来 @@ -112,51 +113,56 @@ public void onAnimationEnd(Animator animation) { } }); //设置 让 AppBarLayout 和 RefreshLayout 的滚动同步 并不保持 toolbar 位置不变 - final AppBarLayout appBar = (AppBarLayout) findViewById(R.id.app_bar); - mRefreshlayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { + final AppBarLayout appBar = findViewById(R.id.appbar); + mRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { @Override - public void onHeaderPulling(RefreshHeader header, float percent, int offset, int footerHeight, int extendHeight) { - appBar.setTranslationY(offset); - toolbar.setTranslationY(-offset); - } - @Override - public void onHeaderReleasing(RefreshHeader header, float percent, int offset, int footerHeight, int extendHeight) { + public void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) { appBar.setTranslationY(offset); toolbar.setTranslationY(-offset); } +// @Override +// public void onHeaderPulling(@NonNull RefreshHeader header, float percent, int offset, int footerHeight, int maxDragHeight) { +// appBar.setTranslationY(offset); +// toolbar.setTranslationY(-offset); +// } +// @Override +// public void onHeaderReleasing(@NonNull RefreshHeader header, float percent, int offset, int footerHeight, int maxDragHeight) { +// appBar.setTranslationY(offset); +// toolbar.setTranslationY(-offset); +// } }); - /************************************************************ + /*----------------------------------------------------------- * 关键代码-结束 - ************************************************************/ + *----------------------------------------------------------*/ if (isFirstEnter) { isFirstEnter = false; - mRefreshlayout.autoRefresh();//第一次进入触发自动刷新,演示效果 + mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 } - /** + /* * 初始化列表数据 */ initDataSet(); mAdapter = new ItemAdapter(this); mLayoutManager = new LinearLayoutManager(this); - mListView = (RecyclerView) findViewById(R.id.recyclerView); + mListView = findViewById(R.id.recyclerView); mListView.setLayoutManager(mLayoutManager); mListView.setAdapter(mAdapter); mListView.setItemAnimator(new SampleItemAnimator()); - mToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout); - mActionButton = (FloatingActionButton) findViewById(R.id.fab); - /** + mToolbarLayout = findViewById(R.id.toolbarLayout); + mActionButton = findViewById(R.id.fab); + /* * 设置点击 ActionButton 时候触发自动刷新 并改变主题颜色 */ mActionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { updateTheme(); - mRefreshlayout.autoRefresh(); + mRefreshLayout.autoRefresh(); } }); - /** + /* * 监听 AppBarLayout 的关闭和开启 给 FlyView(纸飞机) 和 ActionButton 设置关闭隐藏动画 */ appBar.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { @@ -183,7 +189,7 @@ public void onAnimationUpdate(ValueAnimator animation) { misAppbarExpand = true; mActionButton.animate().scaleX(1).scaleY(1); mFlyView.animate().scaleX(1).scaleY(1); - ValueAnimator animator = ValueAnimator.ofInt(mListView.getPaddingTop(), DensityUtil.dp2px(25)); + ValueAnimator animator = ValueAnimator.ofInt(mListView.getPaddingTop(), SmartUtil.dp2px(25)); animator.setDuration(300); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override @@ -200,8 +206,6 @@ public void onAnimationUpdate(ValueAnimator animation) { //状态栏透明和间距处理 StatusBarUtil.immersive(this); StatusBarUtil.setPaddingSmart(this, toolbar); -// StatusBarUtil.setPaddingSmart(this, findViewById(R.id.profile)); -// StatusBarUtil.setPaddingSmart(this, findViewById(R.id.blurview)); } private void updateTheme() { @@ -218,7 +222,7 @@ private void updateTheme() { @Override public void onClick(View v) { int color = ContextCompat.getColor(getApplication(), ids[index % ids.length]); - mRefreshlayout.setPrimaryColors(color); + mRefreshLayout.setPrimaryColors(color); mActionButton.setBackgroundColor(color); mActionButton.setBackgroundTintList(ColorStateList.valueOf(color)); mToolbarLayout.setContentScrimColor(color); @@ -230,13 +234,18 @@ public void onClick(View v) { } private void initDataSet() { - mDataSet.add(new ItemData(Color.parseColor("#76A9FC"), R.drawable.ic_fly_refresh_poll, "Meeting Minutes", new Date(2014 - 1900, 2, 9))); - mDataSet.add(new ItemData(Color.GRAY, R.drawable.ic_fly_refresh_folder, "Favorites Photos", new Date(2014 - 1900, 1, 3))); - mDataSet.add(new ItemData(Color.GRAY, R.drawable.ic_fly_refresh_folder, "Photos", new Date(2014 - 1900, 0, 9))); + try { + DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA); + mDataSet.add(new ItemData(0xFF76A9FC, R.drawable.ic_fly_refresh_poll, "Meeting Minutes", format.parse("2014-03-09"))); + mDataSet.add(new ItemData(Color.GRAY, R.drawable.ic_fly_refresh_folder, "Favorites Photos", format.parse("2014-02-03"))); + mDataSet.add(new ItemData(Color.GRAY, R.drawable.ic_fly_refresh_folder, "Photos", format.parse("2014-01-09"))); + } catch (ParseException e) { + e.printStackTrace(); + } } private void addItemData() { - ItemData itemData = new ItemData(Color.parseColor("#FFC970"), R.drawable.ic_fly_refresh_smartphone, "Magic Cube Show", new Date()); + ItemData itemData = new ItemData(0xFFFFC970, R.drawable.ic_fly_refresh_phone, "Magic Cube Show", new Date()); mDataSet.add(0, itemData); mAdapter.notifyItemInserted(0); mLayoutManager.scrollToPosition(0); @@ -264,23 +273,24 @@ private class ItemAdapter extends RecyclerView.Adapter { private LayoutInflater mInflater; private DateFormat dateFormat; - public ItemAdapter(Context context) { + ItemAdapter(Context context) { mInflater = LayoutInflater.from(context); dateFormat = SimpleDateFormat.getDateInstance(DateFormat.DEFAULT, Locale.ENGLISH); } + @NonNull @Override - public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { + public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { View view = mInflater.inflate(R.layout.activity_fly_refresh_item, viewGroup, false); return new ItemViewHolder(view); } @Override - public void onBindViewHolder(ItemViewHolder itemViewHolder, int i) { + public void onBindViewHolder(@NonNull ItemViewHolder itemViewHolder, int i) { final ItemData data = mDataSet.get(i); ShapeDrawable drawable = new ShapeDrawable(new OvalShape()); drawable.getPaint().setColor(data.color); - itemViewHolder.icon.setBackgroundDrawable(drawable); + itemViewHolder.icon.setBackground(drawable); itemViewHolder.icon.setImageResource(data.icon); itemViewHolder.title.setText(data.title); itemViewHolder.subTitle.setText(dateFormat.format(data.time)); @@ -298,7 +308,7 @@ private static class ItemViewHolder extends RecyclerView.ViewHolder { TextView title; TextView subTitle; - public ItemViewHolder(View itemView) { + ItemViewHolder(View itemView) { super(itemView); icon = (ImageView) itemView.findViewById(R.id.icon); title = (TextView) itemView.findViewById(R.id.title); @@ -309,20 +319,16 @@ public ItemViewHolder(View itemView) { public class ItemData { int color; - public int icon; + int icon; + Date time; public String title; - public Date time; - public ItemData(int color, int icon, String title, Date time) { + ItemData(int color, int icon, String title, Date time) { this.color = color; this.icon = icon; this.title = title; this.time = time; } - - public ItemData(int icon, String title) { - this(Color.DKGRAY, icon, title, new Date()); - } } public class SampleItemAnimator extends BaseItemAnimator { diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameBattleCityStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameBattleCityStyleActivity.java index ff72e43d..2694e8e6 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameBattleCityStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameBattleCityStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -17,7 +18,9 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; @@ -25,15 +28,15 @@ public class FunGameBattleCityStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 默认主题("更改为橙色默认颜色"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 默认主题(R.string.item_style_theme_default_abstract), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -46,7 +49,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_fungame_battlecity); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -54,7 +57,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -66,11 +69,15 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -79,7 +86,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 默认主题: mRefreshLayout.setPrimaryColorsId(android.R.color.white, android.R.color.black); break; diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameHitBlockStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameHitBlockStyleActivity.java index 0b6e106d..32591b5c 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameHitBlockStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/FunGameHitBlockStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -17,7 +18,9 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; @@ -25,15 +28,15 @@ public class FunGameHitBlockStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 默认主题("更改为橙色默认颜色"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 默认主题(R.string.item_style_theme_default_abstract), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -46,7 +49,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_fungame_hitblock); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -54,7 +57,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -66,20 +69,25 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); } + } @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 默认主题: mRefreshLayout.setPrimaryColorsId(android.R.color.white, android.R.color.black); break; diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/MaterialStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/MaterialStyleActivity.java index 0e115dcd..895ae767 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/MaterialStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/MaterialStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -18,28 +19,28 @@ import com.scwang.smartrefresh.header.MaterialHeader; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; public class MaterialStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { - - private enum Item { - 内容不偏移("下拉的时候列表内容停留在原位不动"), - 内容跟随偏移("下拉的时候列表内容跟随向下偏移"), - 打开背景("下拉的时候绘制贝塞尔曲线背景"), - 关闭背景("下拉的时候不绘制贝塞尔曲线背景"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 打开背景(R.string.item_style_bezier_on), + 关闭背景(R.string.item_style_bezier_off), + 内容不偏移(R.string.item_style_content_translation_off), + 内容跟随偏移(R.string.item_style_content_translation_on), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -53,15 +54,10 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_material); - mToolbar = (Toolbar)findViewById(R.id.toolbar); - mToolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); + mToolbar = findViewById(R.id.toolbar); + mToolbar.setNavigationOnClickListener(v -> finish()); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -75,11 +71,14 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -88,7 +87,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 内容不偏移: mRefreshLayout.setEnableHeaderTranslationContent(false); break; @@ -120,6 +119,8 @@ public void onItemClick(AdapterView parent, View view, int position, long id) private void setThemeColor(int colorPrimary, int colorPrimaryDark) { mToolbar.setBackgroundResource(colorPrimary); mRefreshLayout.setPrimaryColorsId(colorPrimary, android.R.color.white); + mMaterialHeader.setProgressBackgroundColorSchemeResource(colorPrimary); + mMaterialHeader.setColorSchemeResources(android.R.color.white); if (Build.VERSION.SDK_INT >= 21) { getWindow().setStatusBarColor(ContextCompat.getColor(this, colorPrimaryDark)); } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/PhoenixStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/PhoenixStyleActivity.java index 1b4ab3fb..96989fdd 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/PhoenixStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/PhoenixStyleActivity.java @@ -3,6 +3,7 @@ import android.content.res.ColorStateList; import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.FloatingActionButton; @@ -21,7 +22,9 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; @@ -29,16 +32,16 @@ public class PhoenixStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 折叠("折叠AppBarLayout,变成正常的列表页面"), - 展开("展开AppBarLayout,变成可伸展头部的页面"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 折叠(R.string.item_style_app_bar_collapse), + 展开(R.string.item_style_app_bar_expand), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -55,7 +58,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_phoenix); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -63,14 +66,14 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 } - mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar); - mToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout); + mAppBarLayout = findViewById(R.id.appbar); + mToolbarLayout = findViewById(R.id.toolbarLayout); View view = findViewById(R.id.recyclerView); if (view instanceof RecyclerView) { @@ -78,21 +81,24 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); mRecyclerView = recyclerView; } - /** - * 监听 AppBarLayout 的关闭和开启 给 FlyView(纸飞机) 和 ActionButton 设置关闭隐藏动画 + /* + * 监听 AppBarLayout 的关闭和开启 ActionButton 设置关闭隐藏动画 */ - mActionButton = (FloatingActionButton) findViewById(R.id.fab); + mActionButton = findViewById(R.id.fab); mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { boolean misAppbarExpand = true; View fab = findViewById(R.id.fab); @@ -114,7 +120,7 @@ public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 折叠: mAppBarLayout.setExpanded(false, true); mAppBarLayout.setEnabled(false); diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/StoreHouseStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/StoreHouseStyleActivity.java index d0a64724..74a1814b 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/StoreHouseStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/StoreHouseStyleActivity.java @@ -1,7 +1,9 @@ package com.scwang.refreshlayout.activity.style; +import android.graphics.Point; import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -15,9 +17,13 @@ import com.scwang.refreshlayout.R; import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.header.StoreHouseHeader; +import com.scwang.smartrefresh.layout.api.RefreshHeader; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; @@ -25,14 +31,18 @@ public class StoreHouseStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 显示商标(R.string.item_style_store_house_brand), + 显示图标(R.string.item_style_store_house_icon), + 显示中文(R.string.item_style_store_house_chinese), + 显示英文(R.string.item_style_store_house_english), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -45,7 +55,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_storehouse); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -53,7 +63,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -65,11 +75,14 @@ public void onClick(View v) { recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -78,7 +91,35 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { + case 显示中文: { + RefreshHeader refreshHeader = mRefreshLayout.getRefreshHeader(); + if (refreshHeader instanceof StoreHouseHeader) { + ((StoreHouseHeader) refreshHeader).initWithPointList(getPointList()); + } + break; + } + case 显示英文: { + RefreshHeader refreshHeader = mRefreshLayout.getRefreshHeader(); + if (refreshHeader instanceof StoreHouseHeader) { + ((StoreHouseHeader) refreshHeader).initWithString("SmartRefresh"); + } + break; + } + case 显示图标: { + RefreshHeader refreshHeader = mRefreshLayout.getRefreshHeader(); + if (refreshHeader instanceof StoreHouseHeader) { + ((StoreHouseHeader) refreshHeader).initWithStringArray(R.array.storehouse); + } + break; + } + case 显示商标: { + RefreshHeader refreshHeader = mRefreshLayout.getRefreshHeader(); + if (refreshHeader instanceof StoreHouseHeader) { + ((StoreHouseHeader) refreshHeader).initWithStringArray(R.array.akta); + } + break; + } case 蓝色主题: setThemeColor(R.color.colorPrimary, R.color.colorPrimaryDark); break; @@ -103,4 +144,80 @@ private void setThemeColor(int colorPrimary, int colorPrimaryDark) { } } + private List getPointList() { + // this point is taken from https://github.com/cloay/CRefreshLayout + List startPoints = new ArrayList<>(); + startPoints.add(new Point(240, 80)); + startPoints.add(new Point(270, 80)); + startPoints.add(new Point(265, 103)); + startPoints.add(new Point(255, 65)); + startPoints.add(new Point(275, 80)); + startPoints.add(new Point(275, 80)); + startPoints.add(new Point(302, 80)); + startPoints.add(new Point(275, 107)); + + startPoints.add(new Point(320, 70)); + startPoints.add(new Point(313, 80)); + startPoints.add(new Point(330, 63)); + startPoints.add(new Point(315, 87)); + startPoints.add(new Point(330, 80)); + startPoints.add(new Point(315, 100)); + startPoints.add(new Point(330, 90)); + startPoints.add(new Point(315, 110)); + startPoints.add(new Point(345, 65)); + startPoints.add(new Point(357, 67)); + startPoints.add(new Point(363, 103)); + + startPoints.add(new Point(375, 80)); + startPoints.add(new Point(375, 80)); + startPoints.add(new Point(425, 80)); + startPoints.add(new Point(380, 95)); + startPoints.add(new Point(400, 63)); + + List endPoints = new ArrayList<>(); + endPoints.add(new Point(270, 80)); + endPoints.add(new Point(270, 110)); + endPoints.add(new Point(270, 110)); + endPoints.add(new Point(250, 110)); + endPoints.add(new Point(275, 107)); + endPoints.add(new Point(302, 80)); + endPoints.add(new Point(302, 107)); + endPoints.add(new Point(302, 107)); + + endPoints.add(new Point(340, 70)); + endPoints.add(new Point(360, 80)); + endPoints.add(new Point(330, 80)); + endPoints.add(new Point(340, 87)); + endPoints.add(new Point(315, 100)); + endPoints.add(new Point(345, 98)); + endPoints.add(new Point(330, 120)); + endPoints.add(new Point(345, 108)); + endPoints.add(new Point(360, 120)); + endPoints.add(new Point(363, 75)); + endPoints.add(new Point(345, 117)); + + endPoints.add(new Point(380, 95)); + endPoints.add(new Point(425, 80)); + endPoints.add(new Point(420, 95)); + endPoints.add(new Point(420, 95)); + endPoints.add(new Point(400, 120)); + List list = new ArrayList<>(); + + int offsetX = Integer.MAX_VALUE; + int offsetY = Integer.MAX_VALUE; + + for (int i = 0; i < startPoints.size(); i++) { + offsetX = Math.min(startPoints.get(i).x, offsetX); + offsetY = Math.min(startPoints.get(i).y, offsetY); + } + for (int i = 0; i < endPoints.size(); i++) { + float[] point = new float[4]; + point[0] = startPoints.get(i).x - offsetX; + point[1] = startPoints.get(i).y - offsetY; + point[2] = endPoints.get(i).x - offsetX; + point[3] = endPoints.get(i).y - offsetY; + list.add(point); + } + return list; + } } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/TaurusStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/TaurusStyleActivity.java index 986dbe3c..e3026a1b 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/TaurusStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/TaurusStyleActivity.java @@ -3,6 +3,7 @@ import android.content.res.ColorStateList; import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CollapsingToolbarLayout; import android.support.design.widget.FloatingActionButton; @@ -21,7 +22,9 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; @@ -29,16 +32,16 @@ public class TaurusStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 折叠("折叠AppBarLayout,变成正常的列表页面"), - 展开("展开AppBarLayout,变成可伸展头部的页面"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 折叠(R.string.item_style_app_bar_collapse), + 展开(R.string.item_style_app_bar_expand), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -55,7 +58,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_taurus); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -63,14 +66,14 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 } - mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar); - mToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.toolbar_layout); + mAppBarLayout = findViewById(R.id.appbar); + mToolbarLayout = findViewById(R.id.toolbarLayout); View view = findViewById(R.id.recyclerView); if (view instanceof RecyclerView) { @@ -78,21 +81,24 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); mRecyclerView = recyclerView; } - /** - * 监听 AppBarLayout 的关闭和开启 给 FlyView(纸飞机) 和 ActionButton 设置关闭隐藏动画 + /* + * 监听 AppBarLayout 的关闭和开启 给 ActionButton 设置关闭隐藏动画 */ - mActionButton = (FloatingActionButton) findViewById(R.id.fab); + mActionButton = findViewById(R.id.fab); mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { boolean misAppbarExpand = true; View fab = findViewById(R.id.fab); @@ -114,7 +120,7 @@ public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 折叠: mAppBarLayout.setExpanded(false, true); mAppBarLayout.setEnabled(false); diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/WaterDropStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/WaterDropStyleActivity.java index 41b30a60..01be31fd 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/WaterDropStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/WaterDropStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -17,7 +18,9 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; @@ -25,17 +28,17 @@ public class WaterDropStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 内容不偏移("下拉的时候列表内容停留在原位不动"), - 内容跟随偏移("下拉的时候列表内容跟随向下偏移"), - 默认主题("更改为默认主题颜色"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 内容不偏移(R.string.item_style_content_translation_off), + 内容跟随偏移(R.string.item_style_content_translation_on), + 默认主题(R.string.item_style_theme_default_abstract), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -48,7 +51,7 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_style_water_drop); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -56,7 +59,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -68,11 +71,14 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -81,7 +87,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 内容不偏移: mRefreshLayout.setEnableHeaderTranslationContent(false); break; diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/style/BezierStyleActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/style/WaveSwipeStyleActivity.java similarity index 74% rename from app/src/main/java/com/scwang/refreshlayout/activity/style/BezierStyleActivity.java rename to app/src/main/java/com/scwang/refreshlayout/activity/style/WaveSwipeStyleActivity.java index a0dd47c3..a0825f0f 100644 --- a/app/src/main/java/com/scwang/refreshlayout/activity/style/BezierStyleActivity.java +++ b/app/src/main/java/com/scwang/refreshlayout/activity/style/WaveSwipeStyleActivity.java @@ -2,6 +2,7 @@ import android.os.Build; import android.os.Bundle; +import android.support.annotation.StringRes; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; @@ -17,24 +18,26 @@ import com.scwang.refreshlayout.adapter.SmartViewHolder; import com.scwang.smartrefresh.layout.api.RefreshLayout; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; -public class BezierStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { +public class WaveSwipeStyleActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { private enum Item { - 内容不偏移("下拉的时候列表内容停留在原位不动"), - 内容跟随偏移("下拉的时候列表内容跟随向下偏移"), - 橙色主题("更改为橙色主题颜色"), - 红色主题("更改为红色主题颜色"), - 绿色主题("更改为绿色主题颜色"), - 蓝色主题("更改为蓝色主题颜色"), + 内容不偏移(R.string.item_style_content_translation_off), + 内容跟随偏移(R.string.item_style_content_translation_on), + 橙色主题(R.string.item_style_theme_orange_abstract), + 红色主题(R.string.item_style_theme_red_abstract), + 绿色主题(R.string.item_style_theme_green_abstract), + 蓝色主题(R.string.item_style_theme_blue_abstract), ; - public String name; - Item(String name) { - this.name = name; + public int nameId; + Item(@StringRes int nameId) { + this.nameId = nameId; } } @@ -45,9 +48,9 @@ private enum Item { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_style_bezier); + setContentView(R.layout.activity_style_wave_swipe); - mToolbar = (Toolbar)findViewById(R.id.toolbar); + mToolbar = findViewById(R.id.toolbar); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -55,7 +58,7 @@ public void onClick(View v) { } }); - mRefreshLayout = (RefreshLayout)findViewById(R.id.refreshLayout); + mRefreshLayout = findViewById(R.id.refreshLayout); if (isFirstEnter) { isFirstEnter = false; mRefreshLayout.autoRefresh();//第一次进入触发自动刷新,演示效果 @@ -67,11 +70,15 @@ public void onClick(View v) { recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, VERTICAL)); recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + List items = new ArrayList<>(); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + items.addAll(Arrays.asList(Item.values())); + recyclerView.setAdapter(new BaseRecyclerAdapter(items, simple_list_item_2,this) { @Override protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.name); + holder.text(android.R.id.text2, model.nameId); holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); } }); @@ -80,7 +87,7 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - switch (Item.values()[position]) { + switch (Item.values()[position % Item.values().length]) { case 内容不偏移: mRefreshLayout.setEnableHeaderTranslationContent(false); break; @@ -111,5 +118,4 @@ private void setThemeColor(int colorPrimary, int colorPrimaryDark) { } } - } diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/using/AssignDefaultUsingActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/using/AssignDefaultUsingActivity.java deleted file mode 100644 index 724f2490..00000000 --- a/app/src/main/java/com/scwang/refreshlayout/activity/using/AssignDefaultUsingActivity.java +++ /dev/null @@ -1,93 +0,0 @@ -package com.scwang.refreshlayout.activity.using; - -import android.content.Context; -import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.view.View; - -import com.scwang.refreshlayout.R; -import com.scwang.smartrefresh.layout.SmartRefreshLayout; -import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreater; -import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreater; -import com.scwang.smartrefresh.layout.api.RefreshFooter; -import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; -import com.scwang.smartrefresh.layout.footer.ClassicsFooter; -import com.scwang.smartrefresh.layout.header.ClassicsHeader; -import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; - -/** - * 全局指定默认的Header和Footer - */ -public class AssignDefaultUsingActivity extends AppCompatActivity { - - private static boolean isFirstEnter = true; - - /** - * 关键代码,需要在布局生成之前设置,建议代码放在 Application.onCreate 中 - */ - public AssignDefaultUsingActivity() { - //设置全局的Header构建器 - SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() { - @NonNull - @Override - public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { - layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white);//创建同时可以先设置主题颜色 - ((View) layout).setBackgroundResource(R.color.colorPrimary);//设置刷新布局的背景融合Header主题色 - return new ClassicsHeader(context).setSpinnerStyle(SpinnerStyle.FixedBehind);//指定为经典Header,默认是 贝塞尔雷达Header - } - }); - //设置全局的Footer构建器 - SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() { - @NonNull - @Override - public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { - ClassicsFooter footer = new ClassicsFooter(context); - footer.setBackgroundResource(android.R.color.white); - footer.setSpinnerStyle(SpinnerStyle.Scale);//设置为拉伸模式 - return footer;//指定为经典Footer,默认是 BallPulseFooter - } - }); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_using_assign_default); - - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); - - /** - * 以下代码仅仅为了演示效果而已,不是必须的 - * 关键代码在构造函数中 - */ - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); - if (isFirstEnter) { - isFirstEnter = false; - //触发上啦加载 - refreshLayout.autoLoadmore(); - //通过多功能监听接口实现 在第一次加载完成之后 自动刷新 - refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener(){ - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - if (oldState == RefreshState.LoadingFinish - && newState == RefreshState.None) { - refreshLayout.autoRefresh(); - refreshLayout.setOnMultiPurposeListener(null); - } - } - }); - } - } - -} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/using/BasicUsingActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/using/BasicUsingActivity.java deleted file mode 100644 index 5eb05f7f..00000000 --- a/app/src/main/java/com/scwang/refreshlayout/activity/using/BasicUsingActivity.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.scwang.refreshlayout.activity.using; - -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.view.View; -import android.widget.ListView; -import android.widget.Toast; - -import com.scwang.refreshlayout.R; -import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; -import com.scwang.refreshlayout.adapter.SmartViewHolder; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener; -import com.scwang.smartrefresh.layout.listener.OnRefreshListener; - -import java.util.Arrays; -import java.util.Collection; -import java.util.Locale; - -import static android.R.layout.simple_list_item_2; - -/** - * 基本的功能使用 - */ -public class BasicUsingActivity extends AppCompatActivity { - - private BaseRecyclerAdapter mAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_using_basic); - - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); - - ListView listView = (ListView) findViewById(R.id.listview); - listView.setAdapter(mAdapter = new BaseRecyclerAdapter(simple_list_item_2) { - @Override - protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { - holder.text(android.R.id.text1, String.format(Locale.CHINA, "第%02d条数据", position)); - holder.text(android.R.id.text2, String.format(Locale.CHINA, "这是测试的第%02d条数据", position)); - holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); - } - }); - - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); - refreshLayout.setEnableAutoLoadmore(true);//开启自动加载功能(非必须) - refreshLayout.setOnRefreshListener(new OnRefreshListener() { - @Override - public void onRefresh(final RefreshLayout refreshlayout) { - ((View) refreshlayout).postDelayed(new Runnable() { - @Override - public void run() { - mAdapter.refresh(initData()); - refreshlayout.finishRefresh(); - } - }, 2000); - } - }); - refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() { - @Override - public void onLoadmore(final RefreshLayout refreshlayout) { - ((View) refreshlayout).postDelayed(new Runnable() { - @Override - public void run() { - mAdapter.loadmore(initData()); - refreshlayout.finishLoadmore(); - if (mAdapter.getItemCount() > 60) { - Toast.makeText(getApplication(), "数据全部加载完毕", Toast.LENGTH_SHORT).show(); - refreshlayout.setLoadmoreFinished(true);//将不会再次触发加载更多事件 - } - } - }, 2000); - } - }); - - //触发自动刷新 - refreshLayout.autoRefresh(); - - } - - private Collection initData() { - return Arrays.asList(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); - } -} diff --git a/app/src/main/java/com/scwang/refreshlayout/activity/using/ListenerUsingActivity.java b/app/src/main/java/com/scwang/refreshlayout/activity/using/ListenerUsingActivity.java deleted file mode 100644 index 1f7d87b6..00000000 --- a/app/src/main/java/com/scwang/refreshlayout/activity/using/ListenerUsingActivity.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.scwang.refreshlayout.activity.using; - -import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.Toolbar; -import android.view.View; -import android.widget.TextView; - -import com.scwang.refreshlayout.R; -import com.scwang.smartrefresh.layout.api.RefreshFooter; -import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; - -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -/** - * 多功能监听器的使用 - */ -public class ListenerUsingActivity extends AppCompatActivity { - - - private static DateFormat FORMAT = new SimpleDateFormat("HH:mm sss", Locale.CHINA); - - private TextView mTvContent; - private static boolean isFirstEnter = true; - private String mHeaderPulling; - private String mHeaderReleasing; - private String mFooterPulling; - private String mFooterReleasing; - private String mFooterStartAnimator; - private String mHeaderStartAnimator; - private String mFooterFinish; - private String mHeaderFinish; - private String mRefresh; - private String mLoadmore; - private String mStateChanged; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_using_listener); - - final Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar); - toolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - finish(); - } - }); - - mTvContent = (TextView) findViewById(R.id.content); - - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout); - refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { - @Override - public void onHeaderPulling(RefreshHeader header, float percent, int offset, int headerHeight, int extendHeight) { - mHeaderPulling = String.format(Locale.CHINA, "%s\npercent=%.02f offset=%03d\nheight=%03d extend=%03d", - FORMAT.format(new Date()), - percent,offset,headerHeight,extendHeight); - updateContent(); - } - - @Override - public void onHeaderReleasing(RefreshHeader header, float percent, int offset, int headerHeight, int extendHeight) { - mHeaderReleasing = String.format(Locale.CHINA, "%s\npercent=%.02f offset=%03d\nheight=%03d extend=%03d", - FORMAT.format(new Date()), - percent,offset,headerHeight,extendHeight); - updateContent(); - } - - @Override - public void onHeaderStartAnimator(RefreshHeader header, int headerHeight, int extendHeight) { - mHeaderStartAnimator = String.format(Locale.CHINA, "%s\nheight=%03d extend=%03d", - FORMAT.format(new Date()), - headerHeight,extendHeight); - updateContent(); - } - - @Override - public void onHeaderFinish(RefreshHeader header, boolean success) { - mHeaderFinish = String.format(Locale.CHINA, "%s - " + success,FORMAT.format(new Date())); - updateContent(); - } - - @Override - public void onFooterPulling(RefreshFooter footer, float percent, int offset, int footerHeight, int extendHeight) { - mFooterPulling = String.format(Locale.CHINA, "%s\npercent=%.02f\noffset=%03d height=%03d\nextend=%03d", - FORMAT.format(new Date()), - percent,offset,footerHeight,extendHeight); - updateContent(); - } - - @Override - public void onFooterReleasing(RefreshFooter footer, float percent, int offset, int footerHeight, int extendHeight) { - mFooterReleasing = String.format(Locale.CHINA, "%s\npercent=%.02f\noffset=%03d height=%03d\nextend=%03d", - FORMAT.format(new Date()), - percent,offset,footerHeight,extendHeight); - updateContent(); - } - - @Override - public void onFooterStartAnimator(RefreshFooter footer, int footerHeight, int extendHeight) { - mFooterStartAnimator = String.format(Locale.CHINA, "%s\nheight=%03d extend=%03d", - FORMAT.format(new Date()), - footerHeight,extendHeight); - updateContent(); - } - - @Override - public void onFooterFinish(RefreshFooter footer, boolean success) { - mFooterFinish = String.format(Locale.CHINA, "%s - " + success,FORMAT.format(new Date())); - updateContent(); - } - - @Override - public void onRefresh(RefreshLayout refreshlayout) { - mRefresh = String.format(Locale.CHINA, "%s",FORMAT.format(new Date())); - updateContent(); - } - - @Override - public void onLoadmore(RefreshLayout refreshlayout) { - mLoadmore = String.format(Locale.CHINA, "%s",FORMAT.format(new Date())); - updateContent(); - } - - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - mStateChanged = String.format(Locale.CHINA, "%s\nnew=%s\nold=%s", - FORMAT.format(new Date()), - newState.name(), - oldState.name()); - updateContent(); - } - }); - - - if (isFirstEnter) { - isFirstEnter = false; - //触发自动刷新 - refreshLayout.autoRefresh(); - } - - } - - private void updateContent() { - mTvContent.setText(String.format(Locale.CHINA, - "onStateChanged:%s\n\n" + - "onHeaderPulling:%s\n\n" + - "onHeaderReleasing:%s\n\n" + - "onHeaderStartAnimator:%s\n\n" + - "onHeaderFinish:%s\n\n" + - "onFooterPulling:%s\n\n" + - "onFooterReleasing:%s\n\n" + - "onFooterStartAnimator:%s\n\n" + - "onFooterFinish:%s\n\n" + - "onRefresh:%s\n\n" + - "onLoadmore:%s\n\n", - mStateChanged, - mHeaderPulling, - mHeaderReleasing, - mHeaderStartAnimator, - mHeaderFinish, - mFooterPulling, - mFooterReleasing, - mFooterStartAnimator, - mFooterFinish, - mRefresh, - mLoadmore)); - } - -} diff --git a/app/src/main/java/com/scwang/refreshlayout/adapter/BaseRecyclerAdapter.java b/app/src/main/java/com/scwang/refreshlayout/adapter/BaseRecyclerAdapter.java index 88af8c20..85e83a7a 100644 --- a/app/src/main/java/com/scwang/refreshlayout/adapter/BaseRecyclerAdapter.java +++ b/app/src/main/java/com/scwang/refreshlayout/adapter/BaseRecyclerAdapter.java @@ -16,17 +16,18 @@ /** * - * Created by SCWANG on 2017/6/11. + * Created by scwang on 2017/6/11. */ - +@SuppressWarnings({"UnusedReturnValue", "unused"}) public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter implements ListAdapter { // - private final int mLayoutId; private final List mList; - private AdapterView.OnItemClickListener mListener; + private int mLastPosition = -1; + private boolean mOpenAnimationEnable = true; + protected AdapterView.OnItemClickListener mListener; public BaseRecyclerAdapter(@LayoutRes int layoutId) { setHasStableIds(false); @@ -48,6 +49,14 @@ public BaseRecyclerAdapter(Collection collection, @LayoutRes int layoutId, Ad } // + private void addAnimate(SmartViewHolder holder, int postion) { + if (mOpenAnimationEnable && mLastPosition < postion) { + holder.itemView.setAlpha(0); + holder.itemView.animate().alpha(1).start(); + mLastPosition = postion; + } + } + // @Override public SmartViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @@ -65,32 +74,18 @@ public void onBindViewHolder(SmartViewHolder holder, int position) { public int getItemCount() { return mList.size(); } - // - - // - - public BaseRecyclerAdapter setOnItemClickListener(AdapterView.OnItemClickListener listener) { - mListener = listener; - return this; - } - public BaseRecyclerAdapter refresh(Collection collection) { - mList.clear(); - mList.addAll(collection); - notifyDataSetChanged(); - notifyListDataSetChanged(); - return this; + @Override + public void onViewAttachedToWindow(SmartViewHolder holder) { + super.onViewAttachedToWindow(holder); + addAnimate(holder, holder.getLayoutPosition()); } - public BaseRecyclerAdapter loadmore(Collection collection) { - mList.addAll(collection); - notifyDataSetChanged(); - notifyListDataSetChanged(); - return this; + public void setOpenAnimationEnable(boolean enabled) { + this.mOpenAnimationEnable = enabled; } // - // private final DataSetObservable mDataSetObservable = new DataSetObservable(); @@ -141,7 +136,9 @@ public View getView(int position, View convertView, ViewGroup parent) { convertView = holder.itemView; convertView.setTag(holder); } + holder.setPosition(position); onBindViewHolder(holder, position); + addAnimate(holder, position); return convertView; } @@ -166,6 +163,40 @@ public Object getItem(int position) { public int getCount() { return mList.size(); } + // + + // + public T get(int index) { + return mList.get(index); + } + + public BaseRecyclerAdapter setOnItemClickListener(AdapterView.OnItemClickListener listener) { + mListener = listener; + return this; + } + + public BaseRecyclerAdapter refresh(Collection collection) { + mList.clear(); + mList.addAll(collection); + notifyDataSetChanged(); + notifyListDataSetChanged(); + mLastPosition = -1; + return this; + } + public BaseRecyclerAdapter loadMore(Collection collection) { + mList.addAll(collection); + notifyDataSetChanged(); + notifyListDataSetChanged(); + return this; + } + + public BaseRecyclerAdapter insert(Collection collection) { + mList.addAll(0, collection); + notifyItemRangeInserted(0, collection.size()); + notifyListDataSetChanged(); + return this; + } // + } diff --git a/app/src/main/java/com/scwang/refreshlayout/adapter/SmartViewHolder.java b/app/src/main/java/com/scwang/refreshlayout/adapter/SmartViewHolder.java index 66b69c26..57cb17f2 100644 --- a/app/src/main/java/com/scwang/refreshlayout/adapter/SmartViewHolder.java +++ b/app/src/main/java/com/scwang/refreshlayout/adapter/SmartViewHolder.java @@ -13,13 +13,14 @@ public class SmartViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private final AdapterView.OnItemClickListener mListener; + private int mPosition = -1; public SmartViewHolder(View itemView, AdapterView.OnItemClickListener mListener) { super(itemView); this.mListener = mListener; itemView.setOnClickListener(this); - /** + /* * 设置水波纹背景 */ if (itemView.getBackground() == null) { @@ -36,12 +37,18 @@ public SmartViewHolder(View itemView, AdapterView.OnItemClickListener mListener) } } + public void setPosition(int position) { + mPosition = position; + } + @Override public void onClick(View v) { if (mListener != null) { int position = getAdapterPosition(); if(position >= 0){ mListener.onItemClick(null, v, position, getItemId()); + } else if (mPosition > -1) { + mListener.onItemClick(null, v, mPosition, getItemId()); } } } @@ -81,4 +88,20 @@ public SmartViewHolder image(int id, int imageId) { } return this; } + + public SmartViewHolder gone(int id) { + View view = findViewById(id); + if (view != null) { + view.setVisibility(View.GONE); + } + return this; + } + + public SmartViewHolder visible(int id) { + View view = findViewById(id); + if (view != null) { + view.setVisibility(View.VISIBLE); + } + return this; + } } \ No newline at end of file diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshStylesFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshStylesFragment.java deleted file mode 100644 index 2b056cd4..00000000 --- a/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshStylesFragment.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.scwang.refreshlayout.fragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.annotation.StringRes; -import android.support.v4.app.Fragment; -import android.support.v7.widget.DefaultItemAnimator; -import android.support.v7.widget.DividerItemDecoration; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; - -import com.scwang.refreshlayout.R; -import com.scwang.refreshlayout.activity.ExperimentActivity; -import com.scwang.refreshlayout.activity.style.BezierStyleActivity; -import com.scwang.refreshlayout.activity.style.CircleStyleActivity; -import com.scwang.refreshlayout.activity.style.ClassicsStyleActivity; -import com.scwang.refreshlayout.activity.style.DeliveryStyleActivity; -import com.scwang.refreshlayout.activity.style.DropboxStyleActivity; -import com.scwang.refreshlayout.activity.style.FlyRefreshStyleActivity; -import com.scwang.refreshlayout.activity.style.FunGameBattleCityStyleActivity; -import com.scwang.refreshlayout.activity.style.FunGameHitBlockStyleActivity; -import com.scwang.refreshlayout.activity.style.MaterialStyleActivity; -import com.scwang.refreshlayout.activity.style.PhoenixStyleActivity; -import com.scwang.refreshlayout.activity.style.StoreHouseStyleActivity; -import com.scwang.refreshlayout.activity.style.TaurusStyleActivity; -import com.scwang.refreshlayout.activity.style.WaterDropStyleActivity; -import com.scwang.refreshlayout.activity.style.WaveSwipStyleActivity; -import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; -import com.scwang.refreshlayout.adapter.SmartViewHolder; -import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.header.ClassicsHeader; - -import java.lang.reflect.Constructor; -import java.util.Arrays; - -import static android.R.layout.simple_list_item_2; -import static android.support.v7.widget.DividerItemDecoration.VERTICAL; -import static com.scwang.refreshlayout.R.id.recyclerView; - -/** - * 风格展示 - * A simple {@link Fragment} subclass. - */ -public class RefreshStylesFragment extends Fragment implements AdapterView.OnItemClickListener { - - private enum Item { - Delivery(R.string.title_activity_style_delivery,DeliveryStyleActivity.class), - Dropbox(R.string.title_activity_style_dropbox, DropboxStyleActivity.class), - FlyRefresh(R.string.title_activity_style_flyrefresh, FlyRefreshStyleActivity.class), - WaveSwipe(R.string.title_activity_style_wave_swip, WaveSwipStyleActivity.class), - WaterDrop(R.string.title_activity_style_water_drop, WaterDropStyleActivity.class), - Material(R.string.title_activity_style_material, MaterialStyleActivity.class), - Phoenix(R.string.title_activity_style_phoenix, PhoenixStyleActivity.class), - Taurus(R.string.title_activity_style_taurus, TaurusStyleActivity.class), - Bezier(R.string.title_activity_style_bezier, BezierStyleActivity.class), - Circle(R.string.title_activity_style_circle, CircleStyleActivity.class), - FunGameHitBlock(R.string.title_activity_style_fungame_hitblock, FunGameHitBlockStyleActivity.class), - FunGameBattleCity(R.string.title_activity_style_fungame_battlecity, FunGameBattleCityStyleActivity.class), - StoreHouse(R.string.title_activity_style_storehouse, StoreHouseStyleActivity.class), - Classics(R.string.title_activity_style_classics, ClassicsStyleActivity.class), - ; - public int nameId; - public Class clazz; - Item(@StringRes int nameId, Class clazz) { - this.nameId = nameId; - this.clazz = clazz; - } - - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_refresh_styles, container, false); - } - - @Override - public void onViewCreated(View root, @Nullable Bundle savedInstanceState) { - super.onViewCreated(root, savedInstanceState); - - View view = root.findViewById(recyclerView); - if (view instanceof RecyclerView) { - RecyclerView recyclerView = (RecyclerView) view; - recyclerView.setItemAnimator(new DefaultItemAnimator()); - recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); - recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { - @Override - protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { - holder.text(android.R.id.text1, model.name()); - holder.text(android.R.id.text2, model.nameId); - holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); - } - }); - } - - root.findViewById(R.id.toolbar).setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - startActivity(new Intent(getContext(), ExperimentActivity.class)); - return false; - } - }); - } - - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - Item item = Item.values()[position]; - if (Activity.class.isAssignableFrom(item.clazz)) { - startActivity(new Intent(getContext(), item.clazz)); - } else if (RefreshHeader.class.isAssignableFrom(item.clazz)) { - try { - Constructor constructor = item.clazz.getConstructor(Context.class); - RefreshHeader header = (RefreshHeader) constructor.newInstance(getContext()); - RefreshLayout layout = (RefreshLayout) getView().findViewById(R.id.refreshLayout); - layout.setRefreshHeader(header); - if (!(header instanceof ClassicsHeader)) { - layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white); - } - layout.autoRefresh(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } -} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/BottomSheetExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/BottomSheetExampleFragment.java new file mode 100644 index 00000000..01ca93f0 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/BottomSheetExampleFragment.java @@ -0,0 +1,104 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.BottomSheetDialog; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; + +import java.util.Arrays; +import java.util.Collection; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * 使用示例-BottomSheet + * A simple {@link Fragment} subclass. + */ +public class BottomSheetExampleFragment extends Fragment { + + private BaseRecyclerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_bottom_sheet, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + root = onCreateView(LayoutInflater.from(getContext()), null, null); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + refreshLayout.setRefreshHeader(new ClassicsHeader(getContext()).setSpinnerStyle(SpinnerStyle.FixedBehind).setPrimaryColorId(R.color.colorPrimary).setAccentColorId(android.R.color.white)); + refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.loadMore(initData()); + refreshLayout.finishLoadMore(); + } + },2000); + } + }); + + RecyclerView recyclerView = root.findViewById(R.id.recyclerView); + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + + recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(initData(),simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + + BottomSheetDialog dialog = new BottomSheetDialog(getContext()); + dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + getActivity().finish(); + } + }); + dialog.setContentView(root); + dialog.setCancelable(false); + dialog.show(); + } + + private Collection initData() { + return Arrays.asList(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/DisallowInterceptExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/DisallowInterceptExampleFragment.java new file mode 100644 index 00000000..aa002b27 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/DisallowInterceptExampleFragment.java @@ -0,0 +1,114 @@ +package com.scwang.refreshlayout.fragment.example; + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.AppCompatTextView; +import android.support.v7.widget.Toolbar; +import android.util.AttributeSet; +import android.view.*; +import com.scwang.refreshlayout.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class DisallowInterceptExampleFragment extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_example_disallow_intercept, container, false); + } + + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + } + + public static class MoveView extends AppCompatTextView { + + + //移动的阈值 + private static final int TOUCH_SLOP = 20; + /** + * 点击按下事件 X坐标记录 + */ + private float mLastMotionX; + /** + * 点击按下事件 Y坐标记录 + */ + private float mLastMotionY; + + private boolean mDelay; + + /** + * 长按模式的标记位 + */ + private boolean isLongPress; + + /** + * 长按的runnable + */ + private Runnable mLongPressRunnable = new Runnable() { + @Override + public void run() { + isLongPress = true; + mDelay = false; + getParent().requestDisallowInterceptTouchEvent(true); + } + }; + + public MoveView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + float x = event.getX(); + float y = event.getY(); + + switch (event.getAction()) { + case MotionEvent.ACTION_DOWN: + mLastMotionX = x; + mLastMotionY = y; + postDelayed(mLongPressRunnable, ViewConfiguration.getLongPressTimeout()); + mDelay = true; + break; + case MotionEvent.ACTION_MOVE: + if (isLongPress) { + //长按状态下.绘制时间和轴线 + setText("x=" + x + ";y=" + y); + } else if (mDelay && (Math.abs(mLastMotionX - x) > TOUCH_SLOP + || Math.abs(mLastMotionY - y) > TOUCH_SLOP)) { + //移动超过阈值,则表示移动了 + removeCallbacks(mLongPressRunnable); + mDelay = false; + } + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + default: + //释放了 + removeCallbacks(mLongPressRunnable); + isLongPress = false; + mDelay = false; + invalidate(); + break; + } + return true; + } + + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragment.java new file mode 100644 index 00000000..35bd1e13 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragment.java @@ -0,0 +1,144 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; +import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; + +import java.util.Arrays; + +import ezy.ui.layout.LoadingLayout; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; +import static com.scwang.refreshlayout.R.id.recyclerView; +import static com.scwang.refreshlayout.R.id.refreshLayout; + +/** + * 使用示例-空布页面 + * A simple {@link Fragment} subclass. + */ +public class EmptyLayoutExampleFragment extends Fragment implements AdapterView.OnItemClickListener, OnRefreshListener { + + public enum Item { + ThirdParty("集成第三方控件", EmptyLayoutExampleFragment.class), + NestedInner("内部嵌套", EmptyLayoutExampleFragmentInner.class), + NestedOuter("外部嵌套", EmptyLayoutExampleFragmentOuter.class), + ; + public String name; + public Class clazz; + Item(String name, Class clazz) { + this.name = name; + this.clazz = clazz; + } + } + + private RecyclerView mRecyclerView; + private RefreshLayout mRefreshLayout; + private LoadingLayout mLoadingLayout; + private static boolean mIsNeedDemo = true; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_emptylayout, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + mRefreshLayout = root.findViewById(refreshLayout); + mRefreshLayout.setRefreshHeader(new ClassicsHeader(getContext()).setSpinnerStyle(SpinnerStyle.FixedBehind).setPrimaryColorId(R.color.colorPrimary).setAccentColorId(android.R.color.white)); + mRefreshLayout.setOnRefreshListener(this); + + mRecyclerView = root.findViewById(recyclerView); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + + mLoadingLayout = root.findViewById(R.id.loading); + mLoadingLayout.showEmpty(); + + /*主动演示刷新*/ + if (mIsNeedDemo) { + mRefreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + if (mIsNeedDemo) { + mRefreshLayout.autoRefresh(); + } + } + }, 3000); + mRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + mIsNeedDemo = false; + } + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); + } + }); + } + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mRefreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mRecyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,EmptyLayoutExampleFragment.this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + mRefreshLayout.finishRefresh(); + mLoadingLayout.showContent(); + } + }, 2000); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Item item = Item.values()[position]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragmentInner.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragmentInner.java new file mode 100644 index 00000000..17d114e2 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragmentInner.java @@ -0,0 +1,140 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ImageView; +import android.widget.TextView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.fragment.example.EmptyLayoutExampleFragment.Item; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; +import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; + +import java.util.ArrayList; +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; +import static com.scwang.refreshlayout.R.id.recyclerView; +import static com.scwang.refreshlayout.R.id.refreshLayout; + +/** + * 使用示例-空布页面 + * A simple {@link Fragment} subclass. + */ +public class EmptyLayoutExampleFragmentInner extends Fragment implements AdapterView.OnItemClickListener, OnRefreshListener { + + private View mEmptyLayout; + private RecyclerView mRecyclerView; + private RefreshLayout mRefreshLayout; + private static boolean mIsNeedDemo = true; + private BaseRecyclerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_emptylayout_inner, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + mRefreshLayout = root.findViewById(refreshLayout); + mRefreshLayout.setRefreshHeader(new ClassicsHeader(getContext()).setSpinnerStyle(SpinnerStyle.FixedBehind).setPrimaryColorId(R.color.colorPrimary).setAccentColorId(android.R.color.white)); + mRefreshLayout.setOnRefreshListener(this); + + mRecyclerView = root.findViewById(recyclerView); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + mRecyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(new ArrayList(), simple_list_item_2,EmptyLayoutExampleFragmentInner.this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + + mEmptyLayout = root.findViewById(R.id.empty); + + ImageView image = root.findViewById(R.id.empty_image); + image.setImageResource(R.drawable.ic_empty); + + TextView empty = root.findViewById(R.id.empty_text); + empty.setText("暂无数据下拉刷新"); + + /*主动演示刷新*/ + if (mIsNeedDemo) { + mRefreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + if (mIsNeedDemo) { + mRefreshLayout.autoRefresh(); + } + } + }, 3000); + mRefreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + mIsNeedDemo = false; + } + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); + } + }); + } + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mRefreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.refresh(Arrays.asList(Item.values())); + mRefreshLayout.finishRefresh(); + mEmptyLayout.setVisibility(View.GONE); + } + }, 2000); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Item item = Item.values()[position]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragmentOuter.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragmentOuter.java new file mode 100644 index 00000000..8a6ed357 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/EmptyLayoutExampleFragmentOuter.java @@ -0,0 +1,124 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ImageView; +import android.widget.TextView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.fragment.example.EmptyLayoutExampleFragment.Item; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; + +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; +import static com.scwang.refreshlayout.R.id.recyclerView; +import static com.scwang.refreshlayout.R.id.refreshLayout; + +/** + * 使用示例-空布页面 + * A simple {@link Fragment} subclass. + */ +public class EmptyLayoutExampleFragmentOuter extends Fragment implements AdapterView.OnItemClickListener, OnRefreshListener { + + private View mEmptyLayout; + private RecyclerView mRecyclerView; + private RefreshLayout mRefreshLayout; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_emptylayout_outer, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + mRefreshLayout = root.findViewById(refreshLayout); + mRefreshLayout.setRefreshHeader(new ClassicsHeader(getContext()).setSpinnerStyle(SpinnerStyle.FixedBehind).setPrimaryColorId(R.color.colorPrimary).setAccentColorId(android.R.color.white)); + mRefreshLayout.setOnRefreshListener(this); + + mRecyclerView = root.findViewById(recyclerView); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + + mEmptyLayout = root.findViewById(R.id.empty); + + ImageView image = root.findViewById(R.id.empty_image); + image.setImageResource(R.drawable.ic_empty); + + TextView empty = root.findViewById(R.id.empty_text); + empty.setText("暂无数据点击刷新"); + + ((View)empty.getParent()).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + doRefresh(0); + } + }); + + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + doRefresh(2000); + } + + protected void doRefresh(int delayed) { + mRefreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mRecyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2, EmptyLayoutExampleFragmentOuter.this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + mRefreshLayout.finishRefresh(); + mEmptyLayout.setVisibility(View.GONE); + } + }, delayed); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Item item = Item.values()[position]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/FlexBoxLayoutManagerFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/FlexBoxLayoutManagerFragment.java new file mode 100644 index 00000000..d3c68e66 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/FlexBoxLayoutManagerFragment.java @@ -0,0 +1,98 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.google.android.flexbox.AlignItems; +import com.google.android.flexbox.FlexDirection; +import com.google.android.flexbox.FlexWrap; +import com.google.android.flexbox.FlexboxLayoutManager; +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.util.SmartUtil; + +import java.util.Arrays; +import java.util.Random; + +/** + * A simple {@link Fragment} subclass. + */ +public class FlexBoxLayoutManagerFragment extends Fragment { + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_flexbox_layout_manager, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + FlexboxLayoutManager manager = new FlexboxLayoutManager(root.getContext()); + //设置主轴排列方式 + manager.setFlexDirection(FlexDirection.ROW); + //设置是否换行 + manager.setFlexWrap(FlexWrap.WRAP); + manager.setAlignItems(AlignItems.STRETCH); + + RecyclerView recyclerView = root.findViewById(R.id.recyclerView); + recyclerView.setLayoutManager(manager); + recyclerView.setClipToPadding(false); + recyclerView.setPadding(SmartUtil.dp2px(2.5f),SmartUtil.dp2px(2.5f),SmartUtil.dp2px(2.5f),SmartUtil.dp2px(2.5f)); + + recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(new Object[100]),0) { + + Random random = new Random(); + + @Override + protected void onBindViewHolder(SmartViewHolder holder, Object model, int position) { + + int[] colorIds = { + R.color.colorPrimaryDark, + android.R.color.holo_green_dark, + android.R.color.holo_red_dark, + android.R.color.holo_orange_dark, + }; + + holder.itemView.setBackgroundResource(colorIds[random.nextInt(colorIds.length)]); + holder.itemView.setMinimumWidth(SmartUtil.dp2px(70f + random.nextInt(70))); + } + @NonNull + @Override + public SmartViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + FlexboxLayoutManager.LayoutParams lp = new FlexboxLayoutManager.LayoutParams(-2,-2); + lp.setFlexGrow(1); + lp.bottomMargin = SmartUtil.dp2px(2.5f); + lp.topMargin = SmartUtil.dp2px(2.5f); + lp.leftMargin = SmartUtil.dp2px(2.5f); + lp.rightMargin = SmartUtil.dp2px(2.5f); + ImageView imageVIew = new ImageView(parent.getContext()); + imageVIew.setMinimumWidth(SmartUtil.dp2px(90f)); + imageVIew.setMinimumHeight(SmartUtil.dp2px(90f)); + imageVIew.setLayoutParams(lp); + return new SmartViewHolder(imageVIew, mListener); + } + }); + } + + +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/HorizontalExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/HorizontalExampleFragment.java new file mode 100644 index 00000000..3475dacd --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/HorizontalExampleFragment.java @@ -0,0 +1,118 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.os.Build; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Objects; + +import static android.R.layout.simple_list_item_2; + +/** + * A simple {@link Fragment} subclass. + */ +public class HorizontalExampleFragment extends Fragment { + + private BaseRecyclerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_example_horizontal, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + root.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + Objects.requireNonNull(getActivity()).getWindow().setStatusBarColor(0); + } + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + final RecyclerView recyclerView = root.findViewById(R.id.recyclerView); + + recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(simple_list_item_2) { + + int[] colorIds = { + android.R.color.holo_blue_dark, + android.R.color.holo_green_dark, + android.R.color.holo_red_dark, + android.R.color.holo_orange_dark, + }; + + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.itemView.getLayoutParams().width = -2;//SmartUtil.dp2px(100); + holder.itemView.getLayoutParams().height = -1; + holder.itemView.setBackgroundResource(colorIds[position%colorIds.length]); + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.textColorId(android.R.id.text1, android.R.color.white); + + } + }); + + mAdapter.refresh(initData()); + + RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); +//// refreshLayout.setRefreshHeader(new MaterialHeader(root.getContext())); +// refreshLayout.setRefreshFooter(new RefreshFooterWrapper(new MaterialHeader(root.getContext())), -1, -2); +//// refreshLayout.setEnableHeaderTranslationContent(true); +// refreshLayout.setEnableFooterTranslationContent(true); +// refreshLayout.setEnableAutoLoadMore(false); + + refreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onRefresh(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.refresh(initData()); + refreshLayout.finishRefresh(); + } + }, 2000); + } + + @Override + public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { + recyclerView.stopScroll(); + recyclerView.stopNestedScroll(); + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.loadMore(initData()); + refreshLayout.finishLoadMore(); + } + }, 2000); + } + }); + } + + private Collection initData() { + return Arrays.asList(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragment.java new file mode 100644 index 00000000..66f9f358 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragment.java @@ -0,0 +1,160 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.AppBarLayout; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.footer.ClassicsFooter; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; + +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * 使用示例-嵌套滚动 + * A simple {@link Fragment} subclass. + */ +public class NestedScrollExampleFragment extends Fragment implements AdapterView.OnItemClickListener { + + public enum Item { + NestedStandard("标准嵌套", NestedScrollExampleFragment.class), + NestedIntegral("整体嵌套", NestedScrollExampleFragmentIntegral.class), + NestedViewPager("ViewPager", NestedScrollExampleFragmentViewPager.class), + ; + public String name; + public Class clazz; + Item(String name, Class clazz) { + this.name = name; + this.clazz = clazz; + } + } + + private static boolean mNestedPager = false; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_nestedscroll, container, false); + } + + @Override + public void onDestroy() { + super.onDestroy(); + mNestedPager = false; + } + + @Override + public void onViewCreated(@NonNull final View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + final BaseRecyclerAdapter adapter; + RecyclerView recyclerView = root.findViewById(R.id.recyclerView); + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + recyclerView.setAdapter(adapter = new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2, NestedScrollExampleFragment.this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + if (mNestedPager) { + final Runnable loadMore = new Runnable() { + @Override + public void run() { + adapter.loadMore(Arrays.asList(Item.values())); + adapter.loadMore(Arrays.asList(Item.values())); + adapter.loadMore(Arrays.asList(Item.values())); + adapter.loadMore(Arrays.asList(Item.values())); + adapter.loadMore(Arrays.asList(Item.values())); + adapter.loadMore(Arrays.asList(Item.values())); + adapter.loadMore(Arrays.asList(Item.values())); + } + }; + final RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + refreshLayout.setEnableFooterFollowWhenNoMoreData(true); + refreshLayout.setRefreshFooter(new ClassicsFooter(getContext())); + refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { + if (adapter.getItemCount() < 100) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + loadMore.run(); + refreshLayout.finishLoadMore(); + } + }, 2000); + } else { + refreshLayout.finishLoadMoreWithNoMoreData(); + } + } + }); + loadMore.run(); + } + + /* + * 监听 AppBarLayout 的关闭和开启 ActionButton 设置关闭隐藏动画 + */ + AppBarLayout appBarLayout = root.findViewById(R.id.appbar); + appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { + boolean misAppbarExpand = true; + View fab = root.findViewById(R.id.fab); + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { + int scrollRange = appBarLayout.getTotalScrollRange(); + float fraction = 1f * (scrollRange + verticalOffset) / scrollRange; + if (fraction < 0.1 && misAppbarExpand) { + misAppbarExpand = false; + fab.animate().scaleX(0).scaleY(0); + } + if (fraction > 0.8 && !misAppbarExpand) { + misAppbarExpand = true; + fab.animate().scaleX(1).scaleY(1); + } + } + }); + + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + mNestedPager = true; + Item item = Item.values()[position%Item.values().length]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragmentIntegral.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragmentIntegral.java new file mode 100644 index 00000000..9306f573 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragmentIntegral.java @@ -0,0 +1,221 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.fragment.example.NestedScrollExampleFragment.Item; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; +import com.youth.banner.Banner; +import com.youth.banner.loader.ImageLoader; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import static android.R.layout.simple_list_item_2; +import static com.scwang.refreshlayout.R.mipmap.image_weibo_home_1; +import static com.scwang.refreshlayout.R.mipmap.image_weibo_home_2; + +/** + * 使用示例-嵌套滚动-整体 + * A simple {@link Fragment} subclass. + */ +public class NestedScrollExampleFragmentIntegral extends Fragment implements AdapterView.OnItemClickListener, OnRefreshLoadMoreListener { + + private ViewPager mViewPager; + private SmartPagerAdapter mAdapter; + +// private BaseRecyclerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_nestedscroll_integral, container, false); + } + + @Override + public void onViewCreated(@NonNull final View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + Banner banner = root.findViewById(R.id.banner); + banner.setImageLoader(new BannerImageLoader()); + banner.setImages(Arrays.asList(image_weibo_home_1, image_weibo_home_2)); + banner.start(); + + mViewPager = root.findViewById(R.id.viewPager); + mViewPager.setAdapter(mAdapter = new SmartPagerAdapter(getChildFragmentManager())); +// RecyclerView recyclerView = root.findViewById(R.id.recyclerView); +// recyclerView.setItemAnimator(new DefaultItemAnimator()); +// recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); +// recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); +// recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(buildItems(), simple_list_item_2, NestedScrollExampleFragmentIntegral.this) { +// @Override +// protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { +// holder.text(android.R.id.text1, model.name()); +// holder.text(android.R.id.text2, model.name); +// holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); +// } +// }); + + RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + refreshLayout.setOnRefreshLoadMoreListener(this); +// refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { +// @Override +// public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { +// refreshLayout.getLayout().postDelayed(new Runnable() { +// @Override +// public void run() { +// mAdapter.loadMore(buildItems()); +// refreshLayout.finishLoadMore(); +// } +// }, 2000); +// } +// }); + + TextView textView = root.findViewById(R.id.target); + textView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(getContext(), "点击测试", Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mAdapter.fragments[mViewPager.getCurrentItem()].onRefresh(refreshLayout); + } + + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + mAdapter.fragments[mViewPager.getCurrentItem()].onLoadMore(refreshLayout); + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + } + + private class BannerImageLoader extends ImageLoader { + @Override + public void displayImage(Context context, Object path, ImageView imageView) { + imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + imageView.setImageResource((Integer)path); + } + } + + + public static class SmartPagerAdapter extends FragmentStatePagerAdapter { + + private final SmartFragment[] fragments; + + SmartPagerAdapter(FragmentManager fm) { + super(fm); + this.fragments = new SmartFragment[]{ + new SmartFragment(),new SmartFragment() + }; + } + + @Override + public int getCount() { + return fragments.length; + } + + @Override + public Fragment getItem(int position) { + return fragments[position]; + } + } + + public static class SmartFragment extends Fragment { + + private RecyclerView mRecyclerView; + private BaseRecyclerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return mRecyclerView = new RecyclerView(inflater.getContext()); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL)); + mRecyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(buildItems(), simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + + private Collection buildItems() { + List items = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + items.addAll(Arrays.asList(Item.values())); + } + return items; + } + + + public void onRefresh(final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.refresh(buildItems()); + refreshLayout.finishRefresh(); + refreshLayout.resetNoMoreData();//setNoMoreData(false); + } + }, 2000); + } + + public void onLoadMore(final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.loadMore(buildItems()); + if (mAdapter.getItemCount() > 60) { + Toast.makeText(getContext(), "数据全部加载完毕", Toast.LENGTH_SHORT).show(); + refreshLayout.finishLoadMoreWithNoMoreData();//将不会再次触发加载更多事件 + } else { + refreshLayout.finishLoadMore(); + } + } + }, 2000); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragmentViewPager.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragmentViewPager.java new file mode 100644 index 00000000..19efcbfd --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NestedScrollExampleFragmentViewPager.java @@ -0,0 +1,167 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.design.widget.AppBarLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.header.PhoenixHeader; +import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import com.scwang.smartrefresh.layout.api.RefreshLayout; + +import java.util.Arrays; +import java.util.Collection; + +import static android.R.layout.simple_list_item_2; + +/** + * 使用示例-嵌套滚动-ViewPager + * A simple {@link Fragment} subclass. + */ +public class NestedScrollExampleFragmentViewPager extends Fragment { + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_nestedscroll_view_pager, container, false); + } + + @Override + public void onViewCreated(@NonNull final View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + ViewPager viewPager = root.findViewById(R.id.viewPager); + viewPager.setAdapter(new SmartPagerAdapter(getChildFragmentManager())); + + /* + * 监听 AppBarLayout 的关闭和开启 ActionButton 设置关闭隐藏动画 + */ + AppBarLayout appBarLayout = root.findViewById(R.id.appbar); + appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { + boolean misAppbarExpand = true; + View fab = root.findViewById(R.id.fab); + @Override + public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { + int scrollRange = appBarLayout.getTotalScrollRange(); + float fraction = 1f * (scrollRange + verticalOffset) / scrollRange; + if (fraction < 0.1 && misAppbarExpand) { + misAppbarExpand = false; + fab.animate().scaleX(0).scaleY(0); + } + if (fraction > 0.8 && !misAppbarExpand) { + misAppbarExpand = true; + fab.animate().scaleX(1).scaleY(1); + } + } + }); + + } + + public static class SmartPagerAdapter extends FragmentStatePagerAdapter { + + private final SmartFragment[] fragments; + + SmartPagerAdapter(FragmentManager fm) { + super(fm); + this.fragments = new SmartFragment[]{ + new SmartFragment(),new SmartFragment() + }; + } + + @Override + public int getCount() { + return fragments.length; + } + + @Override + public Fragment getItem(int position) { + return fragments[position]; + } + } + + public static class SmartFragment extends Fragment { + + private RecyclerView mRecyclerView; + private BaseRecyclerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + RefreshLayout refreshLayout = new SmartRefreshLayout(inflater.getContext()); + refreshLayout.setRefreshHeader(new PhoenixHeader(inflater.getContext())); + refreshLayout.setRefreshContent(mRecyclerView = new RecyclerView(inflater.getContext())); + refreshLayout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white); + refreshLayout.setEnableLoadMore(false); + return refreshLayout.getLayout(); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL)); + mRecyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(initData(), simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + + private Collection initData() { + return Arrays.asList(null,null,null); + } + + public void onRefresh(final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.refresh(initData()); + refreshLayout.finishRefresh(); + refreshLayout.resetNoMoreData();//setNoMoreData(false); + } + }, 2000); + } + + public void onLoadMore(final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.loadMore(initData()); + if (mAdapter.getItemCount() > 60) { + Toast.makeText(getContext(), "数据全部加载完毕", Toast.LENGTH_SHORT).show(); + refreshLayout.finishLoadMoreWithNoMoreData();//将不会再次触发加载更多事件 + } else { + refreshLayout.finishLoadMore(); + } + } + }, 2000); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/NoMoreDataExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NoMoreDataExampleFragment.java new file mode 100644 index 00000000..3dafc1ae --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/NoMoreDataExampleFragment.java @@ -0,0 +1,125 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Random; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * A simple {@link Fragment} subclass. + */ +public class NoMoreDataExampleFragment extends Fragment { + + private BaseRecyclerAdapter mAdapter; + + public NoMoreDataExampleFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_no_more_data_example, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + RecyclerView recyclerView = root.findViewById(R.id.recyclerView); + if (recyclerView != null) { + recyclerView.setNestedScrollingEnabled(false); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + + RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + if (refreshLayout != null) { + refreshLayout.autoRefresh(); + refreshLayout.setEnableLoadMoreWhenContentNotFull(false); + refreshLayout.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + Collection data = loadData(); + mAdapter.refresh(data); + if (data.size() < 9) { + refreshLayout.finishRefreshWithNoMoreData(); + } else { + refreshLayout.finishRefresh(); + } + } + }, 1000); + } + }); + refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + Collection list = loadData(); + mAdapter.loadMore(list); + if (list.size() < 10) { + refreshLayout.finishLoadMoreWithNoMoreData(); + } else { + refreshLayout.finishLoadMore(); + } + } + }, 1000); + } + }); + } + } + + private Random random = new Random(); + + private Collection loadData() { + int count = 3 + random.nextInt(10); + List list = new ArrayList<>(count); + for (int i = 0; i < count; i++) { + list.add(null); + } + return list; + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshUsingFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragment.java similarity index 50% rename from app/src/main/java/com/scwang/refreshlayout/fragment/RefreshUsingFragment.java rename to app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragment.java index 5ce9195b..408745ca 100644 --- a/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshUsingFragment.java +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragment.java @@ -1,54 +1,42 @@ -package com.scwang.refreshlayout.fragment; +package com.scwang.refreshlayout.fragment.example; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.DividerItemDecoration; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import com.scwang.refreshlayout.R; -import com.scwang.refreshlayout.activity.using.AssignCodeUsingActivity; -import com.scwang.refreshlayout.activity.using.AssignDefaultUsingActivity; -import com.scwang.refreshlayout.activity.using.AssignXmlUsingActivity; -import com.scwang.refreshlayout.activity.using.BasicUsingActivity; -import com.scwang.refreshlayout.activity.using.ListenerUsingActivity; -import com.scwang.refreshlayout.activity.using.NestLayoutUsingActivity; +import com.scwang.refreshlayout.activity.FragmentActivity; import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; import com.scwang.refreshlayout.adapter.SmartViewHolder; -import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.header.ClassicsHeader; -import java.lang.reflect.Constructor; import java.util.Arrays; import static android.R.layout.simple_list_item_2; import static android.support.v7.widget.DividerItemDecoration.VERTICAL; /** - * 使用示例 + * 使用示例-纯滚动模式 * A simple {@link Fragment} subclass. */ -public class RefreshUsingFragment extends Fragment implements AdapterView.OnItemClickListener { +public class PureScrollExampleFragment extends Fragment implements AdapterView.OnItemClickListener { - private enum Item { - Basic("基本的使用", BasicUsingActivity.class), - DefaultCreater("设置全局默认的Header和Footer", AssignDefaultUsingActivity.class), - XmlDefine("在XML中定义Header和Footer", AssignXmlUsingActivity.class), - CodeDefine("在代码中指定Header和Footer", AssignCodeUsingActivity.class), - Listener("多功能监听器", ListenerUsingActivity.class), -// OverScroll("越界回弹", OverScrollUsingActivity.class), - NestLayout("嵌套Layout作为内容", NestLayoutUsingActivity.class), + public enum Item { + Basic("基本的使用", PureScrollExampleFragment.class), + HeaderOnly("代码中单独指定Header", PureScrollExampleFragmentHeader.class), + FooterOnly("XML中单独指定Footer", PureScrollExampleFragmentFooter.class), ; public String name; public Class clazz; @@ -56,18 +44,25 @@ private enum Item { this.name = name; this.clazz = clazz; } - } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_refresh_using, container, false); + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_purescroll, container, false); } @Override - public void onViewCreated(View root, @Nullable Bundle savedInstanceState) { + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + View view = root.findViewById(R.id.recyclerView); if (view instanceof RecyclerView) { RecyclerView recyclerView = (RecyclerView) view; @@ -90,19 +85,8 @@ public void onItemClick(AdapterView parent, View view, int position, long id) Item item = Item.values()[position]; if (Activity.class.isAssignableFrom(item.clazz)) { startActivity(new Intent(getContext(), item.clazz)); - } else if (RefreshHeader.class.isAssignableFrom(item.clazz)) { - try { - Constructor constructor = item.clazz.getConstructor(Context.class); - RefreshHeader header = (RefreshHeader) constructor.newInstance(getContext()); - RefreshLayout layout = (RefreshLayout) getView().findViewById(R.id.refreshLayout); - layout.setRefreshHeader(header); - if (!(header instanceof ClassicsHeader)) { - layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white); - } - layout.autoRefresh(); - } catch (Exception e) { - e.printStackTrace(); - } + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); } } } diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragmentFooter.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragmentFooter.java new file mode 100644 index 00000000..8bcd7528 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragmentFooter.java @@ -0,0 +1,88 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.fragment.example.PureScrollExampleFragment.Item; +import com.scwang.smartrefresh.layout.api.RefreshLayout; + +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * 使用示例-纯滚动模式 + * A simple {@link Fragment} subclass. + */ +public class PureScrollExampleFragmentFooter extends Fragment implements AdapterView.OnItemClickListener { + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_purescroll, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + toolbar.setTitle("Footer单独使用"); + + RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + refreshLayout.setEnablePureScrollMode(true); + refreshLayout.setEnableRefresh(false); + refreshLayout.setEnableLoadMore(true); +// refreshLayout.setRefreshFooter(new FalsifyFooter(getContext())); + + View view = root.findViewById(R.id.recyclerView); + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Item item = Item.values()[position]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragmentHeader.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragmentHeader.java new file mode 100644 index 00000000..a0b5a050 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/PureScrollExampleFragmentHeader.java @@ -0,0 +1,85 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.fragment.example.PureScrollExampleFragment.Item; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.header.FalsifyHeader; + +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * 使用示例-纯滚动模式 + * A simple {@link Fragment} subclass. + */ +public class PureScrollExampleFragmentHeader extends Fragment implements AdapterView.OnItemClickListener { + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_purescroll_header, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + refreshLayout.setRefreshHeader(new FalsifyHeader(getContext()));//也可以在 XML 中添加 FalsifyHeader + + View view = root.findViewById(R.id.recyclerView); + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Item item = Item.values()[position]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/SpecifyStyleExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/SpecifyStyleExampleFragment.java new file mode 100644 index 00000000..11a63239 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/SpecifyStyleExampleFragment.java @@ -0,0 +1,96 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.activity.example.AssignCodeExampleActivity; +import com.scwang.refreshlayout.activity.example.AssignDefaultExampleActivity; +import com.scwang.refreshlayout.activity.example.AssignXmlExampleActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; + +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * 使用示例-指定样式 + * A simple {@link Fragment} subclass. + */ +public class SpecifyStyleExampleFragment extends Fragment implements AdapterView.OnItemClickListener { + + public enum Item { + Global("全局指定", AssignDefaultExampleActivity.class), + Code("代码指定", AssignCodeExampleActivity.class), + Xml("XML指定", AssignXmlExampleActivity.class), + ; + public String name; + public Class clazz; + Item(String name, Class clazz) { + this.name = name; + this.clazz = clazz; + } + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.common_independence_recycler, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + toolbar.setTitle("指定样式"); + + View view = root.findViewById(R.id.recyclerView); + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.name); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Item item = Item.values()[position]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/StaggeredGridExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/StaggeredGridExampleFragment.java new file mode 100644 index 00000000..be68421a --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/StaggeredGridExampleFragment.java @@ -0,0 +1,80 @@ +package com.scwang.refreshlayout.fragment.example; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; + +import java.util.Arrays; +import java.util.Collection; + +/** + * A simple {@link Fragment} subclass. + */ +public class StaggeredGridExampleFragment extends Fragment { + + private BaseRecyclerAdapter mAdapter; + + public StaggeredGridExampleFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_example_staggered_grid, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState);//初始化列表和监听 + View recycler = view.findViewById(R.id.recyclerView); + if (recycler instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) recycler; + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(loadModels(), R.layout.item_example_snap_helper) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Integer model, int position) { + holder.image(R.id.imageView, model); + } + }); + } + + RefreshLayout refreshLayout = view.findViewById(R.id.refreshLayout); + refreshLayout.setOnRefreshLoadMoreListener(new OnRefreshLoadMoreListener() { + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(() -> { + mAdapter.refresh(loadModels()); + refreshLayout.finishRefresh(); + }, 2000); + } + + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(() -> { + mAdapter.loadMore(loadModels()); + refreshLayout.finishLoadMore(); + }, 2000); + } + }); + + } + + private Collection loadModels() { + return Arrays.asList(R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2, R.mipmap.image_weibo_home_1, R.mipmap.image_weibo_home_2); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/ThreeLevelExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/ThreeLevelExampleFragment.java new file mode 100644 index 00000000..a1939831 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/ThreeLevelExampleFragment.java @@ -0,0 +1,87 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; + +import java.util.Arrays; +import java.util.List; + +import static android.R.layout.simple_list_item_2; + +/** + * 三级刷新 + * A simple {@link Fragment} subclass. + */ +public class ThreeLevelExampleFragment extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_example_three_level, container, false); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + final Toolbar toolbar = view.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + RecyclerView recyclerView = view.findViewById(R.id.recyclerView); + if (recyclerView != null) { + recyclerView.setAdapter(new BaseRecyclerAdapter(initData(), simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text1, android.R.color.white); + holder.textColorId(android.R.id.text2, android.R.color.white); + } + }); + } + + RefreshLayout refreshLayout1 = view.findViewById(R.id.refreshLayout1); + if (refreshLayout1 != null) { + refreshLayout1.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishRefresh(1000); + } + }); + } + RefreshLayout refreshLayout2 = view.findViewById(R.id.refreshLayout2); + if (refreshLayout2 != null) { + refreshLayout2.getLayout().setEnabled(false); + refreshLayout2.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishRefresh(2000); + } + }); + } + } + + private List initData() { + return Arrays.asList(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/example/ViewPagerExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/example/ViewPagerExampleFragment.java new file mode 100644 index 00000000..2761b9fd --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/example/ViewPagerExampleFragment.java @@ -0,0 +1,189 @@ +package com.scwang.refreshlayout.fragment.example; + + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.support.design.widget.TabLayout; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.footer.ClassicsFooter; +import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; + +import java.util.Arrays; +import java.util.Collection; + +import static android.R.layout.simple_list_item_2; +import static com.scwang.refreshlayout.R.id.refreshLayout; + +/** + * 使用示例-ViewPager页面 + * A simple {@link Fragment} subclass. + */ +public class ViewPagerExampleFragment extends Fragment implements OnRefreshListener, OnRefreshLoadMoreListener { + + + public enum Item { + NestedInner(R.string.item_example_pager_left, SmartFragment.class), + NestedOuter(R.string.item_example_pager_right, SmartFragment.class), + ; + public int nameId; + public Class clazz; + Item(@StringRes int nameId, Class clazz) { + this.nameId = nameId; + this.clazz = clazz; + } + } + + private TabLayout mTabLayout; + private ViewPager mViewPager; + private RefreshLayout mRefreshLayout; + private SmartPagerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_example_viewpager, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + mRefreshLayout = root.findViewById(refreshLayout); + mRefreshLayout.setOnRefreshLoadMoreListener(this); + mRefreshLayout.setRefreshHeader(new ClassicsHeader(getContext())); + mRefreshLayout.setRefreshFooter(new ClassicsFooter(getContext())); + + mViewPager = root.findViewById(R.id.viewPager); + mTabLayout = root.findViewById(R.id.tableLayout); + + mViewPager.setAdapter(mAdapter = new SmartPagerAdapter(Item.values())); + mTabLayout.setupWithViewPager(mViewPager, true); + } + + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + mAdapter.fragments[mViewPager.getCurrentItem()].onRefresh(refreshLayout); + } + + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + mAdapter.fragments[mViewPager.getCurrentItem()].onLoadMore(refreshLayout); + } + + + private class SmartPagerAdapter extends FragmentStatePagerAdapter { + + private final Item[] items; + private final SmartFragment[] fragments; + + SmartPagerAdapter(Item... items) { + super(getChildFragmentManager()); + this.items = items; + this.fragments = new SmartFragment[items.length]; + } + + @Override + public int getCount() { + return items.length; + } + + @Override + public CharSequence getPageTitle(int position) { + return getString(items[position].nameId); + } + + @Override + public Fragment getItem(int position) { + if (fragments[position] == null) { + fragments[position] = new SmartFragment(); + } + return fragments[position]; + } + } + + public static class SmartFragment extends Fragment { + + private RecyclerView mRecyclerView; + private BaseRecyclerAdapter mAdapter; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return new RecyclerView(inflater.getContext()); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + mRecyclerView = (RecyclerView) view; + + mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); + mRecyclerView.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL)); + mRecyclerView.setAdapter(mAdapter = new BaseRecyclerAdapter(initData(), simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + + private Collection initData() { + return Arrays.asList(null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null); + } + + public void onRefresh(final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.refresh(initData()); + refreshLayout.finishRefresh(); + refreshLayout.resetNoMoreData();//setNoMoreData(false); + } + }, 2000); + } + + public void onLoadMore(final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + mAdapter.loadMore(initData()); + if (mAdapter.getItemCount() > 60) { + Toast.makeText(getContext(), "数据全部加载完毕", Toast.LENGTH_SHORT).show(); + refreshLayout.finishLoadMoreWithNoMoreData();//将不会再次触发加载更多事件 + } else { + refreshLayout.finishLoadMore(); + } + } + }, 2000); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshExampleFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshExampleFragment.java new file mode 100644 index 00000000..66b740ca --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshExampleFragment.java @@ -0,0 +1,109 @@ +package com.scwang.refreshlayout.fragment.index; + + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.activity.example.BasicExampleActivity; +import com.scwang.refreshlayout.activity.example.CustomExampleActivity; +import com.scwang.refreshlayout.activity.example.I18nExampleActivity; +import com.scwang.refreshlayout.activity.example.ListenerExampleActivity; +import com.scwang.refreshlayout.activity.example.NestedLayoutExampleActivity; +import com.scwang.refreshlayout.activity.example.SnapHelperExampleActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.fragment.example.*; +import com.scwang.refreshlayout.util.StatusBarUtil; + +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; + +/** + * 使用示例 + * A simple {@link Fragment} subclass. + */ +public class RefreshExampleFragment extends Fragment implements AdapterView.OnItemClickListener { + + private enum Item { + Basic(R.string.index_example_basic, BasicExampleActivity.class), + NoMoreData(R.string.index_example_style, NoMoreDataExampleFragment.class), + SpecifyStyle(R.string.index_example_style, SpecifyStyleExampleFragment.class), + EmptyLayout(R.string.index_example_empty, EmptyLayoutExampleFragment.class), + NestedLayout(R.string.index_example_layout, NestedLayoutExampleActivity.class), + NestedScroll(R.string.index_example_nested, NestedScrollExampleFragment.class), + PureScroll(R.string.index_example_scroll, PureScrollExampleFragment.class), + Listener(R.string.index_example_listener, ListenerExampleActivity.class), + Custom(R.string.index_example_custom, CustomExampleActivity.class), + I18N(R.string.index_example_custom, I18nExampleActivity.class), + SnapHelper(R.string.index_example_snap_helper, SnapHelperExampleActivity.class), + ViewPager(R.string.index_example_pager, ViewPagerExampleFragment.class), + BottomSheet(R.string.index_example_bottom_sheet,BottomSheetExampleFragment.class), + FlexBoxLayout(R.string.index_example_flex_box, FlexBoxLayoutManagerFragment.class), + Horizontal(R.string.index_example_horizontal, HorizontalExampleFragment.class), + DisallowIntercept(R.string.index_example_disallow_intercept, DisallowInterceptExampleFragment.class), + StaggeredGrid(R.string.index_example_disallow_intercept, StaggeredGridExampleFragment.class), +// ThreeLevel(R.string.index_example_level, ThreeLevelExampleFragment.class), + ; + public int nameId; + public Class clazz; + + Item(@StringRes int nameId, Class clazz) { + this.nameId = nameId; + this.clazz = clazz; + } + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_refresh_example, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + StatusBarUtil.setPaddingSmart(getContext(), root.findViewById(R.id.toolbar)); + + View view = root.findViewById(R.id.recyclerView); + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, getString(model.nameId)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Item item = Item.values()[position]; + if (Activity.class.isAssignableFrom(item.clazz)) { + startActivity(new Intent(getContext(), item.clazz)); + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); + } + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshPractiveFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshPracticeFragment.java similarity index 57% rename from app/src/main/java/com/scwang/refreshlayout/fragment/RefreshPractiveFragment.java rename to app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshPracticeFragment.java index ac936d03..b76d3dd9 100644 --- a/app/src/main/java/com/scwang/refreshlayout/fragment/RefreshPractiveFragment.java +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshPracticeFragment.java @@ -1,11 +1,12 @@ -package com.scwang.refreshlayout.fragment; +package com.scwang.refreshlayout.fragment.index; import android.app.Activity; -import android.content.Context; import android.content.Intent; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.StringRes; import android.support.v4.app.Fragment; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.DividerItemDecoration; @@ -17,18 +18,20 @@ import android.widget.AdapterView; import com.scwang.refreshlayout.R; -import com.scwang.refreshlayout.activity.practice.FeedlistPracticeActivity; +import com.scwang.refreshlayout.activity.FragmentActivity; +import com.scwang.refreshlayout.activity.practice.BannerPracticeActivity; +import com.scwang.refreshlayout.activity.practice.FeedListPracticeActivity; import com.scwang.refreshlayout.activity.practice.ProfilePracticeActivity; +import com.scwang.refreshlayout.activity.practice.QQBrowserPracticeActivity; import com.scwang.refreshlayout.activity.practice.RepastPracticeActivity; -import com.scwang.refreshlayout.activity.practice.WebviewPracticeActivity; +import com.scwang.refreshlayout.activity.practice.WebViewPracticeActivity; import com.scwang.refreshlayout.activity.practice.WeiboPracticeActivity; import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; import com.scwang.refreshlayout.adapter.SmartViewHolder; -import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.header.ClassicsHeader; +import com.scwang.refreshlayout.fragment.practice.InstantPracticeFragment; +import com.scwang.refreshlayout.fragment.practice.SecondFloorPracticeFragment; +import com.scwang.refreshlayout.util.StatusBarUtil; -import java.lang.reflect.Constructor; import java.util.Arrays; import static android.R.layout.simple_list_item_2; @@ -38,18 +41,24 @@ * 实战演示 * A simple {@link Fragment} subclass. */ -public class RefreshPractiveFragment extends Fragment implements AdapterView.OnItemClickListener { +public class RefreshPracticeFragment extends Fragment implements AdapterView.OnItemClickListener { private enum Item { - Repast("餐饮美食-简单自定义Header-外边距magin", RepastPracticeActivity.class), - Profile("个人中心-OverScroll", ProfilePracticeActivity.class), - Webview("网页引用-WebView", WebviewPracticeActivity.class), - FeedList("微博列表-智能识别", FeedlistPracticeActivity.class), - Weibo("微博主页-CoordinatorLayout", WeiboPracticeActivity.class), + Repast(R.string.index_practice_repast, RepastPracticeActivity.class), + Profile(R.string.index_practice_profile, ProfilePracticeActivity.class), + WebView(R.string.index_practice_web_view, WebViewPracticeActivity.class), + FeedList(R.string.index_practice_feed_list, FeedListPracticeActivity.class), + Weibo(R.string.index_practice_weibo, WeiboPracticeActivity.class), + Banner(R.string.index_practice_banner, BannerPracticeActivity.class), + QQBrowser(R.string.index_practice_qq_browser, QQBrowserPracticeActivity.class), +// TwoLevel("二级刷新", SecondFloorPracticeFragment.class), + SecondFloor(R.string.index_practice_second_floor, SecondFloorPracticeFragment.class), + Instant(R.string.index_practice_instant, InstantPracticeFragment.class) ; - public String name; + @StringRes + public int name; public Class clazz; - Item(String name, Class clazz) { + Item(@StringRes int name, Class clazz) { this.name = name; this.clazz = clazz; } @@ -57,13 +66,14 @@ private enum Item { } @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_refresh_practive, container, false); } @Override - public void onViewCreated(View root, @Nullable Bundle savedInstanceState) { + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { super.onViewCreated(root, savedInstanceState); + StatusBarUtil.setPaddingSmart(getContext(), root.findViewById(R.id.toolbar)); View view = root.findViewById(R.id.recyclerView); if (view instanceof RecyclerView) { @@ -80,7 +90,6 @@ protected void onBindViewHolder(SmartViewHolder holder, Item model, int position } }); } - } @Override @@ -88,19 +97,8 @@ public void onItemClick(AdapterView parent, View view, int position, long id) Item item = Item.values()[position]; if (Activity.class.isAssignableFrom(item.clazz)) { startActivity(new Intent(getContext(), item.clazz)); - } else if (RefreshHeader.class.isAssignableFrom(item.clazz)) { - try { - Constructor constructor = item.clazz.getConstructor(Context.class); - RefreshHeader header = (RefreshHeader) constructor.newInstance(getContext()); - RefreshLayout layout = (RefreshLayout) getView().findViewById(R.id.refreshLayout); - layout.setRefreshHeader(header); - if (!(header instanceof ClassicsHeader)) { - layout.setPrimaryColorsId(R.color.colorPrimary, android.R.color.white); - } - layout.autoRefresh(); - } catch (Exception e) { - e.printStackTrace(); - } + } else if (Fragment.class.isAssignableFrom(item.clazz)) { + FragmentActivity.start(this, item.clazz); } } } diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshStylesFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshStylesFragment.java new file mode 100644 index 00000000..ec6b39e3 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/index/RefreshStylesFragment.java @@ -0,0 +1,191 @@ +package com.scwang.refreshlayout.fragment.index; + +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.annotation.StringRes; +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.DividerItemDecoration; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.activity.style.BezierCircleStyleActivity; +import com.scwang.refreshlayout.activity.style.BezierRadarStyleActivity; +import com.scwang.refreshlayout.activity.style.ClassicsStyleActivity; +import com.scwang.refreshlayout.activity.style.DeliveryStyleActivity; +import com.scwang.refreshlayout.activity.style.DropBoxStyleActivity; +import com.scwang.refreshlayout.activity.style.FlyRefreshStyleActivity; +import com.scwang.refreshlayout.activity.style.FunGameBattleCityStyleActivity; +import com.scwang.refreshlayout.activity.style.FunGameHitBlockStyleActivity; +import com.scwang.refreshlayout.activity.style.MaterialStyleActivity; +import com.scwang.refreshlayout.activity.style.PhoenixStyleActivity; +import com.scwang.refreshlayout.activity.style.StoreHouseStyleActivity; +import com.scwang.refreshlayout.activity.style.TaurusStyleActivity; +import com.scwang.refreshlayout.activity.style.WaterDropStyleActivity; +import com.scwang.refreshlayout.activity.style.WaveSwipeStyleActivity; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.util.StatusBarUtil; +import com.scwang.smart.refresh.footer.BallPulseFooter; +import com.scwang.smart.refresh.header.BezierCircleHeader; +import com.scwang.smart.refresh.header.ClassicsHeader; +import com.scwang.smart.refresh.header.DeliveryHeader; +import com.scwang.smart.refresh.header.DropBoxHeader; +import com.scwang.smart.refresh.header.FunGameHitBlockHeader; +import com.scwang.smart.refresh.header.PhoenixHeader; +import com.scwang.smart.refresh.header.TaurusHeader; +import com.scwang.smart.refresh.layout.api.RefreshFooter; +import com.scwang.smart.refresh.layout.api.RefreshHeader; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.constant.RefreshState; +import com.scwang.smart.refresh.layout.simple.SimpleMultiListener; +import com.scwang.smart.refresh.layout.util.SmartUtil; +import com.scwang.smart.refresh.layout.wrapper.RefreshFooterWrapper; +import com.scwang.smart.refresh.layout.wrapper.RefreshHeaderWrapper; + +import java.util.Arrays; + +import static android.R.layout.simple_list_item_2; +import static android.support.v7.widget.DividerItemDecoration.VERTICAL; +import static com.scwang.refreshlayout.R.id.recyclerView; + +/** + * 风格展示 + * A simple {@link Fragment} subclass. + */ +public class RefreshStylesFragment extends Fragment implements AdapterView.OnItemClickListener { + + private enum Item { + Hidden(R.string.title_activity_style_delivery,DeliveryStyleActivity.class), + Delivery(R.string.title_activity_style_delivery,DeliveryStyleActivity.class), + DropBox(R.string.title_activity_style_drop_box, DropBoxStyleActivity.class), + WaveSwipe(R.string.title_activity_style_wave_swipe, WaveSwipeStyleActivity.class), + FlyRefresh(R.string.title_activity_style_fly_refresh, FlyRefreshStyleActivity.class), + WaterDrop(R.string.title_activity_style_water_drop, WaterDropStyleActivity.class), + Material(R.string.title_activity_style_material, MaterialStyleActivity.class), + Phoenix(R.string.title_activity_style_phoenix, PhoenixStyleActivity.class), + Taurus(R.string.title_activity_style_taurus, TaurusStyleActivity.class), + Bezier(R.string.title_activity_style_bezier, BezierRadarStyleActivity.class), + Circle(R.string.title_activity_style_circle, BezierCircleStyleActivity.class), + FunGameHitBlock(R.string.title_activity_style_hit_block, FunGameHitBlockStyleActivity.class), + FunGameBattleCity(R.string.title_activity_style_battle_city, FunGameBattleCityStyleActivity.class), + StoreHouse(R.string.title_activity_style_storehouse, StoreHouseStyleActivity.class), + Classics(R.string.title_activity_style_classics, ClassicsStyleActivity.class), + ; + public int nameId; + public Class clazz; + Item(@StringRes int nameId, Class clazz) { + this.nameId = nameId; + this.clazz = clazz; + } + + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_refresh_styles, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + StatusBarUtil.setPaddingSmart(getContext(), root.findViewById(R.id.toolbar)); + + View view = root.findViewById(recyclerView); + if (view instanceof RecyclerView) { + RecyclerView recyclerView = (RecyclerView) view; + recyclerView.setItemAnimator(new DefaultItemAnimator()); + recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + recyclerView.addItemDecoration(new DividerItemDecoration(getContext(), VERTICAL)); + recyclerView.setAdapter(new BaseRecyclerAdapter(Arrays.asList(Item.values()), simple_list_item_2,this) { + @NonNull + @Override + public SmartViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + SmartViewHolder holder = super.onCreateViewHolder(parent, viewType); + if (viewType == 0) { + holder.itemView.setVisibility(View.GONE); + holder.itemView.setLayoutParams(new RecyclerView.LayoutParams(0,0)); + } + return holder; + } + + @Override + public int getViewTypeCount() { + return 2; + } + + @Override + public int getItemViewType(int position) { + return position == 0 ? 0 : 1; + } + + @Override + protected void onBindViewHolder(SmartViewHolder holder, Item model, int position) { + holder.text(android.R.id.text1, model.name()); + holder.text(android.R.id.text2, model.nameId); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + + + RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + if (refreshLayout != null) { + refreshLayout.setOnMultiListener(new SimpleMultiListener() { + @Override + public void onRefresh(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.finishRefresh(3000); + } + @Override + public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); + } + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + if (newState == RefreshState.None) { + if (oldState == RefreshState.LoadFinish) { + RefreshFooter refreshFooter = refreshLayout.getRefreshFooter(); + if (refreshFooter instanceof RefreshFooterWrapper) { + View footerView = refreshFooter.getView(); + if (footerView instanceof TaurusHeader) { + refreshLayout.setRefreshFooter(new RefreshFooterWrapper(new DropBoxHeader(getContext()))); + } else if (footerView instanceof DropBoxHeader) { + refreshLayout.setRefreshFooter(new RefreshFooterWrapper(new DeliveryHeader(getContext()))); + } else if (footerView instanceof DeliveryHeader) { + refreshLayout.setRefreshFooter(new RefreshFooterWrapper(new BezierCircleHeader(getContext()))); + } else { + refreshLayout.setRefreshFooter(new BallPulseFooter(getContext())); + } + } + } else if (oldState == RefreshState.RefreshFinish) { + RefreshHeader refreshHeader = refreshLayout.getRefreshHeader(); + if (refreshHeader instanceof RefreshHeaderWrapper) { + refreshLayout.setRefreshHeader(new PhoenixHeader(getContext()), ViewGroup.LayoutParams.MATCH_PARENT, SmartUtil.dp2px(100)); + } else if (refreshHeader instanceof PhoenixHeader) { + refreshLayout.setRefreshHeader(new DropBoxHeader(getContext()), ViewGroup.LayoutParams.MATCH_PARENT, SmartUtil.dp2px(150)); + } else if (refreshHeader instanceof DropBoxHeader) { + refreshLayout.setRefreshHeader(new FunGameHitBlockHeader(getContext())); + } else if (refreshHeader instanceof FunGameHitBlockHeader) { + refreshLayout.setRefreshHeader(new ClassicsHeader(getContext())); + } else { + refreshLayout.setRefreshHeader(new RefreshHeaderWrapper(new BallPulseFooter(getContext()))); + } + } + } + } + }); + } + } + + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + startActivity(new Intent(getContext(), Item.values()[position].clazz)); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/practice/InstantPracticeFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/practice/InstantPracticeFragment.java new file mode 100644 index 00000000..f0b56b5f --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/practice/InstantPracticeFragment.java @@ -0,0 +1,247 @@ +package com.scwang.refreshlayout.fragment.practice; + + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.util.DynamicTimeFormat; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.footer.ClassicsFooter; +import com.scwang.smartrefresh.layout.impl.ScrollBoundaryDeciderAdapter; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; + +/** + * 即时聊天页面 + * A simple {@link Fragment} subclass. + */ +public class InstantPracticeFragment extends Fragment { + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_practice_instant, container, false); + } + + @Override + public void onViewCreated(@NonNull View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + + final MessageAdapter adapter = new MessageAdapter(initData()); + + ClassicsFooter footer = root.findViewById(R.id.footer); + View arrow = footer.findViewById(ClassicsFooter.ID_IMAGE_ARROW); + arrow.setScaleY(-1);//必须设置 + + RecyclerView listView = root.findViewById(R.id.listView); + listView.setAdapter(adapter); + listView.setScaleY(-1);//必须设置 + + final RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + refreshLayout.setEnableRefresh(false);//必须关闭 + refreshLayout.setEnableAutoLoadMore(true);//必须关闭 + refreshLayout.setEnableNestedScroll(false);//必须关闭 + refreshLayout.setEnableScrollContentWhenLoaded(true);//必须关闭 + refreshLayout.getLayout().setScaleY(-1);//必须设置 + refreshLayout.setScrollBoundaryDecider(new ScrollBoundaryDeciderAdapter() { + @Override + public boolean canLoadMore(View content) { + return super.canRefresh(content);//必须替换 + } + }); + + //监听加载,而不是监听 刷新 + refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull final RefreshLayout refreshLayout) { + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + adapter.insert(initData()); + refreshLayout.finishLoadMore(); + } + }, 2000); + } + }); + + /* + * 触发测试 + */ + toolbar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + refreshLayout.autoLoadMore(); + } + }); + } + + private Collection initData() { + final User user = new User(){{ + avatarId = R.mipmap.image_avatar_1; + }}; + final User mine = new User(){{ + isMe = true; + avatarId = R.mipmap.image_avatar_4; + }}; + return Arrays.asList( + new Message(){{ + this.Time = new Date(System.currentTimeMillis() - 3600 * 1000 * 3); + this.Message = "对方测回了一条消息"; + }}, + new Message(){{ + this.User = user; + this.Time = new Date(System.currentTimeMillis() - 3600 * 1000 * 3 + 5000); + this.Message = "刚刚发错了,不好意思,下面这个才是"; + }}, + new Message(){{ + this.User = user; + this.Time = new Date(System.currentTimeMillis() - 3600 * 1000 * 3 + 10000); + this.Image = R.mipmap.image_avatar_3; + }}, + new Message(){{ + this.User = mine; + this.Time = new Date(System.currentTimeMillis() - 3600 * 1000 * 3 + 15000); + this.Message = "好的,收到了"; + }}, + new Message(){{ + this.User = mine; + this.Time = new Date(System.currentTimeMillis() - 3600 * 1000 * 3 + 15000 * 50); + this.Message = "一会你来我办公室一趟"; + }}, + new Message(){{ + this.User = user; + this.Time = new Date(System.currentTimeMillis() - 3600 * 1000 * 3 + 15000 * 50 + 5000); + this.Message = "好的,马上到。"; + }} + ); + } + + static class User { + int avatarId; + boolean isMe; + } + + static class Message { + Date Time; + User User; + int Image; + String Message; + + } + + static class MessageAdapter extends BaseRecyclerAdapter { + + DynamicTimeFormat format = new DynamicTimeFormat(); + + MessageAdapter(Collection collection) { + super(collection, R.layout.item_practice_instant); + } + + @Override + protected void onBindViewHolder(SmartViewHolder holder, Message message, int index) { + onItemBindingTime(holder, message, index); + if (message.User == null) { + onItemBindingSystem(holder, message); + } else if (message.User.isMe) { + onItemBindingMine(holder, message); + } else { + onItemBindingOther(holder, message); + } + } + + /** + * 展示对方的消息 + */ + private void onItemBindingOther(SmartViewHolder holder, Message message) { + holder.gone(R.id.chatting_right); + holder.gone(R.id.chatting_tv_sysmsg); + holder.visible(R.id.chatting_left); + + holder.image(R.id.chatting_liv_avatar, message.User.avatarId); + + if (message.Image == 0) { + holder.gone(R.id.chatting_liv_img); + holder.text(R.id.chatting_ltv_txt, message.Message).visible(R.id.chatting_ltv_txt); + } else { + holder.gone(R.id.chatting_ltv_txt); + holder.image(R.id.chatting_liv_img, message.Image).visible(R.id.chatting_liv_img); + } + } + + + /** + * 展示自己的消息 + */ + private void onItemBindingMine(SmartViewHolder holder, Message message) { + holder.gone(R.id.chatting_left); + holder.gone(R.id.chatting_tv_sysmsg); + holder.visible(R.id.chatting_right); + + holder.image(R.id.chatting_riv_avatar, message.User.avatarId); + + if (message.Image == 0) { + holder.gone(R.id.chatting_riv_img); + holder.text(R.id.chatting_rtv_txt, message.Message).visible(R.id.chatting_rtv_txt); + } else { + holder.gone(R.id.chatting_rtv_txt); + holder.image(R.id.chatting_riv_img, message.Image).visible(R.id.chatting_riv_img); + } + } + + /** + * 展示系统消息 + */ + private void onItemBindingSystem(SmartViewHolder holder, Message message) { + holder.gone(R.id.chatting_left); + holder.gone(R.id.chatting_right); + holder.gone(R.id.chatting_tv_sendtime); + holder.visible(R.id.chatting_tv_sysmsg).text(R.id.chatting_tv_sysmsg, message.Message); + } + + + /** + * 展示时间 + */ + private void onItemBindingTime(SmartViewHolder holder, Message model, int index) { + Message prev = null; + if (index > 0) { + prev = get(index - 1); + if (prev.User == null) { + if (index > 1) { + prev = get(index - 2); + } else { + prev = null; + } + } + } + if (prev != null && (model.Time.getTime() - prev.Time.getTime() < 5 * 60 * 1000)) { + holder.gone(R.id.chatting_tv_sendtime); + } else { + holder.visible(R.id.chatting_tv_sendtime); + holder.text(R.id.chatting_tv_sendtime, format.format(model.Time)); + } + } + + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/practice/SecondFloorPracticeFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/practice/SecondFloorPracticeFragment.java new file mode 100644 index 00000000..84bcf741 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/practice/SecondFloorPracticeFragment.java @@ -0,0 +1,134 @@ +package com.scwang.refreshlayout.fragment.practice; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.adapter.BaseRecyclerAdapter; +import com.scwang.refreshlayout.adapter.SmartViewHolder; +import com.scwang.refreshlayout.util.StatusBarUtil; +import com.scwang.smartrefresh.layout.api.OnTwoLevelListener; +import com.scwang.smartrefresh.layout.api.RefreshHeader; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.constant.RefreshState; +import com.scwang.smartrefresh.layout.header.TwoLevelHeader; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; +import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; + +import java.util.Arrays; +import java.util.List; + +import static android.R.layout.simple_list_item_2; + +/** + * 淘宝二楼 + * Created by scwang on 2017/12/4. + */ +public class SecondFloorPracticeFragment extends Fragment { + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_practice_second_floor, container, false); + } + + @Override + public void onViewCreated(@NonNull final View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final View floor = root.findViewById(R.id.second_floor); + final Toolbar toolbar = root.findViewById(R.id.toolbar); + final TwoLevelHeader header = root.findViewById(R.id.header); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + final RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + refreshLayout.setOnMultiPurposeListener(new SimpleMultiPurposeListener() { + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + refreshLayout.finishLoadMore(2000); + } + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + Toast.makeText(getContext(),"触发刷新事件",Toast.LENGTH_SHORT).show(); + refreshLayout.finishRefresh(2000); + } + @Override + public void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) { + toolbar.setAlpha(1 - Math.min(percent, 1)); + floor.setTranslationY(Math.min(offset - floor.getHeight() + toolbar.getHeight(), refreshLayout.getLayout().getHeight() - floor.getHeight())); + } + @Override + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + if (oldState == RefreshState.TwoLevel) { + root.findViewById(R.id.second_floor_content).animate().alpha(0).setDuration(1000); + } + } + }); + + /* + * 主动打开二楼 + */ + toolbar.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + header.openTwoLevel(true); + } + }); + + header.setOnTwoLevelListener(new OnTwoLevelListener() { + @Override + public boolean onTwoLevel(@NonNull RefreshLayout refreshLayout) { + Toast.makeText(getContext(),"触发二楼事件",Toast.LENGTH_SHORT).show(); + root.findViewById(R.id.second_floor_content).animate().alpha(1).setDuration(2000); +// refreshLayout.getLayout().postDelayed(new Runnable() { +// @Override +// public void run() { +// header.finishTwoLevel(); +// root.findViewById(R.id.second_floor_content).animate().alpha(0).setDuration(1000); +// } +// },5000); + return true;//true 将会展开二楼状态 false 关闭刷新 + } + }); + + refreshLayout.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + Toast.makeText(getContext(),"触发刷新事件",Toast.LENGTH_SHORT).show(); + refreshLayout.finishRefresh(2000); + } + }); + + RecyclerView recyclerView = root.findViewById(R.id.recyclerView); + if (recyclerView != null) { + recyclerView.setNestedScrollingEnabled(false); + List voids = Arrays.asList(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); + recyclerView.setAdapter(new BaseRecyclerAdapter(voids, simple_list_item_2) { + @Override + protected void onBindViewHolder(SmartViewHolder holder, Void model, int position) { + holder.text(android.R.id.text1, getString(R.string.item_example_number_title, position)); + holder.text(android.R.id.text2, getString(R.string.item_example_number_abstract, position)); + holder.textColorId(android.R.id.text2, R.color.colorTextAssistant); + } + }); + } + + //状态栏透明和间距处理 + StatusBarUtil.immersive(getActivity()); + StatusBarUtil.setMargin(getActivity(), root.findViewById(R.id.classics)); + StatusBarUtil.setPaddingSmart(getActivity(), root.findViewById(R.id.toolbar)); + StatusBarUtil.setPaddingSmart(getActivity(), root.findViewById(R.id.contentPanel)); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/fragment/practice/TwoLevelPracticeFragment.java b/app/src/main/java/com/scwang/refreshlayout/fragment/practice/TwoLevelPracticeFragment.java new file mode 100644 index 00000000..cfb90f0e --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/fragment/practice/TwoLevelPracticeFragment.java @@ -0,0 +1,72 @@ +package com.scwang.refreshlayout.fragment.practice; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.v4.app.Fragment; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +import com.scwang.refreshlayout.R; +import com.scwang.refreshlayout.util.StatusBarUtil; +import com.scwang.smartrefresh.layout.api.OnTwoLevelListener; +import com.scwang.smartrefresh.layout.api.RefreshLayout; +import com.scwang.smartrefresh.layout.header.TwoLevelHeader; +import com.scwang.smartrefresh.layout.listener.OnRefreshListener; + +/** + * 二级刷新 + * Created by scwang on 2018/1/7. + */ +public class TwoLevelPracticeFragment extends Fragment { + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.fragment_practice_twolevel, container, false); + } + + @Override + public void onViewCreated(@NonNull final View root, @Nullable Bundle savedInstanceState) { + super.onViewCreated(root, savedInstanceState); + + final Toolbar toolbar = root.findViewById(R.id.toolbar); + final TwoLevelHeader header = root.findViewById(R.id.header); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + getActivity().finish(); + } + }); + + final RefreshLayout refreshLayout = root.findViewById(R.id.refreshLayout); + + header.setOnTwoLevelListener(new OnTwoLevelListener() { + @Override + public boolean onTwoLevel(@NonNull RefreshLayout refreshLayout) { + Toast.makeText(getContext(),"触发二楼事件",Toast.LENGTH_SHORT).show(); + refreshLayout.getLayout().postDelayed(new Runnable() { + @Override + public void run() { + header.finishTwoLevel(); + } + },5000); + return true;//true 将会展开二楼状态 false 关闭刷新 + } + }); + + refreshLayout.setOnRefreshListener(new OnRefreshListener() { + @Override + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + Toast.makeText(getContext(),"触发刷新事件",Toast.LENGTH_SHORT).show(); + refreshLayout.finishRefresh(2000); + } + }); + + //状态栏透明和间距处理 + StatusBarUtil.immersive(getActivity()); + StatusBarUtil.setPaddingSmart(getActivity(), root.findViewById(R.id.toolbar)); + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/util/DynamicTimeFormat.java b/app/src/main/java/com/scwang/refreshlayout/util/DynamicTimeFormat.java index 662c02b3..e4c50423 100644 --- a/app/src/main/java/com/scwang/refreshlayout/util/DynamicTimeFormat.java +++ b/app/src/main/java/com/scwang/refreshlayout/util/DynamicTimeFormat.java @@ -10,9 +10,8 @@ /** * 动态时间格式化 - * Created by SCWANG on 2017/6/17. + * Created by scwang on 2017/6/17. */ - public class DynamicTimeFormat extends SimpleDateFormat { private static Locale locale = Locale.CHINA; diff --git a/app/src/main/java/com/scwang/refreshlayout/util/StatusBarUtil.java b/app/src/main/java/com/scwang/refreshlayout/util/StatusBarUtil.java index 4a9f8ea8..b3ccf930 100644 --- a/app/src/main/java/com/scwang/refreshlayout/util/StatusBarUtil.java +++ b/app/src/main/java/com/scwang/refreshlayout/util/StatusBarUtil.java @@ -1,11 +1,11 @@ package com.scwang.refreshlayout.util; -import android.support.annotation.RequiresApi; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.os.Build; import android.support.annotation.FloatRange; +import android.support.annotation.RequiresApi; import android.util.Log; import android.util.TypedValue; import android.view.View; @@ -19,14 +19,14 @@ /** * 状态栏透明 - * Created by SCWANG on 2016/10/26. + * Created by scwang on 2016/10/26. */ - @SuppressWarnings("unused") public class StatusBarUtil { public static int DEFAULT_COLOR = 0; public static float DEFAULT_ALPHA = 0;//Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? 0.2f : 0.3f; + public static final int MIN_API = 19; // public static void immersive(Activity activity) { @@ -62,13 +62,22 @@ public static void immersive(Window window, int color, @FloatRange(from = 0.0, t } else if (Build.VERSION.SDK_INT >= 19) { window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); setTranslucentView((ViewGroup) window.getDecorView(), color, alpha); - } else if (Build.VERSION.SDK_INT >= 16) { + } else if (Build.VERSION.SDK_INT >= MIN_API && Build.VERSION.SDK_INT > 16) { int systemUiVisibility = window.getDecorView().getSystemUiVisibility(); systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE; window.getDecorView().setSystemUiVisibility(systemUiVisibility); } } + + public static void color(Activity activity, int color) { + if (Build.VERSION.SDK_INT >= 21) { + Window window = activity.getWindow(); + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.setStatusBarColor(color); + } + } // // @@ -82,6 +91,17 @@ public static void darkMode(Activity activity, boolean dark) { } } + public static void darkModeCancel(Activity activity) { + Window window = activity.getWindow(); + if (isFlyme4Later()) { + darkModeForFlyme4(window, false); + } else if (isMIUI6Later()) { + darkModeForMIUI6(window, false); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + darkModeForM(window, false); + } + } + /** 设置状态栏darkMode,字体颜色及icon变黑(目前支持MIUI6以上,Flyme4以上,Android M以上) */ public static void darkMode(Activity activity) { darkMode(activity.getWindow(), DEFAULT_COLOR, DEFAULT_ALPHA); @@ -91,6 +111,17 @@ public static void darkMode(Activity activity, int color, @FloatRange(from = 0.0 darkMode(activity.getWindow(), color, alpha); } + public static void darkOnly(Activity activity) { + Window window = activity.getWindow(); + if (isFlyme4Later()) { + darkModeForFlyme4(window, true); + } else if (isMIUI6Later()) { + darkModeForMIUI6(window, true); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + darkModeForM(window, true); + } + } + /** 设置状态栏darkMode,字体颜色及icon变黑(目前支持MIUI6以上,Flyme4以上,Android M以上) */ public static void darkMode(Window window, int color, @FloatRange(from = 0.0, to = 1.0) float alpha) { if (isFlyme4Later()) { @@ -105,6 +136,8 @@ public static void darkMode(Window window, int color, @FloatRange(from = 0.0, to } else if (Build.VERSION.SDK_INT >= 19) { window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); setTranslucentView((ViewGroup) window.getDecorView(), color, alpha); + } else { + immersive(window, color, alpha); } // if (Build.VERSION.SDK_INT >= 21) { // window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); @@ -171,7 +204,10 @@ public static boolean darkModeForFlyme4(Window window, boolean dark) { * 设置MIUI6+的状态栏是否为darkMode,darkMode时候字体颜色及icon变黑 * http://dev.xiaomi.com/doc/p=4769/ */ - public static boolean darkModeForMIUI6(Window window, boolean darkmode) { + public static boolean darkModeForMIUI6(Window window, boolean dark) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + darkModeForM(window, dark); + } Class clazz = window.getClass(); try { int darkModeFlag = 0; @@ -179,9 +215,9 @@ public static boolean darkModeForMIUI6(Window window, boolean darkmode) { Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); darkModeFlag = field.getInt(layoutParams); Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); - extraFlagField.invoke(window, darkmode ? darkModeFlag : 0, darkModeFlag); + extraFlagField.invoke(window, dark ? darkModeFlag : 0, darkModeFlag); return true; - } catch (Exception e) { + } catch (Throwable e) { e.printStackTrace(); return false; } @@ -203,7 +239,7 @@ public static boolean isMIUI6Later() { val = val.replaceAll("[vV]", ""); int version = Integer.parseInt(val); return version >= 6; - } catch (Exception e) { + } catch (Throwable e) { return false; } } @@ -212,14 +248,14 @@ public static boolean isMIUI6Later() { /** 增加View的paddingTop,增加的值为状态栏高度 */ public static void setPadding(Context context, View view) { - if (Build.VERSION.SDK_INT >= 16) { + if (Build.VERSION.SDK_INT >= MIN_API) { view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context), view.getPaddingRight(), view.getPaddingBottom()); } } /** 增加View的paddingTop,增加的值为状态栏高度 (智能判断,并设置高度)*/ public static void setPaddingSmart(Context context, View view) { - if (Build.VERSION.SDK_INT >= 16) { + if (Build.VERSION.SDK_INT >= MIN_API) { ViewGroup.LayoutParams lp = view.getLayoutParams(); if (lp != null && lp.height > 0) { lp.height += getStatusBarHeight(context);//增高 @@ -231,7 +267,7 @@ public static void setPaddingSmart(Context context, View view) { /** 增加View的高度以及paddingTop,增加的值为状态栏高度.一般是在沉浸式全屏给ToolBar用的 */ public static void setHeightAndPadding(Context context, View view) { - if (Build.VERSION.SDK_INT >= 16) { + if (Build.VERSION.SDK_INT >= MIN_API) { ViewGroup.LayoutParams lp = view.getLayoutParams(); lp.height += getStatusBarHeight(context);//增高 view.setPadding(view.getPaddingLeft(), view.getPaddingTop() + getStatusBarHeight(context), @@ -240,7 +276,7 @@ public static void setHeightAndPadding(Context context, View view) { } /** 增加View上边距(MarginTop)一般是给高度为 WARP_CONTENT 的小控件用的*/ public static void setMargin(Context context, View view) { - if (Build.VERSION.SDK_INT >= 16) { + if (Build.VERSION.SDK_INT >= MIN_API) { ViewGroup.LayoutParams lp = view.getLayoutParams(); if (lp instanceof ViewGroup.MarginLayoutParams) { ((ViewGroup.MarginLayoutParams) lp).topMargin += getStatusBarHeight(context);//增高 diff --git a/app/src/main/java/com/scwang/refreshlayout/widget/RefreshContentHorizontal.java b/app/src/main/java/com/scwang/refreshlayout/widget/RefreshContentHorizontal.java new file mode 100644 index 00000000..63e12333 --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/widget/RefreshContentHorizontal.java @@ -0,0 +1,43 @@ +package com.scwang.refreshlayout.widget; + +import android.animation.ValueAnimator; +import android.support.annotation.NonNull; +import android.view.View; +import android.widget.AbsListView; + +import com.scwang.smart.refresh.layout.wrapper.RefreshContentWrapper; + +import static com.scwang.smartrefresh.layout.util.SmartUtil.scrollListBy; + +public class RefreshContentHorizontal extends RefreshContentWrapper { + + RefreshContentHorizontal(@NonNull View view) { + super(view); + } + + @Override + public ValueAnimator.AnimatorUpdateListener scrollContentWhenFinished(final int spinner) { + if (mScrollableView != null && spinner != 0) { + if ((spinner < 0 && mScrollableView.canScrollHorizontally(1)) || (spinner > 0 && mScrollableView.canScrollHorizontally(-1))) { + mLastSpinner = spinner; + return this; + } + } + return null; + } + + @Override + public void onAnimationUpdate(ValueAnimator animation) { + int value = (int) animation.getAnimatedValue(); + try { + if (mScrollableView instanceof AbsListView) { + scrollListBy((AbsListView) mScrollableView, value - mLastSpinner); + } else { + mScrollableView.scrollBy(value - mLastSpinner, 0); + } + } catch (Throwable ignored) { + //根据用户反馈,此处可能会有BUG + } + mLastSpinner = value; + } +} diff --git a/app/src/main/java/com/scwang/refreshlayout/widget/RefreshLayout.java b/app/src/main/java/com/scwang/refreshlayout/widget/RefreshLayout.java deleted file mode 100644 index 4e614917..00000000 --- a/app/src/main/java/com/scwang/refreshlayout/widget/RefreshLayout.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.scwang.refreshlayout.widget; - -import android.annotation.TargetApi; -import android.content.Context; -import android.os.Build; -import android.support.annotation.Px; -import android.support.v4.view.GestureDetectorCompat; -import android.util.AttributeSet; -import android.view.GestureDetector; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.widget.OverScroller; - -import com.scwang.smartrefresh.layout.api.RefreshContent; -import com.scwang.smartrefresh.layout.api.RefreshFooter; -import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.impl.RefreshContentWrapper; -import com.scwang.smartrefresh.layout.impl.RefreshFooterWrapper; -import com.scwang.smartrefresh.layout.impl.RefreshHeaderWrapper; - -import static android.view.View.MeasureSpec.AT_MOST; -import static android.view.View.MeasureSpec.EXACTLY; -import static android.view.View.MeasureSpec.getSize; -import static android.view.View.MeasureSpec.makeMeasureSpec; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; - -/** - * ScrollView - * Created by SCWANG on 2017/7/10. - */ - -public class RefreshLayout extends ViewGroup implements GestureDetector.OnGestureListener { - - private OverScroller mScroller; - private RefreshHeader mRefreshHeader; - private RefreshFooter mRefreshFooter; - private RefreshContent mRefreshContent; - private GestureDetectorCompat mGesture; - private int mTouchSlop; - /** - * 头部高度 - */ - protected int mHeaderHeight; - /** - * 底部高度 - */ - protected int mFooterHeight; - - - // - public RefreshLayout(Context context) { - super(context); - initView(context); - } - - public RefreshLayout(Context context, AttributeSet attrs) { - super(context, attrs); - initView(context); - } - - public RefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initView(context); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public RefreshLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - initView(context); - } - - private void initView(Context context) { - mScroller = new OverScroller(context); - mGesture = new GestureDetectorCompat(context, this); - mGesture.setIsLongpressEnabled(false); - mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); - } - // - - // - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - final int childCount = getChildCount(); - if (childCount == 1) { - mRefreshContent = new RefreshContentWrapper(getChildAt(0)); - } else if (childCount > 1) { - mRefreshHeader = new RefreshHeaderWrapper(getChildAt(0)); - mRefreshContent = new RefreshContentWrapper(getChildAt(1)); - if (childCount > 2) { - mRefreshFooter = new RefreshFooterWrapper(getChildAt(2)); - } - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - if (mRefreshContent != null) { - mRefreshContent.measure(widthMeasureSpec, heightMeasureSpec); - } - if (mRefreshHeader != null) { - final View headerView = mRefreshHeader.getView(); - final LayoutParams lp = (LayoutParams) headerView.getLayoutParams(); - final int widthSpec = getChildMeasureSpec(widthMeasureSpec, lp.leftMargin + lp.rightMargin, lp.width); - int heightSpec = heightMeasureSpec; - if (lp.height > 0) { - heightSpec = makeMeasureSpec(lp.height, EXACTLY); - headerView.measure(widthSpec, heightSpec); - } else if (lp.height == WRAP_CONTENT) { - heightSpec = makeMeasureSpec(Math.max(getSize(heightMeasureSpec)/* - lp.topMargin*/ - lp.bottomMargin, 0), AT_MOST); - headerView.measure(widthSpec, heightSpec); - } else { - headerView.measure(widthSpec, heightSpec); - } - mHeaderHeight = headerView.getMeasuredHeight(); - } - if (mRefreshFooter != null) { - final View footerView = mRefreshFooter.getView(); - final LayoutParams lp = (LayoutParams) footerView.getLayoutParams(); - final int widthSpec = getChildMeasureSpec(widthMeasureSpec, lp.leftMargin + lp.rightMargin, lp.width); - int heightSpec = heightMeasureSpec; - if (lp.height > 0) { - heightSpec = makeMeasureSpec(lp.height, EXACTLY); - footerView.measure(widthSpec, heightSpec); - } else if (lp.height == WRAP_CONTENT) { - heightSpec = makeMeasureSpec(Math.max(getSize(heightMeasureSpec)/* - lp.topMargin*/ - lp.bottomMargin, 0), AT_MOST); - footerView.measure(widthSpec, heightSpec); - } else { - footerView.measure(widthSpec, heightSpec); - } - mFooterHeight = footerView.getMeasuredHeight(); - } - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - if (mRefreshContent != null) { - mRefreshContent.layout(0, 0, getMeasuredWidth(), getMeasuredHeight()); - } - if (mRefreshHeader != null) { - final View headerView = mRefreshHeader.getView(); - int right = headerView.getMeasuredWidth(); - int top = -headerView.getMeasuredHeight(); - headerView.layout(0, top, right, 0); - } - if (mRefreshFooter != null) { - final View headerView = mRefreshFooter.getView(); - int right = headerView.getMeasuredWidth(); - int top = getMeasuredHeight(); - int bottom = top + headerView.getMeasuredHeight(); - headerView.layout(0, top, right, bottom); - } - } - // - - // - @Override - protected LayoutParams generateDefaultLayoutParams() { - return new LayoutParams(MATCH_PARENT, MATCH_PARENT); - } - - @Override - protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { - return new LayoutParams(p); - } - - @Override - public LayoutParams generateLayoutParams(AttributeSet attrs) { - return new LayoutParams(getContext(), attrs); - } - - public static class LayoutParams extends MarginLayoutParams { - - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - } - - public LayoutParams(int width, int height) { - super(width, height); - } - - public LayoutParams(MarginLayoutParams source) { - super(source); - } - - public LayoutParams(ViewGroup.LayoutParams source) { - super(source); - } - - } - // - - // - -// @Override -// public boolean dispatchTouchEvent(MotionEvent ev) { -// switch (MotionEventCompat.getActionMasked(ev)) { -// case MotionEvent.ACTION_DOWN: -// mIsBeingDragged = false; -// mInitialDownY = ev.getY(); -// mGesture.onTouchEvent(ev); -// break; -// -// } -// return mIsBeingDragged;//super.dispatchTouchEvent(ev); -// } - - @Override - public boolean onInterceptTouchEvent(MotionEvent ev) { - return true;//super.onInterceptTouchEvent(ev); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - return mGesture.onTouchEvent(event); - } - // - - // - @Override - public void computeScroll() { - if (mScroller.computeScrollOffset()) { - scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); - postInvalidate(); - } - } - @Override - public void scrollTo(@Px int x, @Px int y) { - super.scrollTo(x, Math.max(Math.min(y, mFooterHeight), -mHeaderHeight)); - } - // - - // - @Override - public boolean onDown(MotionEvent e) { - return true; - } - - @Override - public void onShowPress(MotionEvent e) { - - } - - @Override - public boolean onSingleTapUp(MotionEvent e) { - return false; - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - scrollBy(0, (int)distanceY); - return true; - } - - @Override - public void onLongPress(MotionEvent e) { - - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - mScroller.fling(0, getScrollY(), 0, -(int)velocityY, 0, 0, -mHeaderHeight, mFooterHeight); - return true; - } - // -} diff --git a/app/src/main/java/com/scwang/refreshlayout/widget/ScrollBoundaryHorizontal.java b/app/src/main/java/com/scwang/refreshlayout/widget/ScrollBoundaryHorizontal.java new file mode 100644 index 00000000..f13889bd --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/widget/ScrollBoundaryHorizontal.java @@ -0,0 +1,85 @@ +package com.scwang.refreshlayout.widget; + +import android.graphics.PointF; +import android.support.annotation.NonNull; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AbsListView; + +import com.scwang.smartrefresh.layout.util.SmartUtil; + +/** + * 滚动边界 + * Created by scwang on 2017/7/8. + */ +@SuppressWarnings("WeakerAccess") +public class ScrollBoundaryHorizontal { + + // + + /** + * 判断内容是否可以刷新 + * @param targetView 内容视图 + * @param touch 按压事件位置 + * @return 是否可以刷新 + */ + public static boolean canRefresh(@NonNull View targetView, PointF touch) { + if (targetView.canScrollHorizontally(-1) && targetView.getVisibility() == View.VISIBLE) { + return false; + } + //touch == null 时 canRefresh 不会动态递归搜索 + if (targetView instanceof ViewGroup && touch != null) { + ViewGroup viewGroup = (ViewGroup) targetView; + final int childCount = viewGroup.getChildCount(); + PointF point = new PointF(); + for (int i = childCount; i > 0; i--) { + View child = viewGroup.getChildAt(i - 1); + if (SmartUtil.isTransformedTouchPointInView(viewGroup, child, touch.x, touch.y, point)) { + if ("fixed".equals(child.getTag())) { + return false; + } + touch.offset(point.x, point.y); + boolean can = canRefresh(child, touch); + touch.offset(-point.x, -point.y); + return can; + } + } + } + return true; + } + + /** + * 判断内容视图是否可以加载更多 + * @param targetView 内容视图 + * @param touch 按压事件位置 + * @param contentFull 内容是否填满页面 (未填满时,会通过canScrollUp自动判断) + * @return 是否可以刷新 + */ + public static boolean canLoadMore(@NonNull View targetView, PointF touch, boolean contentFull) { + if (targetView.canScrollHorizontally(1) && targetView.getVisibility() == View.VISIBLE) { + return false; + } + //touch == null 时 canLoadMore 不会动态递归搜索 + if (targetView instanceof ViewGroup && touch != null && !SmartUtil.isScrollableView(targetView)) { + ViewGroup viewGroup = (ViewGroup) targetView; + final int childCount = viewGroup.getChildCount(); + PointF point = new PointF(); + for (int i = 0; i < childCount; i++) { + View child = viewGroup.getChildAt(i); + if (SmartUtil.isTransformedTouchPointInView(viewGroup, child, touch.x, touch.y, point)) { + if ("fixed".equals(child.getTag())) { + return false; + } + touch.offset(point.x, point.y); + boolean can = canLoadMore(child, touch, contentFull); + touch.offset(-point.x, -point.y); + return can; + } + } + } + return (contentFull || targetView.canScrollHorizontally(-1)); + } + + // + +} diff --git a/app/src/main/java/com/scwang/refreshlayout/widget/SmartRefreshHorizontal.java b/app/src/main/java/com/scwang/refreshlayout/widget/SmartRefreshHorizontal.java new file mode 100644 index 00000000..b738fa0e --- /dev/null +++ b/app/src/main/java/com/scwang/refreshlayout/widget/SmartRefreshHorizontal.java @@ -0,0 +1,132 @@ +package com.scwang.refreshlayout.widget; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Interpolator; +import android.widget.FrameLayout; + +import com.scwang.refreshlayout.R; +import com.scwang.smart.refresh.layout.api.RefreshComponent; +import com.scwang.smart.refresh.layout.api.RefreshFooter; +import com.scwang.smart.refresh.layout.api.RefreshHeader; +import com.scwang.smart.refresh.layout.api.RefreshLayout; +import com.scwang.smart.refresh.layout.constant.RefreshState; +import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener; +import com.scwang.smart.refresh.layout.listener.OnMultiListener; +import com.scwang.smart.refresh.layout.listener.OnRefreshListener; +import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener; +import com.scwang.smart.refresh.layout.listener.ScrollBoundaryDecider; +import com.scwang.smart.refresh.layout.util.SmartUtil; +import com.scwang.smartrefresh.layout.SmartRefreshLayout; +import com.scwang.smartrefresh.layout.impl.ScrollBoundaryDeciderAdapter; + +public class SmartRefreshHorizontal extends SmartRefreshLayout { + + protected boolean isInLayout = false; + + public SmartRefreshHorizontal(Context context) { + this(context, null); + } + + public SmartRefreshHorizontal(Context context, AttributeSet attrs) { + super(context, attrs); + setEnableAutoLoadMore(false); + setScrollBoundaryDecider(new ScrollBoundaryDeciderAdapter(){ + @Override + public boolean canRefresh(View content) { + return ScrollBoundaryHorizontal.canRefresh(content, mActionEvent); + } + @Override + public boolean canLoadMore(View content) { + return ScrollBoundaryHorizontal.canLoadMore(content, mActionEvent, mEnableLoadMoreWhenContentNotFull); + } + }); + } + + // + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (mRefreshContent != null && !(mRefreshContent instanceof RefreshContentHorizontal)) { + mRefreshContent = new RefreshContentHorizontal(mRefreshContent.getView()); + View fixedHeaderView = mFixedHeaderViewId > 0 ? findViewById(mFixedHeaderViewId) : null; + View fixedFooterView = mFixedFooterViewId > 0 ? findViewById(mFixedFooterViewId) : null; + + mRefreshContent.setScrollBoundaryDecider(mScrollBoundaryDecider); + mRefreshContent.setEnableLoadMoreWhenContentNotFull(mEnableLoadMoreWhenContentNotFull); + mRefreshContent.setUpComponent(mKernel, fixedHeaderView, fixedFooterView); + } + + setRotation(-90); + } + + @Override + @SuppressWarnings("SuspiciousNameCombination") + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(heightMeasureSpec, widthMeasureSpec); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + int width = right - left; + int height = bottom - top; + int div = (height - width) / 2; + if (isInLayout) { + RefreshComponent header = mRefreshHeader; + RefreshComponent footer = mRefreshFooter; + + final View thisView = this; + int paddingLeft = thisView.getPaddingLeft(); + int paddingRight = thisView.getPaddingRight(); + int paddingTop = thisView.getPaddingTop(); + int paddingBottom = thisView.getPaddingBottom(); + + for (int i = 0, len = getChildCount(); i < len; i++) { + View child = getChildAt(i); + if ((header == null || child != header.getView()) && (footer == null || child != footer.getView())) { + if (child.getVisibility() != GONE) { + + int w = height; + int h = width; + int l = paddingBottom; + int t = paddingLeft; + + h -= paddingTop + paddingBottom; + w -= paddingLeft + paddingRight; + + ViewGroup.LayoutParams params = child.getLayoutParams(); + if (params instanceof MarginLayoutParams) { + MarginLayoutParams lp = (MarginLayoutParams) params; + h -= lp.topMargin + lp.bottomMargin; + w -= lp.leftMargin + lp.rightMargin; + l += lp.bottomMargin; + t += lp.leftMargin; + } + + div = (h - w) / 2; + l += div; + t -= div; + + child.setRotation(90); + child.setTag(R.id.srl_tag, "GONE"); + child.measure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY)); + child.layout(l, t, l + w, t + h); + } + } + } + super.onLayout(changed, left, top, right, bottom); + } else { + top -= div; + left += div; + isInLayout = true; + super.layout(left, top, left + width, top + height); + isInLayout = false; + } + + } + // +} diff --git a/app/src/main/res/drawable/animation_loading_frame.xml b/app/src/main/res/drawable/animation_loading_frame.xml new file mode 100644 index 00000000..0561bdc8 --- /dev/null +++ b/app/src/main/res/drawable/animation_loading_frame.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/animation_loading_rotate.xml b/app/src/main/res/drawable/animation_loading_rotate.xml new file mode 100644 index 00000000..1b9f3f0e --- /dev/null +++ b/app/src/main/res/drawable/animation_loading_rotate.xml @@ -0,0 +1,11 @@ + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bc_background_panel.xml b/app/src/main/res/drawable/bc_background_panel.xml index f85082fe..bb5f3364 100644 --- a/app/src/main/res/drawable/bc_background_panel.xml +++ b/app/src/main/res/drawable/bc_background_panel.xml @@ -1,6 +1,6 @@ - + diff --git a/app/src/main/res/drawable/button_blue.xml b/app/src/main/res/drawable/button_blue.xml new file mode 100644 index 00000000..fb16cb32 --- /dev/null +++ b/app/src/main/res/drawable/button_blue.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_empty.xml b/app/src/main/res/drawable/ic_empty.xml new file mode 100644 index 00000000..f61ec5e7 --- /dev/null +++ b/app/src/main/res/drawable/ic_empty.xml @@ -0,0 +1,4 @@ + + + diff --git a/app/src/main/res/drawable/ic_error.xml b/app/src/main/res/drawable/ic_error.xml new file mode 100644 index 00000000..52c296a0 --- /dev/null +++ b/app/src/main/res/drawable/ic_error.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_fly_refresh_smartphone.xml b/app/src/main/res/drawable/ic_fly_refresh_phone.xml similarity index 100% rename from app/src/main/res/drawable/ic_fly_refresh_smartphone.xml rename to app/src/main/res/drawable/ic_fly_refresh_phone.xml diff --git a/app/src/main/res/drawable/ic_index_dashboard.xml b/app/src/main/res/drawable/ic_index_dashboard.xml index ae6a4468..dfacf578 100644 --- a/app/src/main/res/drawable/ic_index_dashboard.xml +++ b/app/src/main/res/drawable/ic_index_dashboard.xml @@ -4,6 +4,6 @@ android:viewportHeight="24.0" android:viewportWidth="24.0"> diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..762e7073 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_list_divider.xml b/app/src/main/res/drawable/ic_list_divider.xml index b8cdb1ba..d7ab10ac 100644 --- a/app/src/main/res/drawable/ic_list_divider.xml +++ b/app/src/main/res/drawable/ic_list_divider.xml @@ -1,8 +1,8 @@ - + - + @@ -10,9 +10,9 @@ - + - + diff --git a/app/src/main/res/drawable/ic_progress_puzzle.xml b/app/src/main/res/drawable/ic_progress_puzzle.xml new file mode 100644 index 00000000..b38539e9 --- /dev/null +++ b/app/src/main/res/drawable/ic_progress_puzzle.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/skin_instantchat_more.xml b/app/src/main/res/drawable/skin_instantchat_more.xml new file mode 100644 index 00000000..4e7ce046 --- /dev/null +++ b/app/src/main/res/drawable/skin_instantchat_more.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/app/src/main/res/drawable/skin_messages_left_bubble.xml b/app/src/main/res/drawable/skin_messages_left_bubble.xml new file mode 100644 index 00000000..54506f5a --- /dev/null +++ b/app/src/main/res/drawable/skin_messages_left_bubble.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/skin_messages_right_bubble.xml b/app/src/main/res/drawable/skin_messages_right_bubble.xml new file mode 100644 index 00000000..970f6499 --- /dev/null +++ b/app/src/main/res/drawable/skin_messages_right_bubble.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/activity_using_assign_code.xml b/app/src/main/res/layout/activity_example_assign_code.xml similarity index 73% rename from app/src/main/res/layout/activity_using_assign_code.xml rename to app/src/main/res/layout/activity_example_assign_code.xml index 3d3a479a..22a451ad 100644 --- a/app/src/main/res/layout/activity_using_assign_code.xml +++ b/app/src/main/res/layout/activity_example_assign_code.xml @@ -5,21 +5,22 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.using.AssignCodeUsingActivity"> + tools:context="com.scwang.refreshlayout.activity.example.AssignCodeExampleActivity"> + app:title="@string/title_activity_example_assign_code"/> + android:layout_height="match_parent" + app:srlEnableLoadMoreWhenContentNotFull="true"> diff --git a/app/src/main/res/layout/activity_using_assign_default.xml b/app/src/main/res/layout/activity_example_assign_default.xml similarity index 76% rename from app/src/main/res/layout/activity_using_assign_default.xml rename to app/src/main/res/layout/activity_example_assign_default.xml index 1ee0368d..93c33566 100644 --- a/app/src/main/res/layout/activity_using_assign_default.xml +++ b/app/src/main/res/layout/activity_example_assign_default.xml @@ -5,12 +5,12 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.using.AssignDefaultUsingActivity"> + tools:context="com.scwang.refreshlayout.activity.example.AssignDefaultExampleActivity"> + app:title="@string/title_activity_example_assign_default"/> + android:text="@string/description_set_default_creator"/> diff --git a/app/src/main/res/layout/activity_using_assign_xml.xml b/app/src/main/res/layout/activity_example_assign_xml.xml similarity index 85% rename from app/src/main/res/layout/activity_using_assign_xml.xml rename to app/src/main/res/layout/activity_example_assign_xml.xml index 2955bbe3..ef262518 100644 --- a/app/src/main/res/layout/activity_using_assign_xml.xml +++ b/app/src/main/res/layout/activity_example_assign_xml.xml @@ -5,12 +5,12 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.using.AssignDefaultUsingActivity"> + tools:context="com.scwang.refreshlayout.activity.example.AssignDefaultExampleActivity"> + app:title="@string/title_activity_example_assign_xml"/> + app:srlEnablePreviewInEditMode="true" + app:srlEnableLoadMoreWhenContentNotFull="true"> + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_using_listener.xml b/app/src/main/res/layout/activity_example_custom.xml similarity index 74% rename from app/src/main/res/layout/activity_using_listener.xml rename to app/src/main/res/layout/activity_example_custom.xml index 7bd569cb..9f9d3249 100644 --- a/app/src/main/res/layout/activity_using_listener.xml +++ b/app/src/main/res/layout/activity_example_custom.xml @@ -5,24 +5,24 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.using.ListenerUsingActivity"> + tools:context="com.scwang.refreshlayout.activity.example.CustomExampleActivity"> + app:title="@string/title_activity_example_custom"/> - + android:overScrollMode="never" + tools:listitem="@android:layout/simple_list_item_2"/> diff --git a/app/src/main/res/layout/activity_using_basic.xml b/app/src/main/res/layout/activity_example_i18n.xml similarity index 71% rename from app/src/main/res/layout/activity_using_basic.xml rename to app/src/main/res/layout/activity_example_i18n.xml index 7454fc81..85a9a03b 100644 --- a/app/src/main/res/layout/activity_using_basic.xml +++ b/app/src/main/res/layout/activity_example_i18n.xml @@ -5,27 +5,24 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.using.BasicUsingActivity"> + tools:context="com.scwang.refreshlayout.activity.example.I18nExampleActivity"> + app:title="@string/title_activity_example_i18n"/> - diff --git a/app/src/main/res/layout/activity_example_listener.xml b/app/src/main/res/layout/activity_example_listener.xml new file mode 100644 index 00000000..2a594e78 --- /dev/null +++ b/app/src/main/res/layout/activity_example_listener.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_using_overscroll.xml b/app/src/main/res/layout/activity_example_overscroll.xml similarity index 85% rename from app/src/main/res/layout/activity_using_overscroll.xml rename to app/src/main/res/layout/activity_example_overscroll.xml index bced3015..486eb406 100644 --- a/app/src/main/res/layout/activity_using_overscroll.xml +++ b/app/src/main/res/layout/activity_example_overscroll.xml @@ -5,12 +5,12 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.using.OverScrollUsingActivity"> + tools:context="com.scwang.refreshlayout.activity.example.OverScrollExampleActivity"> + app:title="@string/title_activity_example_over_scroll"/> - + @@ -31,7 +31,7 @@ - + + tools:context="com.scwang.refreshlayout.activity.example.NestedLayoutExampleActivity"> - + app:srlFixedHeaderViewId="@+id/fsr_region_lyt" + app:srlEnableLoadMore="true"> + android:background="@color/colorBackground"> - + diff --git a/app/src/main/res/layout/activity_example_snaphelper.xml b/app/src/main/res/layout/activity_example_snaphelper.xml new file mode 100644 index 00000000..b3d84b2c --- /dev/null +++ b/app/src/main/res/layout/activity_example_snaphelper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_experiment.xml b/app/src/main/res/layout/activity_experiment.xml index 4d20544d..cb3da6d7 100644 --- a/app/src/main/res/layout/activity_experiment.xml +++ b/app/src/main/res/layout/activity_experiment.xml @@ -6,24 +6,48 @@ android:layout_height="match_parent" tools:context="com.scwang.refreshlayout.activity.ExperimentActivity"> - - - + - + - + android:layout_height="match_parent" + android:gravity="center" + android:text="Footer"/> + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_fly_refresh.xml b/app/src/main/res/layout/activity_fly_refresh.xml index f92b3260..ee122cd0 100644 --- a/app/src/main/res/layout/activity_fly_refresh.xml +++ b/app/src/main/res/layout/activity_fly_refresh.xml @@ -7,8 +7,8 @@ android:clipChildren="false" tools:context="com.scwang.refreshlayout.activity.style.FlyRefreshStyleActivity"> - @@ -52,11 +52,12 @@ app:srlHeaderMaxDragRate="1.5" app:srlHeaderHeight="100dp" app:srlReboundDuration="200" - app:srlEnableLoadmore="false" + app:srlEnableLoadMore="false" app:srlEnablePreviewInEditMode="true" + app:srlEnableOverScrollBounce="false" app:layout_behavior="@string/appbar_scrolling_view_behavior"> @@ -79,8 +81,8 @@ app:layout_anchorGravity="top" app:elevation="0dp" /> - diff --git a/app/src/main/res/layout/activity_practice_banner.xml b/app/src/main/res/layout/activity_practice_banner.xml new file mode 100644 index 00000000..484d4af1 --- /dev/null +++ b/app/src/main/res/layout/activity_practice_banner.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_practice_feedlist.xml b/app/src/main/res/layout/activity_practice_feedlist.xml index 89ba506e..20e471a9 100644 --- a/app/src/main/res/layout/activity_practice_feedlist.xml +++ b/app/src/main/res/layout/activity_practice_feedlist.xml @@ -5,12 +5,13 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.practice.ProfilePracticeActivity"> + android:background="@android:color/white" + tools:context="com.scwang.refreshlayout.activity.practice.FeedListPracticeActivity"> + app:title="@string/title_activity_practice_feed_list"/> + app:srlEnablePreviewInEditMode="false" + app:srlFooterTranslationViewId="@+id/scrollView" + app:srlEnableLoadMoreWhenContentNotFull="false"> + android:layout_height="wrap_content"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:gravity="center_horizontal"> + android:clipToPadding="false" + android:background="@color/colorPrimaryDark"> + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -182,19 +88,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -203,8 +109,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -243,10 +149,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -265,8 +171,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -305,8 +211,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line"> @@ -328,8 +234,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -368,10 +274,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -390,8 +296,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -430,8 +336,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line"> @@ -453,8 +359,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -493,19 +399,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -514,8 +420,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -554,10 +460,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -576,8 +482,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -616,8 +522,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line"> @@ -639,8 +545,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -679,19 +585,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -700,8 +606,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -740,10 +646,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -762,8 +668,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -802,8 +708,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line"> @@ -825,8 +731,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -865,19 +771,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="@android:color/white" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -886,8 +792,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -926,10 +832,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -947,6 +853,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + app:srlEnableLoadMore="false" + app:srlDragRate="0.75"> - @@ -77,7 +78,7 @@ @@ -104,7 +105,7 @@ @@ -131,9 +132,9 @@ + app:srcCompat="@drawable/ic_fly_refresh_phone"/> @@ -173,7 +174,7 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_practice_repast.xml b/app/src/main/res/layout/activity_practice_repast.xml index 5f27127a..9acbb1b8 100644 --- a/app/src/main/res/layout/activity_practice_repast.xml +++ b/app/src/main/res/layout/activity_practice_repast.xml @@ -4,36 +4,47 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/colorBackgroudDark" + android:background="@color/colorBackgroundDark" tools:context="com.scwang.refreshlayout.activity.practice.RepastPracticeActivity"> + app:srlEnableAutoLoadMore="true" + app:srlHeaderInsetStart="?attr/actionBarSize" + app:srlHeaderTriggerRate="0.5"> + android:src="@mipmap/gif_header_repast" + app:layout_srlSpinnerStyle="Scale" + app:layout_srlBackgroundColor="@android:color/transparent"/> + android:overScrollMode="never" + tools:listitem="@layout/item_practice_repast"/> + diff --git a/app/src/main/res/layout/activity_practice_webview.xml b/app/src/main/res/layout/activity_practice_webview.xml index 83d88292..563154c0 100644 --- a/app/src/main/res/layout/activity_practice_webview.xml +++ b/app/src/main/res/layout/activity_practice_webview.xml @@ -4,8 +4,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="@color/colorBackgroudDark" - tools:context="com.scwang.refreshlayout.activity.practice.WebviewPracticeActivity"> + android:background="@color/colorBackgroundDark" + tools:context="com.scwang.refreshlayout.activity.practice.WebViewPracticeActivity"> - - - - - + app:title="@string/title_activity_practice_web_view"/> diff --git a/app/src/main/res/layout/activity_practice_weibo.xml b/app/src/main/res/layout/activity_practice_weibo.xml index 9823b2c5..b88ac62d 100644 --- a/app/src/main/res/layout/activity_practice_weibo.xml +++ b/app/src/main/res/layout/activity_practice_weibo.xml @@ -4,12 +4,13 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@android:color/white" tools:context="com.scwang.refreshlayout.activity.practice.WeiboPracticeActivity"> + app:layout_scrollFlags="scroll|exitUntilCollapsed"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"/> + android:layout_marginTop="@dimen/dimenPaddingCommon"> + android:layout_marginLeft="@dimen/dimenPaddingHorizontal" + android:layout_marginRight="@dimen/dimenPaddingHorizontal"/> - @@ -138,8 +142,8 @@ android:id="@+id/avatar" android:layout_width="80dp" android:layout_height="80dp" - android:layout_marginLeft="@dimen/padding_common" - android:layout_marginStart="@dimen/padding_common" + android:layout_marginLeft="@dimen/dimenPaddingCommon" + android:layout_marginStart="@dimen/dimenPaddingCommon" android:src="@mipmap/image_avatar_5" app:civ_border_width="3dp" app:civ_border_color="@android:color/white" @@ -157,7 +161,7 @@ android:textColor="@android:color/white" android:text="访客总量 15"/> - @@ -167,11 +171,11 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:background="@color/colorBackgroudDark" + android:background="@color/colorBackgroundDark" android:paddingBottom="0dp" app:layout_scrollFlags="scroll"> + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -232,19 +236,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -253,8 +257,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -294,10 +298,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -316,8 +320,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -357,8 +361,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line"> @@ -380,8 +384,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -421,10 +425,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -443,8 +447,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -484,8 +488,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line"> @@ -507,8 +511,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -548,19 +552,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -569,8 +573,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -610,10 +614,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -632,8 +636,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -673,8 +677,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line"> @@ -696,8 +700,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -737,19 +741,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -758,8 +762,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -799,10 +803,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -821,8 +825,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -862,8 +866,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" - app:rv_cornerRadius="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line"> @@ -885,8 +889,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -926,19 +930,19 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - android:padding="@dimen/padding_common" + android:padding="@dimen/dimenPaddingCommon" app:rv_strokeColor="#cccccc" app:rv_strokeWidth="@dimen/division_line" - app:rv_cornerRadius="@dimen/padding_common_d"> + app:rv_cornerRadius="@dimen/dimenPaddingDiminutive"> - @@ -947,8 +951,8 @@ + android:paddingLeft="@dimen/dimenPaddingCommon" + android:paddingRight="@dimen/dimenPaddingCommon"> @@ -988,10 +992,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" - android:layout_marginBottom="@dimen/padding_common_d" + android:layout_marginBottom="@dimen/dimenPaddingDiminutive" android:orientation="vertical" - app:rv_cornerRadius_TL="@dimen/padding_common_d" - app:rv_cornerRadius_TR="@dimen/padding_common_d"> + app:rv_cornerRadius_TL="@dimen/dimenPaddingDiminutive" + app:rv_cornerRadius_TR="@dimen/dimenPaddingDiminutive"> @@ -1027,8 +1031,8 @@ android:id="@+id/toolbar_avatar" android:layout_width="32dp" android:layout_height="32dp" - android:layout_marginEnd="@dimen/padding_common_d" - android:layout_marginRight="@dimen/padding_common_d" + android:layout_marginEnd="@dimen/dimenPaddingDiminutive" + android:layout_marginRight="@dimen/dimenPaddingDiminutive" android:src="@mipmap/image_avatar_5" app:civ_border_width="@dimen/division_line" app:civ_border_color="@android:color/white" diff --git a/app/src/main/res/layout/activity_style_bezier.xml b/app/src/main/res/layout/activity_style_bezier.xml index facc98c6..0f355ce9 100644 --- a/app/src/main/res/layout/activity_style_bezier.xml +++ b/app/src/main/res/layout/activity_style_bezier.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.scwang.refreshlayout.activity.style.BezierStyleActivity" + tools:context="com.scwang.refreshlayout.activity.style.BezierRadarStyleActivity" android:orientation="vertical"> + app:srlEnableLoadMore="false"> diff --git a/app/src/main/res/layout/activity_style_circle.xml b/app/src/main/res/layout/activity_style_circle.xml index 72743682..ceaa0fb4 100644 --- a/app/src/main/res/layout/activity_style_circle.xml +++ b/app/src/main/res/layout/activity_style_circle.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.scwang.refreshlayout.activity.style.CircleStyleActivity" + tools:context="com.scwang.refreshlayout.activity.style.BezierCircleStyleActivity" android:orientation="vertical"> - + diff --git a/app/src/main/res/layout/activity_style_classics.xml b/app/src/main/res/layout/activity_style_classics.xml index 806f89d4..55af5972 100644 --- a/app/src/main/res/layout/activity_style_classics.xml +++ b/app/src/main/res/layout/activity_style_classics.xml @@ -4,7 +4,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.scwang.refreshlayout.activity.style.BezierStyleActivity" + android:background="@color/colorBackgroundDark" + tools:context="com.scwang.refreshlayout.activity.style.ClassicsStyleActivity" android:orientation="vertical"> + app:srlAccentColor="@color/colorTextContent" + app:srlPrimaryColor="@android:color/transparent" + app:srlEnableLoadMore="true" + app:srlEnableAutoLoadMore="false"> + app:srlFinishDuration="500" + app:srlEnableLastTime="true" + app:srlClassicsSpinnerStyle="FixedBehind" + app:srlTextSizeTitle="16sp" + app:srlTextSizeTime="10dp" + app:srlTextTimeMarginTop="2dp" + app:srlDrawableArrowSize="20dp" + app:srlDrawableProgressSize="20dp" + app:srlDrawableMarginRight="20dp" + app:srlDrawableProgress="@drawable/ic_progress_puzzle"/> + app:srlEnableLoadMore="false" + app:srlAccentColor="@android:color/white" + app:srlPrimaryColor="@android:color/transparent"> @@ -30,8 +32,9 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:clipToPadding="false" - android:padding="@dimen/padding_common_d" - tools:listitem="@layout/listitem_style_delivery"/> + android:padding="@dimen/dimenPaddingDiminutive" + android:overScrollMode="never" + tools:listitem="@layout/item_style_delivery"/> \ No newline at end of file diff --git a/app/src/main/res/layout/activity_style_dropbox.xml b/app/src/main/res/layout/activity_style_dropbox.xml index ec221932..4fd11b80 100644 --- a/app/src/main/res/layout/activity_style_dropbox.xml +++ b/app/src/main/res/layout/activity_style_dropbox.xml @@ -4,31 +4,33 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.scwang.refreshlayout.activity.style.BezierStyleActivity" + tools:context="com.scwang.refreshlayout.activity.style.BezierRadarStyleActivity" android:orientation="vertical"> + app:title="@string/title_activity_style_drop_box"/> - + diff --git a/app/src/main/res/layout/activity_style_fungame_battlecity.xml b/app/src/main/res/layout/activity_style_fungame_battlecity.xml index 32259a9a..ae4cc858 100644 --- a/app/src/main/res/layout/activity_style_fungame_battlecity.xml +++ b/app/src/main/res/layout/activity_style_fungame_battlecity.xml @@ -4,21 +4,22 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.scwang.refreshlayout.activity.style.BezierStyleActivity" + tools:context="com.scwang.refreshlayout.activity.style.BezierRadarStyleActivity" android:orientation="vertical"> + app:title="@string/title_activity_style_battle_city"/> + app:srlEnableLoadMore="false"> @@ -26,6 +27,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:overScrollMode="never" tools:listitem="@android:layout/simple_list_item_2"/> diff --git a/app/src/main/res/layout/activity_style_fungame_hitblock.xml b/app/src/main/res/layout/activity_style_fungame_hitblock.xml index 7e026865..ede4d887 100644 --- a/app/src/main/res/layout/activity_style_fungame_hitblock.xml +++ b/app/src/main/res/layout/activity_style_fungame_hitblock.xml @@ -4,21 +4,22 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.scwang.refreshlayout.activity.style.BezierStyleActivity" + tools:context="com.scwang.refreshlayout.activity.style.BezierRadarStyleActivity" android:orientation="vertical"> + app:title="@string/title_activity_style_hit_block"/> + app:srlEnableLoadMore="false"> @@ -26,6 +27,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:overScrollMode="never" tools:listitem="@android:layout/simple_list_item_2"/> diff --git a/app/src/main/res/layout/activity_style_material.xml b/app/src/main/res/layout/activity_style_material.xml index 77612398..904c9072 100644 --- a/app/src/main/res/layout/activity_style_material.xml +++ b/app/src/main/res/layout/activity_style_material.xml @@ -16,10 +16,11 @@ android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@android:color/white" app:srlPrimaryColor="@color/colorPrimary" app:srlAccentColor="@android:color/white" app:srlEnableHeaderTranslationContent="false" - app:srlEnableLoadmore="false"> + app:srlEnableLoadMore="false"> @@ -27,6 +28,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:overScrollMode="never" tools:listitem="@android:layout/simple_list_item_2"/> diff --git a/app/src/main/res/layout/activity_style_phoenix.xml b/app/src/main/res/layout/activity_style_phoenix.xml index 68dd5f24..eca26684 100644 --- a/app/src/main/res/layout/activity_style_phoenix.xml +++ b/app/src/main/res/layout/activity_style_phoenix.xml @@ -7,14 +7,14 @@ tools:context="com.scwang.refreshlayout.activity.style.PhoenixStyleActivity"> + app:srlEnableLoadMore="false"> @@ -47,6 +48,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:overScrollMode="never" tools:listitem="@android:layout/simple_list_item_2"/> @@ -55,7 +57,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/fab_margin" - app:srcCompat="@drawable/ic_fly_refresh_smartphone" + app:srcCompat="@drawable/ic_fly_refresh_phone" app:layout_anchor="@id/recyclerView" app:layout_anchorGravity="top|end" app:fabSize="normal" diff --git a/app/src/main/res/layout/activity_style_storehouse.xml b/app/src/main/res/layout/activity_style_storehouse.xml index b82b55eb..0523a09a 100644 --- a/app/src/main/res/layout/activity_style_storehouse.xml +++ b/app/src/main/res/layout/activity_style_storehouse.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.scwang.refreshlayout.activity.style.BezierStyleActivity" + tools:context="com.scwang.refreshlayout.activity.style.BezierRadarStyleActivity" android:orientation="vertical"> diff --git a/app/src/main/res/layout/activity_style_taurus.xml b/app/src/main/res/layout/activity_style_taurus.xml index 23bc3840..fb4542df 100644 --- a/app/src/main/res/layout/activity_style_taurus.xml +++ b/app/src/main/res/layout/activity_style_taurus.xml @@ -7,14 +7,14 @@ tools:context="com.scwang.refreshlayout.activity.style.TaurusStyleActivity"> + app:srlEnableLoadMore="false"> @@ -47,6 +48,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:overScrollMode="never" tools:listitem="@android:layout/simple_list_item_2"/> @@ -55,7 +57,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/fab_margin" - app:srcCompat="@drawable/ic_fly_refresh_smartphone" + app:srcCompat="@drawable/ic_fly_refresh_phone" app:layout_anchor="@id/recyclerView" app:layout_anchorGravity="top|end" app:fabSize="normal" diff --git a/app/src/main/res/layout/activity_style_water_drop.xml b/app/src/main/res/layout/activity_style_water_drop.xml index 7fa1b1cc..6dc43ac7 100644 --- a/app/src/main/res/layout/activity_style_water_drop.xml +++ b/app/src/main/res/layout/activity_style_water_drop.xml @@ -16,9 +16,12 @@ android:id="@+id/refreshLayout" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@android:color/white" + app:srlHeaderMaxDragRate="2.5" app:srlPrimaryColor="@android:color/darker_gray" app:srlAccentColor="@android:color/white" - app:srlEnableLoadmore="false"> + app:srlEnableLoadMore="false"> + @@ -26,6 +29,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:overScrollMode="never" tools:listitem="@android:layout/simple_list_item_2"/> diff --git a/app/src/main/res/layout/activity_style_wave_swip.xml b/app/src/main/res/layout/activity_style_wave_swipe.xml similarity index 86% rename from app/src/main/res/layout/activity_style_wave_swip.xml rename to app/src/main/res/layout/activity_style_wave_swipe.xml index a19e354f..59f750f1 100644 --- a/app/src/main/res/layout/activity_style_wave_swip.xml +++ b/app/src/main/res/layout/activity_style_wave_swipe.xml @@ -5,21 +5,22 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.activity.style.WaveSwipStyleActivity"> + tools:context="com.scwang.refreshlayout.activity.style.WaveSwipeStyleActivity"> + app:title="@string/title_activity_style_wave_swipe"/> + app:srlEnableLoadMore="false"> @@ -27,6 +28,7 @@ android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" + android:overScrollMode="never" tools:listitem="@android:layout/simple_list_item_2"/> diff --git a/app/src/main/res/layout/fragment_refresh_using.xml b/app/src/main/res/layout/common_independence_recycler.xml similarity index 75% rename from app/src/main/res/layout/fragment_refresh_using.xml rename to app/src/main/res/layout/common_independence_recycler.xml index 77426ba9..a0c6ca85 100644 --- a/app/src/main/res/layout/fragment_refresh_using.xml +++ b/app/src/main/res/layout/common_independence_recycler.xml @@ -4,23 +4,24 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.fragment.RefreshUsingFragment"> + tools:context="com.scwang.refreshlayout.fragment.example.PureScrollExampleFragment"> + android:id="@+id/toolbar" + app:navigationIcon="?attr/homeAsUpIndicator" + app:title="@string/app_name"/> + app:srlEnablePureScrollMode="true"> diff --git a/app/src/main/res/layout/common_loading.xml b/app/src/main/res/layout/common_loading.xml new file mode 100644 index 00000000..d6bffc4a --- /dev/null +++ b/app/src/main/res/layout/common_loading.xml @@ -0,0 +1,19 @@ + + + + + diff --git a/app/src/main/res/layout/fragment_example_bottom_sheet.xml b/app/src/main/res/layout/fragment_example_bottom_sheet.xml new file mode 100644 index 00000000..71a26e37 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_bottom_sheet.xml @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_disallow_intercept.xml b/app/src/main/res/layout/fragment_example_disallow_intercept.xml new file mode 100644 index 00000000..482d2f60 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_disallow_intercept.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_emptylayout.xml b/app/src/main/res/layout/fragment_example_emptylayout.xml new file mode 100644 index 00000000..376cd93a --- /dev/null +++ b/app/src/main/res/layout/fragment_example_emptylayout.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_emptylayout_inner.xml b/app/src/main/res/layout/fragment_example_emptylayout_inner.xml new file mode 100644 index 00000000..1319ceb4 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_emptylayout_inner.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_emptylayout_outer.xml b/app/src/main/res/layout/fragment_example_emptylayout_outer.xml new file mode 100644 index 00000000..138853a9 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_emptylayout_outer.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_horizontal.xml b/app/src/main/res/layout/fragment_example_horizontal.xml new file mode 100644 index 00000000..b9da1407 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_horizontal.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_nestedscroll.xml b/app/src/main/res/layout/fragment_example_nestedscroll.xml new file mode 100644 index 00000000..9ac7f171 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_nestedscroll.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_example_nestedscroll_integral.xml b/app/src/main/res/layout/fragment_example_nestedscroll_integral.xml new file mode 100644 index 00000000..633f9131 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_nestedscroll_integral.xml @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_example_nestedscroll_view_pager.xml b/app/src/main/res/layout/fragment_example_nestedscroll_view_pager.xml new file mode 100644 index 00000000..de8b4a98 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_nestedscroll_view_pager.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_example_purescroll.xml b/app/src/main/res/layout/fragment_example_purescroll.xml new file mode 100644 index 00000000..80893ffa --- /dev/null +++ b/app/src/main/res/layout/fragment_example_purescroll.xml @@ -0,0 +1,29 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_purescroll_header.xml b/app/src/main/res/layout/fragment_example_purescroll_header.xml new file mode 100644 index 00000000..80ea2553 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_purescroll_header.xml @@ -0,0 +1,32 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_staggered_grid.xml b/app/src/main/res/layout/fragment_example_staggered_grid.xml new file mode 100644 index 00000000..4e761fdf --- /dev/null +++ b/app/src/main/res/layout/fragment_example_staggered_grid.xml @@ -0,0 +1,30 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_three_level.xml b/app/src/main/res/layout/fragment_example_three_level.xml new file mode 100644 index 00000000..55721cb3 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_three_level.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_example_viewpager.xml b/app/src/main/res/layout/fragment_example_viewpager.xml new file mode 100644 index 00000000..8a626816 --- /dev/null +++ b/app/src/main/res/layout/fragment_example_viewpager.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_flexbox_layout_manager.xml b/app/src/main/res/layout/fragment_flexbox_layout_manager.xml new file mode 100644 index 00000000..cc191211 --- /dev/null +++ b/app/src/main/res/layout/fragment_flexbox_layout_manager.xml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_no_more_data_example.xml b/app/src/main/res/layout/fragment_no_more_data_example.xml new file mode 100644 index 00000000..2becf806 --- /dev/null +++ b/app/src/main/res/layout/fragment_no_more_data_example.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_practice_instant.xml b/app/src/main/res/layout/fragment_practice_instant.xml new file mode 100644 index 00000000..4ae1df63 --- /dev/null +++ b/app/src/main/res/layout/fragment_practice_instant.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_practice_second_floor.xml b/app/src/main/res/layout/fragment_practice_second_floor.xml new file mode 100644 index 00000000..9931141c --- /dev/null +++ b/app/src/main/res/layout/fragment_practice_second_floor.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_practice_twolevel.xml b/app/src/main/res/layout/fragment_practice_twolevel.xml new file mode 100644 index 00000000..adaaaa7a --- /dev/null +++ b/app/src/main/res/layout/fragment_practice_twolevel.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_refresh_example.xml b/app/src/main/res/layout/fragment_refresh_example.xml new file mode 100644 index 00000000..8eed796f --- /dev/null +++ b/app/src/main/res/layout/fragment_refresh_example.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_refresh_practive.xml b/app/src/main/res/layout/fragment_refresh_practive.xml index b809589b..d3eef650 100644 --- a/app/src/main/res/layout/fragment_refresh_practive.xml +++ b/app/src/main/res/layout/fragment_refresh_practive.xml @@ -4,24 +4,32 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.fragment.RefreshStylesFragment"> + tools:context="com.scwang.refreshlayout.fragment.index.RefreshPracticeFragment"> + android:id="@id/toolbar" + app:title="@string/fragment_refresh_practice"/> - + app:srlEnableFooterTranslationContent="true" + app:srlPrimaryColor="@color/colorTextContent" + app:srlEnableAutoLoadMore="false"> + - + + diff --git a/app/src/main/res/layout/fragment_refresh_styles.xml b/app/src/main/res/layout/fragment_refresh_styles.xml index 2bca9bd0..ffa1c147 100644 --- a/app/src/main/res/layout/fragment_refresh_styles.xml +++ b/app/src/main/res/layout/fragment_refresh_styles.xml @@ -4,25 +4,34 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.scwang.refreshlayout.fragment.RefreshStylesFragment"> + tools:context="com.scwang.refreshlayout.fragment.index.RefreshStylesFragment"> - + app:srlPrimaryColor="@color/colorPrimary" + app:srlAccentColor="@android:color/white" + app:srlEnableLoadMore="true" + app:srlEnableAutoLoadMore="false" + app:srlEnablePreviewInEditMode="true"> + - - + + diff --git a/app/src/main/res/layout/item_example_snap_helper.xml b/app/src/main/res/layout/item_example_snap_helper.xml new file mode 100644 index 00000000..0a7c3454 --- /dev/null +++ b/app/src/main/res/layout/item_example_snap_helper.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_movie_banner.xml b/app/src/main/res/layout/item_movie_banner.xml new file mode 100644 index 00000000..cbd183b9 --- /dev/null +++ b/app/src/main/res/layout/item_movie_banner.xml @@ -0,0 +1,27 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_movie_header.xml b/app/src/main/res/layout/item_movie_header.xml new file mode 100644 index 00000000..8334d88a --- /dev/null +++ b/app/src/main/res/layout/item_movie_header.xml @@ -0,0 +1,11 @@ + + diff --git a/app/src/main/res/layout/item_movie_item.xml b/app/src/main/res/layout/item_movie_item.xml new file mode 100644 index 00000000..fd0a90ca --- /dev/null +++ b/app/src/main/res/layout/item_movie_item.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/item_practice_instant.xml b/app/src/main/res/layout/item_practice_instant.xml new file mode 100644 index 00000000..3dfc880b --- /dev/null +++ b/app/src/main/res/layout/item_practice_instant.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/listitem_practive_repast.xml b/app/src/main/res/layout/item_practice_repast.xml similarity index 81% rename from app/src/main/res/layout/listitem_practive_repast.xml rename to app/src/main/res/layout/item_practice_repast.xml index 701cf1c2..1c06c2f2 100644 --- a/app/src/main/res/layout/listitem_practive_repast.xml +++ b/app/src/main/res/layout/item_practice_repast.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="150dp" - android:background="@android:color/white" - android:layout_marginTop="@dimen/padding_common"> + android:background="@color/colorBackgroundDark" + android:paddingTop="@dimen/dimenPaddingCommon"> + android:padding="@dimen/dimenPaddingCommon"> @@ -40,7 +41,7 @@ android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="@dimen/padding_common_h" + android:layout_marginTop="@dimen/dimenPaddingHorizontal" android:textAppearance="@style/TextAppearance.AppCompat.Title" tools:text="香煎蛋果儿"/> diff --git a/app/src/main/res/layout/listitem_style_delivery.xml b/app/src/main/res/layout/item_style_delivery.xml similarity index 77% rename from app/src/main/res/layout/listitem_style_delivery.xml rename to app/src/main/res/layout/item_style_delivery.xml index 66027a21..6a648b7d 100644 --- a/app/src/main/res/layout/listitem_style_delivery.xml +++ b/app/src/main/res/layout/item_style_delivery.xml @@ -8,19 +8,19 @@ app:cardMaxElevation="2dp" android:layout_width="match_parent" android:layout_height="wrap_content" - tools:context="com.scwang.refreshlayout.activity.using.ListenerUsingActivity"> + tools:context="com.scwang.refreshlayout.activity.example.ListenerExampleActivity"> + android:padding="@dimen/dimenPaddingCommon"> + android:layout_marginEnd="@dimen/dimenPaddingCommon" + android:layout_marginRight="@dimen/dimenPaddingCommon"/> + android:layout_marginTop="@dimen/dimenPaddingCommon"/> + android:layout_marginTop="@dimen/dimenPaddingCommon"/> diff --git a/app/src/main/res/menu/navigation.xml b/app/src/main/res/menu/navigation.xml index a8a8d22f..92841cb0 100644 --- a/app/src/main/res/menu/navigation.xml +++ b/app/src/main/res/menu/navigation.xml @@ -12,8 +12,8 @@ android:title="@string/title_style" /> + android:title="@string/title_example"/> diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 00000000..c4a603d4 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 00000000..c4a603d4 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_item1.jpg b/app/src/main/res/mipmap-hdpi/ic_item1.jpg new file mode 100644 index 00000000..f3475465 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_item1.jpg differ diff --git a/app/src/main/res/mipmap-hdpi/ic_item2.jpg b/app/src/main/res/mipmap-hdpi/ic_item2.jpg new file mode 100644 index 00000000..a2acf192 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_item2.jpg differ diff --git a/app/src/main/res/mipmap-hdpi/ic_item3.jpg b/app/src/main/res/mipmap-hdpi/ic_item3.jpg new file mode 100644 index 00000000..7faed430 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_item3.jpg differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index 5a65eccc..060c07f9 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..23ad9e0f Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 9a078e3e..a9f9b7f0 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-hdpi/image_movie_header_12231501221682438.jpg b/app/src/main/res/mipmap-hdpi/image_movie_header_12231501221682438.jpg new file mode 100644 index 00000000..3bad74a6 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/image_movie_header_12231501221682438.jpg differ diff --git a/app/src/main/res/mipmap-hdpi/image_movie_header_12981501221820220.jpg b/app/src/main/res/mipmap-hdpi/image_movie_header_12981501221820220.jpg new file mode 100644 index 00000000..5b74a46f Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/image_movie_header_12981501221820220.jpg differ diff --git a/app/src/main/res/mipmap-hdpi/image_movie_header_48621499931969370.jpg b/app/src/main/res/mipmap-hdpi/image_movie_header_48621499931969370.jpg new file mode 100644 index 00000000..f0d329e3 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/image_movie_header_48621499931969370.jpg differ diff --git a/app/src/main/res/mipmap-hdpi/image_practice_profile.png b/app/src/main/res/mipmap-hdpi/image_practice_profile.png deleted file mode 100644 index cf23c214..00000000 Binary files a/app/src/main/res/mipmap-hdpi/image_practice_profile.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/image_weibo_home_1.png b/app/src/main/res/mipmap-hdpi/image_weibo_home_1.png deleted file mode 100644 index 0f098eba..00000000 Binary files a/app/src/main/res/mipmap-hdpi/image_weibo_home_1.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/skin_aio_more_normal.png b/app/src/main/res/mipmap-hdpi/skin_aio_more_normal.png new file mode 100644 index 00000000..75cfbd4c Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/skin_aio_more_normal.png differ diff --git a/app/src/main/res/mipmap-hdpi/skin_aio_more_pressed.png b/app/src/main/res/mipmap-hdpi/skin_aio_more_pressed.png new file mode 100644 index 00000000..6545858b Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/skin_aio_more_pressed.png differ diff --git a/app/src/main/res/mipmap-hdpi/skin_common_btn_blue_disabled.9.png b/app/src/main/res/mipmap-hdpi/skin_common_btn_blue_disabled.9.png new file mode 100644 index 00000000..433d007a Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/skin_common_btn_blue_disabled.9.png differ diff --git a/app/src/main/res/mipmap-hdpi/skin_messages_left_bubble.9.png b/app/src/main/res/mipmap-hdpi/skin_messages_left_bubble.9.png new file mode 100644 index 00000000..cc93742f Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/skin_messages_left_bubble.9.png differ diff --git a/app/src/main/res/mipmap-hdpi/skin_messages_left_bubble_highlighted.9.png b/app/src/main/res/mipmap-hdpi/skin_messages_left_bubble_highlighted.9.png new file mode 100644 index 00000000..fa269762 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/skin_messages_left_bubble_highlighted.9.png differ diff --git a/app/src/main/res/mipmap-hdpi/skin_messages_right_bubble.9.png b/app/src/main/res/mipmap-hdpi/skin_messages_right_bubble.9.png new file mode 100644 index 00000000..794bdf16 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/skin_messages_right_bubble.9.png differ diff --git a/app/src/main/res/mipmap-hdpi/skin_messages_right_bubble_highlighted.9.png b/app/src/main/res/mipmap-hdpi/skin_messages_right_bubble_highlighted.9.png new file mode 100644 index 00000000..217056ff Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/skin_messages_right_bubble_highlighted.9.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index 68f97ff5..ab643d8d 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..a9bfacc8 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index efc028a6..c21cf518 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-mdpi/image_second_floor.jpg b/app/src/main/res/mipmap-mdpi/image_second_floor.jpg new file mode 100644 index 00000000..0dd69894 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/image_second_floor.jpg differ diff --git a/app/src/main/res/mipmap-mdpi/image_second_floor_content.jpg b/app/src/main/res/mipmap-mdpi/image_second_floor_content.jpg new file mode 100644 index 00000000..9a8f7127 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/image_second_floor_content.jpg differ diff --git a/app/src/main/res/mipmap-mdpi/image_taobao.jpg b/app/src/main/res/mipmap-mdpi/image_taobao.jpg new file mode 100644 index 00000000..df891a88 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/image_taobao.jpg differ diff --git a/app/src/main/res/mipmap-mdpi/image_weibo_home_1.png b/app/src/main/res/mipmap-mdpi/image_weibo_home_1.png new file mode 100644 index 00000000..16fa91d9 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/image_weibo_home_1.png differ diff --git a/app/src/main/res/mipmap-hdpi/image_weibo_home_2.png b/app/src/main/res/mipmap-mdpi/image_weibo_home_2.png similarity index 100% rename from app/src/main/res/mipmap-hdpi/image_weibo_home_2.png rename to app/src/main/res/mipmap-mdpi/image_weibo_home_2.png diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 9dc79afc..62641a60 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..cec67c70 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 3af2608a..5083293a 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 0d6bfdc6..4e5a8b9b 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..e6795198 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 9bec2e62..42707ad3 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index d2e32e56..c506c734 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 00000000..951f160d Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 34947cd6..b89ca168 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/app/src/main/res/values-zh/arrays.xml b/app/src/main/res/values-zh/arrays.xml new file mode 100644 index 00000000..0fc60e41 --- /dev/null +++ b/app/src/main/res/values-zh/arrays.xml @@ -0,0 +1,40 @@ + + + + + 22,0,0,30, + 22,0,30,0, + 30,0,52,30, + 0,30,26,30, + 60,0,60,15, + 60,15,60,30, + 60,15,85,15, + 85,15,108,0, + 85,15,108,30, + 117,0,147,0, + 147,0,177,0, + 147,0,147,32, + 198,0,176,30, + 198,0,206,0, + 206,0,228,30, + 176,30,202,30, + + + + 0,35,12,42, + 12,42,24,35, + 24,35,12,28, + 0,35,12,28, + 0,21,12,28, + 12,28,24,21, + 24,35,24,21, + 24,21,12,14, + 0,21,12,14, + 0,21,0,7, + 12,14,0,7, + 12,14,24,7, + 24,7,12,0, + 0,7,12,0, + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml new file mode 100644 index 00000000..20732f6c --- /dev/null +++ b/app/src/main/res/values-zh/strings.xml @@ -0,0 +1,188 @@ + + 智能刷新 + + 样式 + 使用 + 实战 + + 未选择 + 已选地区 + + 风格展示 + 使用示例 + 实战 + + Refresh + + 餐饮美食 + 个人中心 + Github + 微博列表 + 滚动广告 + 微博主页 + QQ浏览器 + + 全屏水滴 + 官方主题 + 苹果水滴 + 金色校园 + 冲上云霄 + 贝塞尔雷达 + 经典风格 + 弹出圆圈 + 战争城市 + 打砖块 + StoreHouse + 掉落盒子 + 气球快递 + 纸飞机 + + 基本使用 + 全局默认 + XML配置 + java代码设置 + 越界回弹 + 多功能监听器 + 自定义Header + SnapHelper + 国际化 + + 没有更多数据 + 水平滚动模式 + 纯滚动模式 + 纯滚动模式-单独指定Header + 空页面 + 空页面-内部嵌套 + 空页面-外部嵌套 + 嵌套滚动 + 嵌套滚动-整体嵌套 + ViewPager + 三级刷新 + Bottom Sheet 对话框 + Flexbox Layout 管理器 + 禁止拦截 + 瀑布流 + + 即时通讯 + + 基本的使用 + 没有更多数据的使用 + 使用指定的Header和Footer + 整合空页面 + 嵌套Layout作为内容 + 嵌套滚动使用 + 纯滚动模式 + 多功能监听器 + 自定义Header + 国际化支持 + 结合 SnapHelper 使用 + ViewPager 多页面共用一个 RefreshLayout + BottomSheet内部使用加载更多 + 三级刷新 + 结合 FlexboxLayoutManager 使用 + 水平滚动刷新 + requestDisallowInterceptTouchEvent + StaggeredGridLayoutManager 的使用 + + 餐饮美食-简单自定义Header-外边距magin + 个人中心-PureScrollMode-纯滚动模式 + 网页引用-WebView + 微博列表-智能识别 + 微博主页-MultiPurposeListener + 滚动广告-Banner + QQ浏览器-模拟QQ浏览器内核提示 + 二级刷新-仿淘宝二楼 + 即时通讯 + + 更改为橙色主题颜色 + 更改为红色主题颜色 + 更改为绿色主题颜色 + 更改为蓝色主题颜色 + 下拉的时候列表内容停留在原位不动 + 下拉的时候列表内容跟随向下偏移 + 打开左右拖动效果 + 关闭左右拖动效果 + 下拉的时候Header的高度跟随变大 + 下拉的时候Header的位置向下偏移 + 下拉的时候Header固定在背后 + 开启显示上次更新功能 + 关闭显示上次更新功能 + 更改为默认主题颜色 + 上拉加载更多 + 下拉的时候绘制贝塞尔曲线背景 + 下拉的时候不绘制贝塞尔曲线背景 + 展开AppBarLayout,变成可伸展头部的页面 + 折叠AppBarLayout,变成正常的列表页面 + 跟换显示符号为英文 + 跟换显示符号为中文 + 跟换显示符号为图标 + 跟换显示符号为商标 + + 第%02d条数据 + 这是测试的第%02d条数据 + 左边 + 右边 + + 跟随系统 + 中文 + 英语 + 点击切换语言为 %s + + 网页由 github.com 提供\n已启用QQ浏览器X5内核 + + 这是使用定制Header和Footer的第一种方法-全局默认\n\n + 本方法是实际项目中最常用的方法,其特点有:\n\n + 1.设置一次全部生效,不用多次写重复的代码\n + 2.优先级最低,在特别页面可以轻松的覆盖替换\n\n + 使用方法: \n + //设置全局的Header构建器 \n + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {\n + public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {\n + return new ClassicsHeader(context);//指定为经典Header,默认是 贝塞尔雷达Header\n + }\n + });\n + //设置全局的Footer构建器\n + SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {\n + public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {\n + return new ClassicsFooter(context);//指定为经典Footer,默认是 BallPulseFooter\n + }\n + });\n\n + 关键代码,需要在布局生成之前设置,建议代码放在 Application.onCreate 中 + + \n + \t\n + \t\n + \t\n + \n + ]]> + 这是使用定制Header和Footer的第三种方法-代码设置\n\n + 本方法是实际项目中比较少用的方法,其特点有:\n\n + 1.设置一次生效一次,需要多处设置,建议特别的页面使用\n + 2.优先级最高,即使使用了会覆盖方法一和方法二的设置\n\n + 使用方法: \n + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout);\n + //设置 Header 为 Material风格\n + refreshLayout.setRefreshHeader(new MaterialHeader(this));\n + //设置 Footer 为 三球动画\n + refreshLayout.setRefreshFooter(new BallPulseFooter(this));\n\n + + + 输入消息 + 发送 + 加载更多时显示新内容 + + diff --git a/app/src/main/res/values-zh/strings_srl.xml b/app/src/main/res/values-zh/strings_srl.xml new file mode 100644 index 00000000..7a77fe81 --- /dev/null +++ b/app/src/main/res/values-zh/strings_srl.xml @@ -0,0 +1,20 @@ + + + \@下拉刷新 + \@正在刷新… + \@正在加载… + \@释放刷新 + \@刷新完成 + \@刷新失败 + \@上次更新 M-d HH:mm + \@进入二楼 + + \@上拉加载 + \@释放加载 + \@正在加载… + \@正在刷新… + \@加载完成 + \@加载失败 + \@没有更多数据了 + + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml new file mode 100644 index 00000000..0fc60e41 --- /dev/null +++ b/app/src/main/res/values/arrays.xml @@ -0,0 +1,40 @@ + + + + + 22,0,0,30, + 22,0,30,0, + 30,0,52,30, + 0,30,26,30, + 60,0,60,15, + 60,15,60,30, + 60,15,85,15, + 85,15,108,0, + 85,15,108,30, + 117,0,147,0, + 147,0,177,0, + 147,0,147,32, + 198,0,176,30, + 198,0,206,0, + 206,0,228,30, + 176,30,202,30, + + + + 0,35,12,42, + 12,42,24,35, + 24,35,12,28, + 0,35,12,28, + 0,21,12,28, + 12,28,24,21, + 24,35,24,21, + 24,21,12,14, + 0,21,12,14, + 0,21,0,7, + 12,14,0,7, + 12,14,24,7, + 24,7,12,0, + 0,7,12,0, + + + \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml new file mode 100644 index 00000000..1220cb47 --- /dev/null +++ b/app/src/main/res/values/attrs.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 6d4568d5..299c0c07 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -9,8 +9,8 @@ #444444 #888888 - #FFFFFF - #f2f2f2 - #33aaaaaa + #FFFFFF + #f2f2f2 + #33aaaaaa diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 8fc822cc..fc2f8d14 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -9,10 +9,15 @@ 0.5dp - 10dp - 15dp - 10dp - 5dp + 2.5dp + 5dp + 10dp + 10dp + 12.5dp + 15dp + 20dp + 25dp + 12sp 14sp @@ -21,4 +26,13 @@ 19sp 20sp + 10sp + 12sp + 14sp + 16sp + 17sp + 19sp + 20sp + 14sp + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 23c94eef..e22804be 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,61 +1,156 @@ - SmartRefreshLayout - Settings - Settings + SmartRefresh - + Style + Example + Practice + + unselected + selected area + + Styles + Examples + Practice - FlyRefresh Refresh - 风格 - 使用 - 实战 - 未选择 - 已选地区 - - 风格展示 - 使用示例 - 实战 - 全屏水波 - 官方主题 - 苹果水滴 - 金色校园 - 冲上云霄 - 贝塞尔雷达 - 经典风格 - 弹出圆圈 - 战争城市 - 打砖块 - StoreHouse - 基本使用 - 全局默认 - XML配置 - java代码设置 - 这是使用定制Header和Footer的第一种方法-全局默认\n\n - 本方法是实际项目中最常用的方法,起特点有:\n\n - 1.设置一次全部生效,不用多次写重复的代码\n - 2.优先级最低,在特别页面可以轻松的覆盖替换\n\n - 使用方法: \n - //设置全局的Header构建器 \n - SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() {\n + + Restaurant + Profile + Github + Feed List + Banner + Weibo Home + QQ Browser + + WaveSwipeHeader + MaterialHeader + WaterDropHeader + PhoenixHeader + TaurusHeader + BezierRadarHeader + ClassicsHeader + BezierCircleHeader + FunGameBattleCityHeader + FunGameHitBlockHeader + StoreHouseHeader + DropBoxHeader + DeliveryHeader + FlyRefreshHeader + + General Example + Global Default + Specified In XML + Specified In Java + Cross-border springBack + Multifunction monitor + Custom Header + SnapHelper + I18N + + No More Data + Horizontal Scroll Mode + Pure Rolling Mode + Pure Rolling Mode - Header Only + Empty Layout + Empty Layout - Nested Inside + Empty Layout - Nested Outside + Nested Scrolling + Nested Scrolling - Whole Nested + ViewPager + Three Level Refresh + Bottom Sheet + FlexBox Layout Manager + Disallow Intercept + Staggered Grid + + + Instant + + Simple customization header, HeaderInsetStart + Pure scroll mode + Use WebView + Intelligent identification + MultiPurposeListener + Use banner + Imitate QQ browser + Imitate the second floor of "Treasure Prospecting" + Instant Messaging + + + The basic usage of refresh layout + Specify the style of Header and Footer + The usage of no more data + The usage of empty pages + Use Layout as content + The usage of nested scroll + The usage of pure rolling mode + The usage of multifunction listener + The usage of custom Header + The usage of I18n + The usage of SnapHelper + The usage of ViewPager + The usage of BottomSheet + The usage of three level refresh + The usage of FlexboxLayoutManager + The usage of Horizontal Scroll + The usage of requestDisallowInterceptTouchEvent + The usage of StaggeredGridLayoutManager + + Change theme to orange color + Change theme to red color + Change theme to green color + Change theme to blue color + Change theme to default color + The content stays where it is when it is pulled down + The content follow the downward migration when pulling down + Open left and right drag effect + Close the left and right drag effect + The height of the Header is larger when you pull down + The Header\'s position is shifted down when you pull down + The Header is fixed behind the back when you pull down + Open display last update function + The shutdown shows the last update function + The top pull loads more + Draw the background of bezier curve when pulling down + Don\'t draw the background of bezier curve when pulling down + Expand the AppBarLayout + Collapse the AppBarLayout + And change the display symbol in English + The display symbol is Chinese + Follow the display symbol for ICONS + It is a trademark for the display symbol + + Item %02d + This is the abstract item %02d + Left Pager + Right Pager + + System + Chinese + English + Click to switch the language to %s + + The web page is provided by github.com.\nThe QQ browser X5 kernel has been enabled. + + \n + Usage: \n + SmartRefreshLayout.setDefaultRefreshHeaderCreator(new DefaultRefreshHeaderCreator() {\n public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {\n - return new ClassicsHeader(context);//指定为经典Header,默认是 贝塞尔雷达Header\n + return new ClassicsHeader(context);\n }\n });\n - //设置全局的Footer构建器\n - SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() {\n + SmartRefreshLayout.setDefaultRefreshFooterCreator(new DefaultRefreshFooterCreator() {\n public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {\n - return new ClassicsFooter(context);//指定为经典Footer,默认是 BallPulseFooter\n + return new ClassicsFooter(context);\n }\n });\n\n - 关键代码,需要在布局生成之前设置,建议代码放在 Application.onCreate 中 + The key code needs to be set before the layout is generated and the recommended code is placed in the "Application.onCreate". - \n @@ -70,24 +165,19 @@ \t\tandroid:layout_height="wrap_content"/>\n \n ]]> - 这是使用定制Header和Footer的第三种方法-代码设置\n\n - 本方法是实际项目中比较少用的方法,起特点有:\n\n - 1.设置一次生效一次,需要多处设置,建议特别的页面使用\n - 2.优先级最高,即使使用了会覆盖方法一和方法二的设置\n\n - 使用方法: \n - final RefreshLayout refreshLayout = (RefreshLayout) findViewById(R.id.refreshLayout);\n - //设置 Header 为 Material风格\n + \n + Usage: \n + final RefreshLayout refreshLayout = findViewById(R.id.refreshLayout);\n refreshLayout.setRefreshHeader(new MaterialHeader(this));\n - //设置 Footer 为 三球动画\n refreshLayout.setRefreshFooter(new BallPulseFooter(this));\n\n - 多功能监听器 - 掉落盒子 - 气球快递 - 纸飞机 - 餐饮美食 - 个人中心 - 越界回弹 - Github - 微博列表 + + input message + Send + Scroll Content + + + Hello blank fragment + + diff --git a/app/src/main/res/values/strings_srl.xml b/app/src/main/res/values/strings_srl.xml new file mode 100644 index 00000000..a23cde1c --- /dev/null +++ b/app/src/main/res/values/strings_srl.xml @@ -0,0 +1,20 @@ + + + Pull Down To Refresh + Refreshing… + Wait For Loading… + Release To Refresh + Refresh Finished + Refresh Failed + \'Last Update\' M-d HH:mm + Release To Second Floor + + Pull Up To Load More + Release To Load More + Loading… + Wait For Refreshing… + Load More Finished + Load More Failed + No More Data + + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index dece2ea9..f5aafa52 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -9,6 +9,20 @@ @dimen/division_line @drawable/ic_list_divider @drawable/ic_arrow_back_white_24dp + @style/LoadingLayoutStyle + + + + + + + + + + - - @@ -61,10 +75,10 @@ - @@ -127,18 +141,18 @@ - + + \ No newline at end of file diff --git a/refresh-layout-kernel/src/main/res/values/ids.xml b/refresh-layout-kernel/src/main/res/values/ids.xml new file mode 100644 index 00000000..fc2249e7 --- /dev/null +++ b/refresh-layout-kernel/src/main/res/values/ids.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/refresh-layout-kernel/src/main/res/values/strings.xml b/refresh-layout-kernel/src/main/res/values/strings.xml new file mode 100644 index 00000000..3f388b1a --- /dev/null +++ b/refresh-layout-kernel/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + The content view in SmartRefreshLayout is empty. Do you forget to add it in xml layout file? + %s falsify area,\n Represents the height[%.1fdp] of drag at run time,\n It does not show anything. + diff --git a/refresh-layout-kernel/src/test/java/com/scwang/smartrefresh/layout/ExampleUnitTest.java b/refresh-layout-kernel/src/test/java/com/scwang/smartrefresh/layout/ExampleUnitTest.java new file mode 100644 index 00000000..1bc7ef8a --- /dev/null +++ b/refresh-layout-kernel/src/test/java/com/scwang/smartrefresh/layout/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.scwang.smartrefresh.layout; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() throws Exception { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/refresh-layout/build.gradle b/refresh-layout/build.gradle index 5940637b..200c215d 100644 --- a/refresh-layout/build.gradle +++ b/refresh-layout/build.gradle @@ -1,14 +1,13 @@ apply plugin: 'com.android.library' -apply plugin: 'com.novoda.bintray-release' -//apply plugin: 'me.tatarka.retrolambda' +//apply plugin: 'com.novoda.bintray-release' android { - compileSdkVersion 25 - buildToolsVersion "25.0.3" + + compileSdkVersion 28 defaultConfig { - minSdkVersion 12 - targetSdkVersion 25 + minSdkVersion 16 + targetSdkVersion 28 versionCode 1 versionName "1.0" @@ -27,21 +26,26 @@ android { } dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { + implementation fileTree(dir: 'libs', include: ['*.jar']) + androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) - provided 'com.android.support:appcompat-v7:25.3.1' - provided 'com.android.support:design:25.3.1' - provided 'com.android.support:recyclerview-v7:25.3.1' - testCompile 'junit:junit:4.12' -} + testImplementation 'junit:junit:4.12' -publish { - userOrg = 'scwang90' - groupId = 'com.scwang.smartrefresh' - artifactId = 'SmartRefreshLayout' - version = '1.0.2-alpha-8' - description = 'An intelligent refresh layout' - website = "https://github.com/scwang90/${rootProject.name}" -} \ No newline at end of file + compileOnly 'com.android.support:design:28.0.0' + compileOnly project(':refresh-layout-kernel') + compileOnly project(':refresh-footer-ball') + compileOnly project(':refresh-header-falsify') + compileOnly project(':refresh-header-radar') + compileOnly project(':refresh-header-two-level') + +} +// +//publish { +// userOrg = SMART_USER +// groupId = 'com.scwang.smartrefresh' +// artifactId = 'SmartRefreshLayout' +// publishVersion = SMART_VERSION +// desc = 'An intelligent refresh layout' +// website = "https://github.com/scwang90/${rootProject.name}" +//} diff --git a/refresh-layout/src/main/AndroidManifest.xml b/refresh-layout/src/main/AndroidManifest.xml index 95c5c97a..3d274dd7 100644 --- a/refresh-layout/src/main/AndroidManifest.xml +++ b/refresh-layout/src/main/AndroidManifest.xml @@ -1,10 +1,9 @@ - - + + + diff --git a/refresh-layout/src/main/java/android/support/v4/view/PagerAdapterWrapper.java b/refresh-layout/src/main/java/android/support/v4/view/PagerAdapterWrapper.java deleted file mode 100644 index d82854d9..00000000 --- a/refresh-layout/src/main/java/android/support/v4/view/PagerAdapterWrapper.java +++ /dev/null @@ -1,130 +0,0 @@ -package android.support.v4.view; - -import android.database.DataSetObserver; -import android.os.Parcelable; -import android.view.View; -import android.view.ViewGroup; - -@SuppressWarnings("deprecation") -public class PagerAdapterWrapper extends PagerAdapter { - - protected PagerAdapter wrapped = null; - - public PagerAdapterWrapper(PagerAdapter wrapped) { - this.wrapped = wrapped; - } - - public void attachViewPager(ViewPager viewPager) { - viewPager.mAdapter = this; - } - - @Override - protected void setViewPagerObserver(DataSetObserver observer) { - super.setViewPagerObserver(observer); - } - - @Override - public int getCount() { - return wrapped.getCount(); - } - - @Override - public void startUpdate(ViewGroup container) { - wrapped.startUpdate(container); - } - - @Override - public Object instantiateItem(ViewGroup container, int position) { - return wrapped.instantiateItem(container, position); - } - - @Override - public void destroyItem(ViewGroup container, int position, Object object) { - wrapped.destroyItem(container, position, object); - } - - @Override - public void setPrimaryItem(ViewGroup container, int position, Object object) { - wrapped.setPrimaryItem(container, position, object); - } - - @Override - public void finishUpdate(ViewGroup container) { - wrapped.finishUpdate(container); - } - - @Override - @Deprecated - public void startUpdate(View container) { - wrapped.startUpdate(container); - } - - @Override - @Deprecated - public Object instantiateItem(View container, int position) { - return wrapped.instantiateItem(container, position); - } - - @Override - @Deprecated - public void destroyItem(View container, int position, Object object) { - wrapped.destroyItem(container, position, object); - } - - @Override - @Deprecated - public void setPrimaryItem(View container, int position, Object object) { - wrapped.setPrimaryItem(container, position, object); - } - - @Override - @Deprecated - public void finishUpdate(View container) { - wrapped.finishUpdate(container); - } - - @Override - public boolean isViewFromObject(View view, Object object) { - return wrapped.isViewFromObject(view, object); - } - - @Override - public Parcelable saveState() { - return wrapped.saveState(); - } - - @Override - public void restoreState(Parcelable state, ClassLoader loader) { - wrapped.restoreState(state, loader); - } - - @Override - public int getItemPosition(Object object) { - return wrapped.getItemPosition(object); - } - - @Override - public void notifyDataSetChanged() { - wrapped.notifyDataSetChanged(); - } - - @Override - public void registerDataSetObserver(DataSetObserver observer) { - wrapped.registerDataSetObserver(observer); - } - - @Override - public void unregisterDataSetObserver(DataSetObserver observer) { - wrapped.unregisterDataSetObserver(observer); - } - - @Override - public CharSequence getPageTitle(int position) { - return wrapped.getPageTitle(position); - } - - @Override - public float getPageWidth(int position) { - return wrapped.getPageWidth(position); - } -} \ No newline at end of file diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/SmartRefreshLayout.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/SmartRefreshLayout.java index 4e5fdfc9..84952e71 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/SmartRefreshLayout.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/SmartRefreshLayout.java @@ -1,2270 +1,284 @@ package com.scwang.smartrefresh.layout; -import android.animation.Animator; -import android.animation.Animator.AnimatorListener; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.annotation.SuppressLint; import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.os.Build; -import android.support.annotation.ColorRes; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.annotation.RequiresApi; -import android.support.v4.content.ContextCompat; -import android.support.v4.view.MotionEventCompat; -import android.support.v4.view.NestedScrollingChild; -import android.support.v4.view.NestedScrollingChildHelper; -import android.support.v4.view.NestedScrollingParent; -import android.support.v4.view.NestedScrollingParentHelper; -import android.support.v4.view.ScrollingView; -import android.support.v4.view.ViewCompat; -import android.support.v4.view.ViewPager; import android.util.AttributeSet; -import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.view.animation.DecelerateInterpolator; -import android.view.animation.Interpolator; -import android.webkit.WebView; -import android.widget.AbsListView; -import android.widget.ScrollView; -import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreater; -import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreater; -import com.scwang.smartrefresh.layout.api.RefreshContent; +import com.scwang.smart.refresh.header.ClassicsHeader; +import com.scwang.smartrefresh.layout.api.DefaultRefreshFooterCreator; +import com.scwang.smartrefresh.layout.api.DefaultRefreshHeaderCreator; +import com.scwang.smartrefresh.layout.api.DefaultRefreshInitializer; import com.scwang.smartrefresh.layout.api.RefreshFooter; import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshKernel; import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.api.RefreshScrollBoundary; -import com.scwang.smartrefresh.layout.constant.DimensionStatus; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.api.ScrollBoundaryDecider; import com.scwang.smartrefresh.layout.footer.BallPulseFooter; import com.scwang.smartrefresh.layout.header.BezierRadarHeader; -import com.scwang.smartrefresh.layout.header.FalsifyHeader; -import com.scwang.smartrefresh.layout.impl.RefreshContentWrapper; -import com.scwang.smartrefresh.layout.impl.RefreshFooterWrapper; -import com.scwang.smartrefresh.layout.impl.RefreshHeaderWrapper; -import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; import com.scwang.smartrefresh.layout.listener.OnMultiPurposeListener; import com.scwang.smartrefresh.layout.listener.OnRefreshListener; -import com.scwang.smartrefresh.layout.listener.OnRefreshLoadmoreListener; -import com.scwang.smartrefresh.layout.util.DensityUtil; -import com.scwang.smartrefresh.layout.util.ViscousFluidInterpolator; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; +import com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener; -import static android.view.View.MeasureSpec.AT_MOST; -import static android.view.View.MeasureSpec.EXACTLY; -import static android.view.View.MeasureSpec.getSize; -import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static com.scwang.smartrefresh.layout.util.DensityUtil.dp2px; -import static java.lang.System.currentTimeMillis; /** * 智能刷新布局 - * Intelligent Refreshlayout - * Created by SCWANG on 2017/5/26. + * Intelligent RefreshLayout + * Created by scwang on 2017/5/26. */ -@SuppressWarnings({"unused","WeakerAccess"}) -public class SmartRefreshLayout extends ViewGroup implements RefreshLayout { +@SuppressLint("RestrictedApi") +@SuppressWarnings({"unused"}) +public class SmartRefreshLayout extends com.scwang.smart.refresh.layout.SmartRefreshLayout implements RefreshLayout { - // - - protected RefreshState mState = RefreshState.None; - - // - protected int mTouchSlop; - protected int mSpinner; - protected int mReboundDuration = 250; - protected int mScreenHeightPixels; - protected float mTouchX; - protected float mTouchY; - protected float mDragRate = .5f; - protected float mInitialMotionY; - protected Interpolator mReboundInterpolator; - protected View mFixedHeaderView;//固定在头部的视图 - protected View mFixedFooterView;//固定在底部的视图 - protected int mFixedHeaderViewId;//固定在头部的视图Id - protected int mFixedFooterViewId;//固定在头部的视图Id - // - - // - protected int[] mPrimaryColors; - protected boolean mEnableRefresh = true; - protected boolean mEnableLoadmore = true; - protected boolean mDisableContentWhenRefresh = false;//是否开启在刷新时候禁止操作内容视图 - protected boolean mDisableContentWhenLoading = false;//是否开启在刷新时候禁止操作内容视图 - protected boolean mEnableHeaderTranslationContent = true;//是否启用内容视图拖动效果 - protected boolean mEnableFooterTranslationContent = true;//是否启用内容视图拖动效果 - protected boolean mEnablePreviewInEditMode = true;//是否在编辑模式下开启预览功能 - protected boolean mEnableOverScrollBounce = true;//是否启用越界回弹 - protected boolean mEnableAutoLoadmore = true;//是否在列表滚动到底部时自动加载更多 - protected boolean mEnablePureScrollMode = false;//是否开启纯滚动模式 - protected boolean mEnableScrollContentWhenLoaded = true;//是否在加载更多完成之后滚动内容显示新数据 - protected boolean mLoadmoreFinished = false;//数据是否全部加载完成,如果完成就不能在触发加载事件 - // - - // - protected OnRefreshListener mRefreshListener; - protected OnLoadmoreListener mLoadmoreListener; - protected OnMultiPurposeListener mOnMultiPurposeListener; - // - - // - protected int[] mParentScrollConsumed = new int[2]; - protected int[] mParentOffsetInWindow = new int[2]; - protected int mTotalUnconsumed; - protected boolean mNestedScrollInProgress; - protected NestedScrollingChildHelper mNestedScrollingChildHelper; - protected NestedScrollingParentHelper mNestedScrollingParentHelper; - // - - protected RefreshKernel mKernel; - - // - /** - * 头部高度 - */ - protected int mHeaderHeight; - protected DimensionStatus mHeaderHeightStatus = DimensionStatus.DefaultUnNotify; - /** - * 底部高度 - */ - protected int mFooterHeight; - protected DimensionStatus mFooterHeightStatus = DimensionStatus.DefaultUnNotify; - - /** - * 扩展高度 - */ - protected int mHeaderExtendHeight; - /** - * 扩展高度 - */ - protected int mFooterExtendHeight; - /** - * 最大拖动比率(最大高度/Header高度) - */ - protected float mHeaderMaxDragRate = 2.0f; - /** - * 最大拖动比率(最大高度/Footer高度) - */ - protected float mFooterMaxDragRate = 3.0f; - /** - * 下拉头部视图 - */ - protected RefreshHeader mRefreshHeader; - /** - * 显示内容视图 - */ - protected RefreshContent mRefreshContent; - /** - * 上拉底部视图 - */ - protected RefreshFooter mRefreshFooter; - // - - protected static DefaultRefreshFooterCreater mFooterCreater = new DefaultRefreshFooterCreater() { - @NonNull - @Override - public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) { - return new BallPulseFooter(context); - } - }; - protected static DefaultRefreshHeaderCreater mHeaderCreater = new DefaultRefreshHeaderCreater() { - @NonNull - @Override - public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) { - return new BezierRadarHeader(context); - } - }; - - protected long mLastLoadingTime = 0; - protected long mLastRefreshingTime = 0; - - protected Paint mPaint; - protected int mHeaderBackgroundColor = 0; - protected int mFooterBackgroundColor = 0; - - // - - // - public SmartRefreshLayout(Context context) { - super(context); - this.initView(context, null); - } - - public SmartRefreshLayout(Context context, AttributeSet attrs) { - super(context, attrs); - this.initView(context, attrs); - } - - public SmartRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - this.initView(context, attrs); - } - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - public SmartRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - this.initView(context, attrs); - } - - private void initView(Context context, AttributeSet attrs) { - setClipToPadding(false); - - mScreenHeightPixels = context.getResources().getDisplayMetrics().heightPixels; - mReboundInterpolator = new ViscousFluidInterpolator(); - mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); - - mNestedScrollingParentHelper = new NestedScrollingParentHelper(this); - mNestedScrollingChildHelper = new NestedScrollingChildHelper(this); - - DensityUtil density = new DensityUtil(); - TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SmartRefreshLayout); - - ViewCompat.setNestedScrollingEnabled(this, ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableNestedScrolling, true)); - mDragRate = ta.getFloat(R.styleable.SmartRefreshLayout_srlDragRate, mDragRate); - mHeaderMaxDragRate = ta.getFloat(R.styleable.SmartRefreshLayout_srlHeaderMaxDragRate, mHeaderMaxDragRate); - mFooterMaxDragRate = ta.getFloat(R.styleable.SmartRefreshLayout_srlFooterMaxDragRate, mFooterMaxDragRate); - mEnableRefresh = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableRefresh, mEnableRefresh); - mReboundDuration = ta.getInt(R.styleable.SmartRefreshLayout_srlReboundDuration, mReboundDuration); - mEnableLoadmore = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableLoadmore, mEnableLoadmore); - mHeaderHeight = ta.getDimensionPixelOffset(R.styleable.SmartRefreshLayout_srlHeaderHeight, density.dip2px(100)); - mFooterHeight = ta.getDimensionPixelOffset(R.styleable.SmartRefreshLayout_srlFooterHeight, density.dip2px(60)); - mDisableContentWhenRefresh = ta.getBoolean(R.styleable.SmartRefreshLayout_srlDisableContentWhenRefresh, mDisableContentWhenRefresh); - mDisableContentWhenLoading = ta.getBoolean(R.styleable.SmartRefreshLayout_srlDisableContentWhenLoading, mDisableContentWhenLoading); - mEnableHeaderTranslationContent = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableHeaderTranslationContent, mEnableHeaderTranslationContent); - mEnableFooterTranslationContent = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableFooterTranslationContent, mEnableFooterTranslationContent); - mEnablePreviewInEditMode = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnablePreviewInEditMode, mEnablePreviewInEditMode); - mEnableAutoLoadmore = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableAutoLoadmore, mEnableAutoLoadmore); - mEnableOverScrollBounce = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableAutoLoadmore, mEnableOverScrollBounce); - mEnablePureScrollMode = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnablePureScrollMode, mEnablePureScrollMode); - mEnableScrollContentWhenLoaded = ta.getBoolean(R.styleable.SmartRefreshLayout_srlEnableScrollContentWhenLoaded, mEnableScrollContentWhenLoaded); - mFixedHeaderViewId = ta.getResourceId(R.styleable.SmartRefreshLayout_srlFixedHeaderViewId, View.NO_ID); - mFixedFooterViewId = ta.getResourceId(R.styleable.SmartRefreshLayout_srlFixedFooterViewId, View.NO_ID); - - mFooterExtendHeight = (int) Math.max((mFooterHeight * (mHeaderMaxDragRate - 1)), 0); - mHeaderExtendHeight = (int) Math.max((mHeaderHeight * (mHeaderMaxDragRate - 1)), 0); - - if (ta.hasValue(R.styleable.SmartRefreshLayout_srlHeaderHeight)) { - mHeaderHeightStatus = DimensionStatus.XmlLayoutUnNotify; - } - if (ta.hasValue(R.styleable.SmartRefreshLayout_srlFooterHeight)) { - mFooterHeightStatus = DimensionStatus.XmlLayoutUnNotify; - } - - int accentColor = ta.getColor(R.styleable.SmartRefreshLayout_srlAccentColor, 0); - int primaryColor = ta.getColor(R.styleable.SmartRefreshLayout_srlPrimaryColor, 0); - if (primaryColor != 0 ) { - if (accentColor != 0) { - mPrimaryColors = new int[]{primaryColor, accentColor}; - } else { - mPrimaryColors = new int[]{primaryColor}; - } - } - - ta.recycle(); - - } - // - - // - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - final int count = getChildCount(); - if (count > 3) { - throw new RuntimeException("最多只支持3个子View,Most only support three sub view"); - } else if (mEnablePureScrollMode && count > 1) { - throw new RuntimeException("PureScrollMode模式只支持一个子View,Most only support one sub view in PureScrollMode"); - } - - //定义为确认的子View索引 - boolean[] uncertains = new boolean[count]; - //第一次查找确认的 子View - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view instanceof RefreshHeader && mRefreshHeader == null) { - mRefreshHeader = ((RefreshHeader) view); - } else if (view instanceof RefreshFooter && mRefreshFooter == null) { - mRefreshFooter = ((RefreshFooter) view); - } else if (mRefreshContent == null && ( view instanceof AbsListView - || view instanceof WebView - || view instanceof ScrollView - || view instanceof ScrollingView - || view instanceof NestedScrollingChild - || view instanceof NestedScrollingParent - || view instanceof ViewPager)) { - mRefreshContent = new RefreshContentWrapper(view); - } else if (RefreshHeaderWrapper.isTagedHeader(view) && mRefreshHeader == null) { - mRefreshHeader = new RefreshHeaderWrapper(view); - } else if (RefreshFooterWrapper.isTagedFooter(view) && mRefreshFooter == null) { - mRefreshFooter = new RefreshFooterWrapper(view); - } else if (RefreshContentWrapper.isTagedContent(view) && mRefreshContent == null) { - mRefreshContent = new RefreshContentWrapper(view); - } else { - uncertains[i] = true;//标记未确认 - } - } - //如果有 未确认(uncertains)的子View 通过智能算法计算 - for (int i = 0; i < count; i++) { - if (uncertains[i]) { - View view = getChildAt(i); - if (count == 1 && mRefreshContent == null) { - mRefreshContent = new RefreshContentWrapper(view); - } else if (i == 0 && mRefreshHeader == null) { - mRefreshHeader = new RefreshHeaderWrapper(view); - } else if (count == 2 && mRefreshContent == null) { - mRefreshContent = new RefreshContentWrapper(view); - } else if (i == 2 && mRefreshFooter == null) { - mRefreshFooter = new RefreshFooterWrapper(view); - } else if (mRefreshContent == null) { - mRefreshContent = new RefreshContentWrapper(view); - } - } - } - - if (isInEditMode()) { - if (mPrimaryColors != null) { - if (mRefreshHeader != null) { - mRefreshHeader.setPrimaryColors(mPrimaryColors); - } - if (mRefreshFooter != null) { - mRefreshFooter.setPrimaryColors(mPrimaryColors); - } - } - - //重新排序 - bringChildToFront(mRefreshContent.getView()); - if (mRefreshHeader != null && mRefreshHeader.getSpinnerStyle() != SpinnerStyle.FixedBehind) { - bringChildToFront(mRefreshHeader.getView()); - } - if (mRefreshFooter != null && mRefreshFooter.getSpinnerStyle() != SpinnerStyle.FixedBehind) { - bringChildToFront(mRefreshFooter.getView()); - } - - if (mKernel == null) { - mKernel = new RefreshKernelImpl(); - } - } - - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (isInEditMode()) return; - - if (mRefreshContent == null - && mRefreshHeader == null - && mRefreshFooter == null) { - onFinishInflate(); - } - - if (mKernel == null) { - mKernel = new RefreshKernelImpl(); - } - - if (mRefreshContent == null) { - for (int i = 0, len = getChildCount(); i < len; i++) { - View view = getChildAt(i); - if ((mRefreshHeader == null || view != mRefreshHeader.getView())&& - (mRefreshFooter == null || view != mRefreshFooter.getView())) { - mRefreshContent = new RefreshContentWrapper(view); - } - } - if (mRefreshContent == null) { - mRefreshContent = new RefreshContentWrapper(getContext()); - mRefreshContent.getView().setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT)); - } - } - if (mFixedHeaderViewId > 0 && mFixedHeaderView == null) { - mFixedHeaderView = findViewById(mFixedHeaderViewId); - } - if (mFixedFooterViewId > 0 && mFixedFooterView == null) { - mFixedFooterView = findViewById(mFixedFooterViewId); - } - mRefreshContent.setupComponent(mKernel, mFixedHeaderView, mFixedFooterView); - - if (mRefreshHeader == null) { - if (mEnablePureScrollMode) { - mRefreshHeader = new FalsifyHeader(getContext()); - } else { - mRefreshHeader = mHeaderCreater.createRefreshHeader(getContext(), this); - } - if (!(mRefreshHeader.getView().getLayoutParams() instanceof MarginLayoutParams)) { - if (mRefreshHeader.getSpinnerStyle() == SpinnerStyle.Scale) { - addView(mRefreshHeader.getView(), MATCH_PARENT, MATCH_PARENT); - } else { - addView(mRefreshHeader.getView(), MATCH_PARENT, WRAP_CONTENT); - } - } - } - if (mRefreshFooter == null) { - if (mEnablePureScrollMode) { - mRefreshFooter = new RefreshFooterWrapper(new FalsifyHeader(getContext())); - } else { - mRefreshFooter = mFooterCreater.createRefreshFooter(getContext(), this); - } - if (!(mRefreshFooter.getView().getLayoutParams() instanceof MarginLayoutParams)) { - if (mRefreshFooter.getSpinnerStyle() == SpinnerStyle.Scale) { - addView(mRefreshFooter.getView(), MATCH_PARENT, MATCH_PARENT); - } else { - addView(mRefreshFooter.getView(), MATCH_PARENT, WRAP_CONTENT); - } - } - } - - //重新排序 - bringChildToFront(mRefreshContent.getView()); - if (mRefreshHeader.getSpinnerStyle() != SpinnerStyle.FixedBehind) { - bringChildToFront(mRefreshHeader.getView()); - } - if (mRefreshFooter.getSpinnerStyle() != SpinnerStyle.FixedBehind) { - bringChildToFront(mRefreshFooter.getView()); - } - - if (mRefreshListener == null) { - mRefreshListener = new OnRefreshListener() { - @Override - public void onRefresh(RefreshLayout refreshlayout) { - refreshlayout.finishRefresh(3000); - } - }; - } - if (mLoadmoreListener == null) { - mLoadmoreListener = new OnLoadmoreListener() { - @Override - public void onLoadmore(RefreshLayout refreshlayout) { - refreshlayout.finishLoadmore(2000); - } - }; - } - if (mPrimaryColors != null) { - mRefreshHeader.setPrimaryColors(mPrimaryColors); - mRefreshFooter.setPrimaryColors(mPrimaryColors); - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int minimumHeight = 0; - final boolean isInEditMode = isInEditMode() && mEnablePreviewInEditMode; - - if (mRefreshHeader != null) { - final View headerView = mRefreshHeader.getView(); - final LayoutParams lp = (LayoutParams) headerView.getLayoutParams(); - final int widthSpec = getChildMeasureSpec(widthMeasureSpec, lp.leftMargin + lp.rightMargin, lp.width); - int heightSpec = heightMeasureSpec; - - if (mHeaderHeightStatus.gteReplaceWith(DimensionStatus.CodeExactUnNotify)) { - heightSpec = makeMeasureSpec(Math.max(mHeaderHeight/* - lp.topMargin*/ - lp.bottomMargin, 0), EXACTLY); - headerView.measure(widthSpec, heightSpec); - } else { - if (lp.height > 0) { - if (mHeaderHeightStatus.canReplaceWith(DimensionStatus.XmlExact)) { - mHeaderHeightStatus = DimensionStatus.XmlExact; - mHeaderHeight = lp.height/* + lp.topMargin*/ + lp.bottomMargin; - mHeaderExtendHeight = (int) Math.max((mHeaderHeight * (mHeaderMaxDragRate - 1)), 0); - mRefreshHeader.onInitialized(mKernel, mHeaderHeight, mHeaderExtendHeight); - } - heightSpec = makeMeasureSpec(lp.height, EXACTLY); - headerView.measure(widthSpec, heightSpec); - } else if (lp.height == WRAP_CONTENT) { - heightSpec = makeMeasureSpec(Math.max(getSize(heightMeasureSpec)/* - lp.topMargin*/ - lp.bottomMargin, 0), AT_MOST); - headerView.measure(widthSpec, heightSpec); - int measuredHeight = headerView.getMeasuredHeight(); - if (measuredHeight > 0 && mHeaderHeightStatus.canReplaceWith(DimensionStatus.XmlWrap)) { - mHeaderHeightStatus = DimensionStatus.XmlWrap; - mHeaderHeight = headerView.getMeasuredHeight()/* + lp.topMargin*/ + lp.bottomMargin; - mHeaderExtendHeight = (int) Math.max((mHeaderHeight * (mHeaderMaxDragRate - 1)), 0); - mRefreshHeader.onInitialized(mKernel, mHeaderHeight, mHeaderExtendHeight); - } else if (measuredHeight <= 0) { - heightSpec = makeMeasureSpec(Math.max(mHeaderHeight/* - lp.topMargin*/ - lp.bottomMargin, 0), EXACTLY); - headerView.measure(widthSpec, heightSpec); - } - } else if (lp.height == MATCH_PARENT) { - heightSpec = makeMeasureSpec(Math.max(mHeaderHeight/* - lp.topMargin*/ - lp.bottomMargin, 0), EXACTLY); - headerView.measure(widthSpec, heightSpec); - } else { - headerView.measure(widthSpec, heightSpec); - } - } - if (mRefreshHeader.getSpinnerStyle() == SpinnerStyle.Scale && !isInEditMode) { - final int height = Math.max(0, mSpinner); - heightSpec = makeMeasureSpec(Math.max(height/* - lp.topMargin*/ - lp.bottomMargin, 0), EXACTLY); - headerView.measure(widthSpec, heightSpec); - } - - if (!mHeaderHeightStatus.notifyed) { - mHeaderHeightStatus = mHeaderHeightStatus.notifyed(); - mRefreshHeader.onInitialized(mKernel, mHeaderHeight, mHeaderExtendHeight); - } - - if (isInEditMode) { - minimumHeight += headerView.getMeasuredHeight(); - } - } - - if (mRefreshFooter != null) { - final View footerView = mRefreshFooter.getView(); - final LayoutParams lp = (LayoutParams) footerView.getLayoutParams(); - final int widthSpec = getChildMeasureSpec(widthMeasureSpec, lp.leftMargin + lp.rightMargin, lp.width); - int heightSpec = heightMeasureSpec; - if (mFooterHeightStatus.gteReplaceWith(DimensionStatus.CodeExactUnNotify)) { - heightSpec = makeMeasureSpec(Math.max(mFooterHeight - lp.topMargin/* - lp.bottomMargin*/, 0), EXACTLY); - footerView.measure(widthSpec, heightSpec); - } else if (lp.height > 0) { - if (mFooterHeightStatus.canReplaceWith(DimensionStatus.XmlExact)) { - mFooterHeightStatus = DimensionStatus.XmlExact; - mFooterHeight = lp.height + lp.topMargin/* + lp.bottomMargin*/; - mFooterExtendHeight = (int) Math.max((mFooterHeight * (mFooterMaxDragRate - 1)), 0); - mRefreshFooter.onInitialized(mKernel, mFooterHeight, mFooterExtendHeight); - } - heightSpec = makeMeasureSpec(lp.height - lp.topMargin/* - lp.bottomMargin*/, EXACTLY); - footerView.measure(widthSpec, heightSpec); - } else if (lp.height == WRAP_CONTENT) { - heightSpec = makeMeasureSpec(Math.max(getSize(heightMeasureSpec) - lp.topMargin/* - lp.bottomMargin*/, 0), AT_MOST); - footerView.measure(widthSpec, heightSpec); - int measuredHeight = footerView.getMeasuredHeight(); - if (measuredHeight > 0 && mFooterHeightStatus.canReplaceWith(DimensionStatus.XmlWrap)) { - mFooterHeightStatus = DimensionStatus.XmlWrap; - mFooterHeight = footerView.getMeasuredHeight() + lp.topMargin/* + lp.bottomMargin*/; - mFooterExtendHeight = (int) Math.max((mFooterHeight * (mFooterMaxDragRate - 1)), 0); - mRefreshFooter.onInitialized(mKernel, mFooterHeight, mFooterExtendHeight); - } else if (measuredHeight <= 0){ - heightSpec = makeMeasureSpec(Math.max(mFooterHeight - lp.topMargin/* - lp.bottomMargin*/, 0), EXACTLY); - footerView.measure(widthSpec, heightSpec); - } - } else if (lp.height == MATCH_PARENT) { - heightSpec = makeMeasureSpec(Math.max(mFooterHeight - lp.topMargin/* - lp.bottomMargin*/, 0), EXACTLY); - footerView.measure(widthSpec, heightSpec); - } else { - footerView.measure(widthSpec, heightSpec); - } - - if (mRefreshFooter.getSpinnerStyle() == SpinnerStyle.Scale && !isInEditMode) { - final int height = Math.max(0, -mSpinner); - heightSpec = makeMeasureSpec(Math.max(height - lp.topMargin/* - lp.bottomMargin*/, 0), EXACTLY); - footerView.measure(widthSpec, heightSpec); - } - - if (!mFooterHeightStatus.notifyed) { - mFooterHeightStatus = mFooterHeightStatus.notifyed(); - mRefreshFooter.onInitialized(mKernel, mFooterHeight, mFooterExtendHeight); - } - - if (isInEditMode) { - minimumHeight += footerView.getMeasuredHeight(); - } - } - - if (mRefreshContent != null) { - final LayoutParams lp = (LayoutParams) mRefreshContent.getLayoutParams(); - final int widthSpec = getChildMeasureSpec(widthMeasureSpec, - getPaddingLeft() + getPaddingRight() + - lp.leftMargin + lp.rightMargin, lp.width); - final int heightSpec = getChildMeasureSpec(heightMeasureSpec, - getPaddingTop() + getPaddingBottom() + - lp.topMargin + lp.bottomMargin + - ((isInEditMode && mRefreshHeader != null && (mEnableHeaderTranslationContent||mRefreshHeader.getSpinnerStyle() == SpinnerStyle.FixedBehind)) ? mHeaderHeight : 0) + - ((isInEditMode && mRefreshFooter != null && (mEnableFooterTranslationContent||mRefreshFooter.getSpinnerStyle() == SpinnerStyle.FixedBehind)) ? mFooterHeight : 0), lp.height); - mRefreshContent.measure(widthSpec, heightSpec); - mRefreshContent.onInitialHeaderAndFooter(mHeaderHeight, mFooterHeight); - minimumHeight += mRefreshContent.getMeasuredHeight(); - } - - setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec), resolveSize(minimumHeight, heightMeasureSpec)); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - final int paddingLeft = getPaddingLeft(); - final int paddingTop = getPaddingTop(); - final int paddingBottom = getPaddingBottom(); - final boolean isInEditMode = isInEditMode() && mEnablePreviewInEditMode; - - if (mRefreshContent != null) { - final LayoutParams lp = (LayoutParams) mRefreshContent.getLayoutParams(); - int left = paddingLeft + lp.leftMargin; - int top = paddingTop + lp.topMargin; - int right = left + mRefreshContent.getMeasuredWidth(); - int bottom = top + mRefreshContent.getMeasuredHeight(); - if (isInEditMode && mRefreshHeader != null && (mEnableHeaderTranslationContent||mRefreshHeader.getSpinnerStyle() == SpinnerStyle.FixedBehind)) { - top = top + mHeaderHeight; - bottom = bottom + mHeaderHeight; - } - mRefreshContent.layout(left, top, right, bottom); - } - - if (mRefreshHeader != null) { - final View headerView = mRefreshHeader.getView(); - final LayoutParams lp = (LayoutParams) headerView.getLayoutParams(); - int left = lp.leftMargin; - int top = lp.topMargin ; - int right = left + headerView.getMeasuredWidth(); - int bottom = top + headerView.getMeasuredHeight(); - if (!isInEditMode) { - if (mRefreshHeader.getSpinnerStyle() == SpinnerStyle.Translate) { - top = top - mHeaderHeight + Math.max(0, mSpinner); - bottom = top + headerView.getMeasuredHeight(); - } else if (mRefreshHeader.getSpinnerStyle() == SpinnerStyle.Scale) { - bottom = top + Math.max(Math.max(0, mSpinner)/* - lp.topMargin*/ - lp.bottomMargin, 0); -// } else if (mRefreshHeader.getSpinnerStyle() == SpinnerStyle.FixedBehind -// || mRefreshHeader.getSpinnerStyle() == SpinnerStyle.FixedFront) { -// bottom = top + Math.max(headerView.getMeasuredHeight(), mSpinner); - } - } - headerView.layout(left, top, right, bottom); - } - - if (mRefreshFooter != null) { - final View footerView = mRefreshFooter.getView(); - final LayoutParams lp = (LayoutParams) footerView.getLayoutParams(); - final SpinnerStyle style = mRefreshFooter.getSpinnerStyle(); - int left = lp.leftMargin; - int top = lp.topMargin + getMeasuredHeight(); - - if (isInEditMode - || style == SpinnerStyle.FixedFront - || style == SpinnerStyle.FixedBehind) { - top = top - mFooterHeight; - } else if (style == SpinnerStyle.Scale || style == SpinnerStyle.Translate) { - top = top - Math.max(Math.max(-mSpinner, 0) - lp.topMargin/* - lp.bottomMargin*/, 0); - } - - int right = left + footerView.getMeasuredWidth(); - int bottom = top + footerView.getMeasuredHeight(); - footerView.layout(left, top, right, bottom); - } - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - mKernel = null; - mRefreshHeader = null; - mRefreshFooter = null; - mRefreshContent = null; - mFixedHeaderView = null; - mFixedFooterView = null; - } - - @Override - protected void dispatchDraw(Canvas canvas) { - boolean isInEditMode = mEnablePreviewInEditMode && isInEditMode(); - if (mHeaderBackgroundColor != 0 && (mSpinner > 0 || isInEditMode)) { - mPaint.setColor(mHeaderBackgroundColor); - canvas.drawRect(0, 0, getWidth(), (isInEditMode) ? mHeaderHeight : mSpinner, mPaint); - } else if (mFooterBackgroundColor != 0 && (mSpinner < 0 || isInEditMode)) { - mPaint.setColor(mFooterBackgroundColor); - canvas.drawRect(0, 0, getWidth(), getHeight() + (isInEditMode ? (-mFooterHeight) : mSpinner), mPaint); - } - super.dispatchDraw(canvas); - } - - // - - // - MotionEvent mFalsifyEvent = null; - - @Override - public boolean dispatchTouchEvent(MotionEvent e) { - final int action = MotionEventCompat.getActionMasked(e); - if (mRefreshContent != null) { - switch (action) { - case MotionEvent.ACTION_DOWN: - mRefreshContent.onActionDown(e); - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mRefreshContent.onActionUpOrCancel(); - } - } - if (reboundAnimator != null - || (mState == RefreshState.Loading && mDisableContentWhenLoading) - || (mState == RefreshState.Refreshing && mDisableContentWhenRefresh)) { - return false; - } - if (!isEnabled() || mNestedScrollInProgress - || (!isEnableRefresh() && !(isEnableLoadmore())) - || mState == RefreshState.Loading - || mState == RefreshState.Refreshing) { - return super.dispatchTouchEvent(e); - } - switch (action) { - case MotionEvent.ACTION_DOWN: - mTouchX = e.getX(); - mTouchY = e.getY(); - super.dispatchTouchEvent(e); - return true; - - case MotionEvent.ACTION_MOVE: - final float dx = e.getX() - mTouchX; - final float dy = e.getY() - mTouchY; - if(mState == RefreshState.None) { - if (Math.abs(dy) >= mTouchSlop && Math.abs(dx) < Math.abs(dy)) {//滑动允许最大角度为45度 - if (dy > 0 && isEnableRefresh() && !mRefreshContent.canScrollUp()) { - mInitialMotionY = dy + mTouchY - mTouchSlop; - setStatePullDownToRefresh(); - e.setAction(MotionEvent.ACTION_CANCEL); - super.dispatchTouchEvent(e); - } else if (dy < 0 && isEnableLoadmore() && !mRefreshContent.canScrollDown()) { - mInitialMotionY = dy + mTouchY + mTouchSlop; - setStatePullUpToLoad(); - e.setAction(MotionEvent.ACTION_CANCEL); - super.dispatchTouchEvent(e); - } else { - return super.dispatchTouchEvent(e); - } - } else { - return super.dispatchTouchEvent(e); - } - } - final float spinner = dy + mTouchY - mInitialMotionY; - if (((mState == RefreshState.PullDownToRefresh || mState == RefreshState.ReleaseToRefresh) && spinner < 0) - ||((mState == RefreshState.PullToUpLoad || mState == RefreshState.ReleaseToLoad) && spinner > 0)) { - long time = currentTimeMillis(); - if (mFalsifyEvent == null) { - mFalsifyEvent = MotionEvent.obtain(time, time, MotionEvent.ACTION_DOWN, mTouchX + dx, mInitialMotionY, 0); - super.dispatchTouchEvent(mFalsifyEvent); - } - MotionEvent em = MotionEvent.obtain(time, time, MotionEvent.ACTION_MOVE, mTouchX + dx, mInitialMotionY + spinner, 0); - super.dispatchTouchEvent(em); - if (mSpinner != 0) { - moveSpinnerInfinitely(0); - } - return true; - } - if (mState == RefreshState.PullDownToRefresh || mState == RefreshState.ReleaseToRefresh || - mState == RefreshState.PullToUpLoad || mState == RefreshState.ReleaseToLoad) { - moveSpinnerInfinitely(spinner); - return true; - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - final float y = e.getY(); - if (mFalsifyEvent != null) { - mFalsifyEvent = null; - long time = currentTimeMillis(); - MotionEvent ec = MotionEvent.obtain(time, time, MotionEvent.ACTION_CANCEL, mTouchX, y, 0); - super.dispatchTouchEvent(ec); - } - if (overSpinner()) { - return true; - } - break; - } - return super.dispatchTouchEvent(e); - } - - @Override - public boolean onInterceptTouchEvent(MotionEvent e) { - if (mState == RefreshState.Refreshing || mState == RefreshState.Loading) { - final int action = MotionEventCompat.getActionMasked(e); - if (isNestedScrollingEnabled() && mRefreshContent != null && mRefreshContent.isNestedScrollingChild(e)) { - return false; - } - switch (action) { - case MotionEvent.ACTION_DOWN: - mTouchX = e.getX(); - mTouchY = e.getY(); - mTotalUnconsumed = 0; - break; - case MotionEvent.ACTION_MOVE: - final float dy = e.getY() - mTouchY; - final float dx = e.getX() - mTouchX; - if (Math.abs(dy) >= mTouchSlop && Math.abs(dx) < Math.abs(dy)) {//滑动允许最大角度为45度 - if ((dy < 0 && (mSpinner > 0 || (mRefreshContent != null && !mRefreshContent.canScrollDown()))) - || (dy > 0 && (mSpinner < 0 || (mRefreshContent != null && !mRefreshContent.canScrollUp())))) { - mTouchY += dy + (dy > 0 ? -1 : 1) * mTouchSlop; - mInitialMotionY = mSpinner; - mTotalUnconsumed = 1; - return true; - } - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mTouchX = 0; - mTouchY = 0; - break; - } - } - return super.onInterceptTouchEvent(e); - } - - @Override - public boolean onTouchEvent(MotionEvent e) { - if (mState == RefreshState.Refreshing || mState == RefreshState.Loading) { - final int action = MotionEventCompat.getActionMasked(e); - switch (action) { - case MotionEvent.ACTION_DOWN: - mTouchX = e.getX(); - mTouchY = e.getY(); - mInitialMotionY = -1; - mTotalUnconsumed = 0; - break; - case MotionEvent.ACTION_MOVE: - final float dy = e.getY() - mTouchY; - if (mTotalUnconsumed == 0) { - final float dx = e.getX() - mTouchX; - if (Math.abs(dy) >= mTouchSlop && Math.abs(dx) < Math.abs(dy)) {//滑动允许最大角度为45度 - if (dy < 0) {//向上滚动 - mTouchY = Math.max(dy + mTouchY + mTouchSlop, 1); - } else { - mTouchY = Math.max(dy + mTouchY - mTouchSlop, 1); - } - mInitialMotionY = mSpinner; - mTotalUnconsumed = 1; - } - } - if (mTotalUnconsumed > 0) { - if (mState == RefreshState.Refreshing) { -// if (mRefreshHeader != null && mRefreshHeader.getSpinnerStyle() != SpinnerStyle.FixedFront) { - final int spinner = (int)(mInitialMotionY + dy); - if (spinner < 0 && (mRefreshContent != null && mRefreshContent.canScrollDown())) { - moveSpinnerInfinitely(0); - e.setAction(MotionEvent.ACTION_DOWN); - super.dispatchTouchEvent(e); - e.setAction(MotionEvent.ACTION_MOVE); - e.offsetLocation(0, mInitialMotionY + dy); - super.dispatchTouchEvent(e); - mTotalUnconsumed = 0; - mInitialMotionY = 0; - return false; - } - moveSpinnerInfinitely(spinner); -// } - } else { -// if (mRefreshFooter != null && mRefreshFooter.getSpinnerStyle() != SpinnerStyle.FixedFront) { - final int spinner = (int)(mInitialMotionY + dy); - if (spinner > 0 && (mRefreshContent != null && mRefreshContent.canScrollUp())) { - moveSpinnerInfinitely(0); - e.setAction(MotionEvent.ACTION_DOWN); - super.dispatchTouchEvent(e); - e.setAction(MotionEvent.ACTION_MOVE); - e.offsetLocation(0, mInitialMotionY + dy); - super.dispatchTouchEvent(e); - mTotalUnconsumed = 0; - mInitialMotionY = 0; - return false; - } - moveSpinnerInfinitely(spinner); -// } - } - } - break; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - mTouchX = 0; - mTouchY = 0; - mTotalUnconsumed = 0; - mInitialMotionY = 0; - overSpinner(); - break; - } - return true; - } - return super.onTouchEvent(e); - } - - @Override - public void requestDisallowInterceptTouchEvent(boolean b) { - // if this is a List < L or another view that doesn't support nested - // scrolling, ignore this request so that the vertical scroll event - // isn't stolen - View target = mRefreshContent.getScrollableView(); - if ((android.os.Build.VERSION.SDK_INT >= 21 || !(target instanceof AbsListView)) - && (target == null || ViewCompat.isNestedScrollingEnabled(target))) { - super.requestDisallowInterceptTouchEvent(b); - //} else { - // Nope. - } - } - - // - - // - - protected void notifyStateChanged(RefreshState state) { - final RefreshState oldState = mState; - if (oldState != state) { - mState = state; - if (mRefreshFooter != null) { - mRefreshFooter.onStateChanged(this, oldState, state); - } - if (mRefreshHeader != null) { - mRefreshHeader.onStateChanged(this, oldState, state); - } - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onStateChanged(this, oldState, state); - } - } - } - - protected void setStatePullUpToLoad() { - notifyStateChanged(RefreshState.PullToUpLoad); - } - - protected void setStateReleaseToLoad() { - notifyStateChanged(RefreshState.ReleaseToLoad); - } - - protected void setStateReleaseToRefresh() { - notifyStateChanged(RefreshState.ReleaseToRefresh); - } - - protected void setStatePullDownToRefresh() { - notifyStateChanged(RefreshState.PullDownToRefresh); - } - - protected void setStatePullDownCanceled() { - notifyStateChanged(RefreshState.PullDownCanceled); - resetStatus(); - } - - protected void setStatePullUpCanceled() { - notifyStateChanged(RefreshState.PullUpCanceled); - resetStatus(); - } - - protected void setStateLoding() { - mLastLoadingTime = currentTimeMillis(); - notifyStateChanged(RefreshState.Loading); - animSpinner(-mFooterHeight); - if (mLoadmoreListener != null) { - mLoadmoreListener.onLoadmore(this); - } - if (mRefreshFooter != null) { - mRefreshFooter.onStartAnimator(this, mFooterHeight, mFooterExtendHeight); - } - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onLoadmore(this); - mOnMultiPurposeListener.onFooterStartAnimator(mRefreshFooter, mFooterHeight, mFooterExtendHeight); - } - } - - protected void setStateRefresing() { - mLastRefreshingTime = currentTimeMillis(); - notifyStateChanged(RefreshState.Refreshing); - animSpinner(mHeaderHeight); - if (mRefreshListener != null) { - mRefreshListener.onRefresh(this); - } - if (mRefreshHeader != null) { - mRefreshHeader.onStartAnimator(this, mHeaderHeight, mHeaderExtendHeight); - } - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onRefresh(this); - mOnMultiPurposeListener.onHeaderStartAnimator(mRefreshHeader, mHeaderHeight, mHeaderExtendHeight); - } - } - - /** - * 重置状态 - */ - protected void resetStatus() { - if (mState != RefreshState.None) { - if (mSpinner == 0) { - notifyStateChanged(RefreshState.None); - } - } - if (mSpinner != 0) { - animSpinner(0); - } - } - // - - // - - // - protected ValueAnimator reboundAnimator; - protected AnimatorListener reboundAnimatorEndListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - reboundAnimator = null; - if ((int)((ValueAnimator)animation).getAnimatedValue() == 0) { - if (mState != RefreshState.None && mState != RefreshState.Refreshing && mState != RefreshState.Loading) { - notifyStateChanged(RefreshState.None); - } - } - } - }; - - protected AnimatorUpdateListener reboundUpdateListener = new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - moveSpinner((int) animation.getAnimatedValue(), true); - } - }; - // - - protected ValueAnimator animSpinner(int endSpinner) { - return animSpinner(endSpinner, 0); - } - protected ValueAnimator animSpinner(int endSpinner, int startDelay) { - return animSpinner(endSpinner, startDelay, mReboundInterpolator); - } - - protected ValueAnimator animSpinner(int endSpinner, int startDelay, Interpolator interpolator) { - if (mSpinner != endSpinner) { - if (reboundAnimator != null) { - reboundAnimator.cancel(); - } - reboundAnimator = ValueAnimator.ofInt(mSpinner, endSpinner); - reboundAnimator.setDuration(mReboundDuration); - reboundAnimator.setInterpolator(interpolator); - reboundAnimator.addUpdateListener(reboundUpdateListener); - reboundAnimator.addListener(reboundAnimatorEndListener); - reboundAnimator.setStartDelay(startDelay); - reboundAnimator.start(); - } - return reboundAnimator; - } - - /** - * 执行回弹动画 - */ - protected ValueAnimator animSpinnerBounce(int bounceSpinner) { - if (reboundAnimator == null) { - if (mState == RefreshState.Refreshing && bounceSpinner > 0) { - reboundAnimator = ValueAnimator.ofInt(mSpinner, Math.min(2 * bounceSpinner, mHeaderHeight)); - reboundAnimator.setDuration(250); - } else if (mState == RefreshState.Loading && bounceSpinner < 0) { - reboundAnimator = ValueAnimator.ofInt(mSpinner, Math.max(2 * bounceSpinner, -mFooterHeight)); - reboundAnimator.setDuration(250); - } else if (mSpinner == 0 && mEnableOverScrollBounce) { - reboundAnimator = ValueAnimator.ofInt(0, bounceSpinner, 0); - reboundAnimator.setDuration(500); - } - if (reboundAnimator != null) { - reboundAnimator.setInterpolator(new DecelerateInterpolator()); - reboundAnimator.addUpdateListener(reboundUpdateListener); - reboundAnimator.addListener(reboundAnimatorEndListener); - reboundAnimator.start(); - } - } - return reboundAnimator; - } - - /** - * 手势拖动结束 - * 开始执行回弹动画 - */ - protected boolean overSpinner() { - if (mState == RefreshState.Loading) { - if (mSpinner < -mFooterHeight) { - mTotalUnconsumed = -mFooterHeight; - animSpinner(-mFooterHeight); - } else if (mSpinner > 0) { - mTotalUnconsumed = 0; - animSpinner(0); - } else { - return false; - } - } else if (mState == RefreshState.Refreshing) { - if (mSpinner > mHeaderHeight) { - mTotalUnconsumed = mHeaderHeight; - animSpinner(mHeaderHeight); - } else if (mSpinner < 0) { - mTotalUnconsumed = 0; - animSpinner(0); - } else { - return false; - } - } else if (mState == RefreshState.PullDownToRefresh - || (mEnablePureScrollMode && mState == RefreshState.ReleaseToRefresh)) { - setStatePullDownCanceled(); - } else if (mState == RefreshState.PullToUpLoad - || (mEnablePureScrollMode && mState == RefreshState.ReleaseToLoad)) { - setStatePullUpCanceled(); - } else if (mState == RefreshState.ReleaseToRefresh) { - setStateRefresing(); - } else if (mState == RefreshState.ReleaseToLoad) { - setStateLoding(); - } else if (mSpinner != 0) { - animSpinner(0); - } else { - return false; - } - return true; - } - - protected void moveSpinnerInfinitely(float dy) { - if (mState == RefreshState.Refreshing && dy >= 0) { - if (dy < mHeaderHeight) { - moveSpinner((int) dy, false); - } else { - final double M = mHeaderExtendHeight; - final double H = Math.max(mScreenHeightPixels * 4 / 3, getHeight()) - mHeaderHeight; - final double x = Math.max(0, (dy - mHeaderHeight) * mDragRate); - final double y = Math.min(M * (1 - Math.pow(100, -x / H)), x);// 公式 y = M(1-40^(-x/H)) - moveSpinner((int) y + mHeaderHeight, false); - } - } else if (mState == RefreshState.Loading && dy < 0) { - if (dy > -mFooterHeight) { - moveSpinner((int) dy, false); - } else { - final double M = mFooterExtendHeight; - final double H = Math.max(mScreenHeightPixels * 4 / 3, getHeight()) - mFooterHeight; - final double x = -Math.min(0, (dy + mHeaderHeight) * mDragRate); - final double y = -Math.min(M * (1 - Math.pow(100, -x / H)), x);// 公式 y = M(1-40^(-x/H)) - moveSpinner((int) y - mFooterHeight, false); - } - } else if (dy >= 0) { - final double M = mHeaderExtendHeight + mHeaderHeight; - final double H = Math.max(mScreenHeightPixels / 2, getHeight()); - final double x = Math.max(0, dy * mDragRate); - final double y = Math.min(M * (1 - Math.pow(100, -x / H)), x);// 公式 y = M(1-40^(-x/H)) - moveSpinner((int) y, false); - } else { - final double M = mFooterExtendHeight + mFooterHeight; - final double H = Math.max(mScreenHeightPixels / 2, getHeight()); - final double x = -Math.min(0, dy * mDragRate); - final double y = -Math.min(M * (1 - Math.pow(100, -x / H)), x);// 公式 y = M(1-40^(-x/H)) - moveSpinner((int) y, false); - } - } - - /** - * 移动滚动 Scroll - * moveSpinner 的取名来自 谷歌官方的 @{@link android.support.v4.widget.SwipeRefreshLayout#moveSpinner(float)} - */ - protected void moveSpinner(int spinner, boolean isAnimator) { - if (mSpinner == spinner) { - return; - } - final int oldSpinner = mSpinner; - this.mSpinner = spinner; - if (!isAnimator && mState != RefreshState.Refreshing && mState != RefreshState.Loading) { - if (mSpinner > mHeaderHeight) { - setStateReleaseToRefresh(); - } else if (-mSpinner > mFooterHeight && !mLoadmoreFinished) { - setStateReleaseToLoad(); - } else if (mSpinner < 0 && !mLoadmoreFinished) { - setStatePullUpToLoad(); - } else if (mSpinner > 0) { - setStatePullDownToRefresh(); - } - } - if (mRefreshContent != null) { - if (spinner >= 0) { - if (mEnableHeaderTranslationContent || mRefreshHeader == null || mRefreshHeader.getSpinnerStyle() == SpinnerStyle.FixedBehind) { - mRefreshContent.moveSpinner(spinner); - if (mHeaderBackgroundColor != 0) { - invalidate(); - } - } - } else { - if (mEnableFooterTranslationContent || mRefreshFooter == null || mRefreshFooter.getSpinnerStyle() == SpinnerStyle.FixedBehind) { - mRefreshContent.moveSpinner(spinner); - if (mHeaderBackgroundColor != 0) { - invalidate(); - } - } - } - } - if ((spinner >= 0 || oldSpinner > 0) && mRefreshHeader != null) { - spinner = Math.max(spinner, 0); - if (isEnableRefresh()) { - if (mRefreshHeader.getSpinnerStyle() == SpinnerStyle.Scale - || mRefreshHeader.getSpinnerStyle() == SpinnerStyle.Translate) { - mRefreshHeader.getView().requestLayout(); - } - } - if (isAnimator) { - mRefreshHeader.onReleasing(1f * spinner / mHeaderHeight, spinner, mHeaderHeight, mHeaderExtendHeight); - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onHeaderReleasing(mRefreshHeader, 1f * spinner / mHeaderHeight, spinner, mHeaderHeight, mHeaderExtendHeight); - } - } else { - mRefreshHeader.onPullingDown(1f * spinner / mHeaderHeight, spinner, mHeaderHeight, mHeaderExtendHeight); - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onHeaderPulling(mRefreshHeader, 1f * spinner / mHeaderHeight, spinner, mHeaderHeight, mHeaderExtendHeight); - } - } - } - if ((spinner <= 0 || oldSpinner < 0) && mRefreshFooter != null) { - spinner = Math.min(spinner, 0); - if (mEnableLoadmore) { - if (mRefreshFooter.getSpinnerStyle() == SpinnerStyle.Scale - || mRefreshFooter.getSpinnerStyle() == SpinnerStyle.Translate) { - mRefreshFooter.getView().requestLayout(); - } - } - if (isAnimator) { - mRefreshFooter.onPullReleasing(1f * spinner / mFooterHeight, spinner, mFooterHeight, mFooterExtendHeight); - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onFooterReleasing(mRefreshFooter, 1f * spinner / mFooterHeight, spinner, mFooterHeight, mFooterExtendHeight); - } - } else { - mRefreshFooter.onPullingUp(1f * spinner / mFooterHeight, spinner, mFooterHeight, mFooterExtendHeight); - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onFooterPulling(mRefreshFooter, 1f * spinner / mFooterHeight, spinner, mFooterHeight, mFooterExtendHeight); - } - } - } - } - - // - - // - @Override - protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { - return p instanceof LayoutParams; - } - - @Override - protected LayoutParams generateDefaultLayoutParams() { - return new LayoutParams(MATCH_PARENT, MATCH_PARENT); - } - - @Override - protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { - return new LayoutParams(p); - } - - @Override - public LayoutParams generateLayoutParams(AttributeSet attrs) { - return new LayoutParams(getContext(), attrs); - } - - public static class LayoutParams extends MarginLayoutParams { - - public LayoutParams(Context c, AttributeSet attrs) { - super(c, attrs); - } - - public LayoutParams(int width, int height) { - super(width, height); - } - - public LayoutParams(MarginLayoutParams source) { - super(source); - } - - public LayoutParams(ViewGroup.LayoutParams source) { - super(source); - } - } - // - - // - - // - @Override - public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) { - boolean accepted = isEnabled() && isNestedScrollingEnabled() && (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0; - accepted = accepted && (isEnableRefresh()||isEnableLoadmore()); - return accepted; - } - - @Override - public void onNestedScrollAccepted(View child, View target, int axes) { - // Reset the counter of how much leftover scroll needs to be consumed. - mNestedScrollingParentHelper.onNestedScrollAccepted(child, target, axes); - // Dispatch up to the nested parent - startNestedScroll(axes & ViewCompat.SCROLL_AXIS_VERTICAL); - mTotalUnconsumed = 0; - mInitialMotionY = mSpinner; - mNestedScrollInProgress = true; - } - - @Override - public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) { - // If we are in the middle of consuming, a scroll, then we want to move the spinner back up - // before allowing the list to scroll - if (mState == RefreshState.Refreshing || mState == RefreshState.Loading) { - final int[] parentConsumed = mParentScrollConsumed; - if (dispatchNestedPreScroll(dx, dy, parentConsumed, null)) { - dy -= parentConsumed[1]; - } - - if (mState == RefreshState.Refreshing && dy > 0) { - consumed[1] = 0; - if (mTotalUnconsumed > 0) { - if (dy > mTotalUnconsumed) { - consumed[1] += mTotalUnconsumed; - mTotalUnconsumed = 0; - dy -= mTotalUnconsumed; - if (mInitialMotionY <= 0) { - moveSpinnerInfinitely(0); - } - } else { - mTotalUnconsumed -= dy; - consumed[1] += dy; - dy = 0; - moveSpinnerInfinitely(mTotalUnconsumed + mInitialMotionY); - } - } - - if (dy > 0 && mInitialMotionY > 0) { - if (dy > mInitialMotionY) { - consumed[1] += mInitialMotionY; - mInitialMotionY = 0; - } else { - mInitialMotionY -= dy; - consumed[1] += dy; - } - moveSpinnerInfinitely(mInitialMotionY); - } - } else if (mState == RefreshState.Loading && dy < 0) { - consumed[1] = 0; - if (mTotalUnconsumed < 0) { - if (dy < mTotalUnconsumed) { - consumed[1] += mTotalUnconsumed; - mTotalUnconsumed = 0; - dy -= mTotalUnconsumed; - if (mInitialMotionY >= 0) { - moveSpinnerInfinitely(0); - } - } else { - mTotalUnconsumed -= dy; - consumed[1] += dy; - dy = 0; - moveSpinnerInfinitely(mTotalUnconsumed + mInitialMotionY); - } - } - - if (dy < 0 && mInitialMotionY < 0) { - if (dy < mInitialMotionY) { - consumed[1] += mInitialMotionY; - mInitialMotionY = 0; - } else { - mInitialMotionY -= dy; - consumed[1] += dy; - } - moveSpinnerInfinitely(mInitialMotionY); - } - } - } else { - if (isEnableRefresh() && dy > 0 && mTotalUnconsumed > 0) { - if (dy > mTotalUnconsumed) { - consumed[1] = dy - mTotalUnconsumed; - mTotalUnconsumed = 0; - } else { - mTotalUnconsumed -= dy; - consumed[1] = dy; - } - moveSpinnerInfinitely(mTotalUnconsumed); - } else if (mEnableLoadmore && dy < 0 && mTotalUnconsumed < 0) { - if (dy < mTotalUnconsumed) { - consumed[1] = dy - mTotalUnconsumed; - mTotalUnconsumed = 0; - } else { - mTotalUnconsumed -= dy; - consumed[1] = dy; - } - moveSpinnerInfinitely(mTotalUnconsumed); - } - - // If a client layout is using a custom start position for the circle - // view, they mean to hide it again before scrolling the child view - // If we get back to mTotalUnconsumed == 0 and there is more to go, hide - // the circle so it isn't exposed if its blocking content is moved -// if (mUsingCustomStart && dy > 0 && mTotalUnconsumed == 0 -// && Math.abs(dy - consumed[1]) > 0) { -// mCircleView.setVisibility(View.GONE); -// } - - // Now let our nested parent consume the leftovers - final int[] parentConsumed = mParentScrollConsumed; - if (dispatchNestedPreScroll(dx - consumed[0], dy - consumed[1], parentConsumed, null)) { - consumed[0] += parentConsumed[0]; - consumed[1] += parentConsumed[1]; - } - } - - } - - @Override - public int getNestedScrollAxes() { - return mNestedScrollingParentHelper.getNestedScrollAxes(); - } - - @Override - public void onStopNestedScroll(View target) { - mNestedScrollingParentHelper.onStopNestedScroll(target); - mNestedScrollInProgress = false; - // Finish the spinner for nested scrolling if we ever consumed any - // unconsumed nested scroll -// if (mState != RefreshState.Refreshing && mState != RefreshState.Loading) { -// } - mTotalUnconsumed = 0; - overSpinner(); - // Dispatch up our nested parent - stopNestedScroll(); - } - - @Override - public void onNestedScroll(final View target, final int dxConsumed, final int dyConsumed, - final int dxUnconsumed, final int dyUnconsumed) { - // Dispatch up to the nested parent first - dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, - mParentOffsetInWindow); - - // This is a bit of a hack. Nested scrolling works from the bottom up, and as we are - // sometimes between two nested scrolling views, we need a way to be able to know when any - // nested scrolling parent has stopped handling events. We do that by using the - // 'offset in window 'functionality to see if we have been moved from the event. - // This is a decent indication of whether we should take over the event stream or not. - - final int dy = dyUnconsumed + mParentOffsetInWindow[1]; - if (mState == RefreshState.Refreshing || mState == RefreshState.Loading) { - if (isEnableRefresh() && dy < 0 && (mRefreshContent == null || !mRefreshContent.canScrollUp())) { - mTotalUnconsumed += Math.abs(dy); - moveSpinnerInfinitely(mTotalUnconsumed + mInitialMotionY); - } else if (isEnableLoadmore() && dy > 0 && (mRefreshContent == null || !mRefreshContent.canScrollDown())) { - mTotalUnconsumed -= Math.abs(dy); - moveSpinnerInfinitely(mTotalUnconsumed + mInitialMotionY); - } - } else { - if (isEnableRefresh() && dy < 0 && (mRefreshContent == null || !mRefreshContent.canScrollUp())) { - if (mState == RefreshState.None) { - setStatePullDownToRefresh(); - } - mTotalUnconsumed += Math.abs(dy); - moveSpinnerInfinitely(mTotalUnconsumed); - } else if (mEnableLoadmore && dy > 0 - && (mRefreshContent == null || !mRefreshContent.canScrollDown())) { - if (mState == RefreshState.None && !mLoadmoreFinished) { - setStatePullUpToLoad(); - } - mTotalUnconsumed -= Math.abs(dy); - moveSpinnerInfinitely(mTotalUnconsumed); - } - } - } - - @Override - public boolean onNestedPreFling(View target, float velocityX, float velocityY) { - return reboundAnimator != null - || mState == RefreshState.PullDownToRefresh || mState == RefreshState.PullToUpLoad - || mState == RefreshState.ReleaseToRefresh || mState == RefreshState.ReleaseToLoad -// || (mState == RefreshState.Refreshing && mHeaderTranslationY > -mHeaderHeight) -// || (mState == RefreshState.Loading && mFooterTranslationY < mFooterHeight) - || (mState == RefreshState.Refreshing && mSpinner != 0) - || (mState == RefreshState.Loading && mSpinner != 0) - || dispatchNestedPreFling(velocityX, velocityY); - } - - @Override - public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) { - return dispatchNestedFling(velocityX, velocityY, consumed); - } - // - - // - @Override - public void setNestedScrollingEnabled(boolean enabled) { - mNestedScrollingChildHelper.setNestedScrollingEnabled(enabled); - } - - @Override - public boolean isNestedScrollingEnabled() { - return mNestedScrollingChildHelper.isNestedScrollingEnabled(); - } - - @Override - public boolean startNestedScroll(int axes) { - return mNestedScrollingChildHelper.startNestedScroll(axes); - } - - @Override - public void stopNestedScroll() { - mNestedScrollingChildHelper.stopNestedScroll(); - } - - @Override - public boolean hasNestedScrollingParent() { - return mNestedScrollingChildHelper.hasNestedScrollingParent(); - } - - @Override - public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, - int dyUnconsumed, int[] offsetInWindow) { - return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, - dxUnconsumed, dyUnconsumed, offsetInWindow); - } - - @Override - public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { - return mNestedScrollingChildHelper.dispatchNestedPreScroll( - dx, dy, consumed, offsetInWindow); - } - - @Override - public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { - return mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed); + // + public SmartRefreshLayout(Context context) { + this(context, null); } - @Override - public boolean dispatchNestedPreFling(float velocityX, float velocityY) { - return mNestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY); + public SmartRefreshLayout(Context context, AttributeSet attrs) { + super(context, attrs); } // - // - // - @Override - public SmartRefreshLayout setFooterHeight(float heightDp) { - return setFooterHeightPx(dp2px(heightDp)); - } - @Override - public SmartRefreshLayout setFooterHeightPx(int heightPx) { - if (mFooterHeightStatus.canReplaceWith(DimensionStatus.CodeExact)) { - mFooterHeight = heightPx; - mFooterExtendHeight = (int) Math.max((heightPx * (mFooterMaxDragRate - 1)), 0); - if (mRefreshFooter != null) { - mFooterHeightStatus = DimensionStatus.CodeExact; - mRefreshFooter.onInitialized(mKernel, mFooterHeight, mFooterExtendHeight); - } else { - mFooterHeightStatus = DimensionStatus.CodeExactUnNotify; - } - } - return this; - } - @Override - public SmartRefreshLayout setHeaderHeight(float heightDp) { - return setHeaderHeightPx(dp2px(heightDp)); - } - @Override - public SmartRefreshLayout setHeaderHeightPx(int heightPx) { - if (mHeaderHeightStatus.canReplaceWith(DimensionStatus.CodeExact)) { - mHeaderHeight = heightPx; - mHeaderExtendHeight = (int) Math.max((heightPx * (mHeaderMaxDragRate - 1)), 0); - if (mRefreshHeader != null) { - mHeaderHeightStatus = DimensionStatus.CodeExact; - mRefreshHeader.onInitialized(mKernel, mHeaderHeight, mHeaderExtendHeight); - } else { - mHeaderHeightStatus = DimensionStatus.CodeExactUnNotify; - } - } - return this; - } - - @Override - public SmartRefreshLayout setDragRate(float rate) { - this.mDragRate = rate; - return this; - } - - /** - * 设置下拉最大高度和Header高度的比率(将会影响可以下拉的最大高度) - */ - @Override - public SmartRefreshLayout setHeaderMaxDragRate(float rate) { - this.mHeaderMaxDragRate = rate; - this.mHeaderExtendHeight = (int) Math.max((mHeaderHeight * (mHeaderMaxDragRate - 1)), 0); - if (mRefreshHeader != null) { - mRefreshHeader.onInitialized(mKernel, mHeaderHeight, mHeaderExtendHeight); - } - return this; - } - - /** - * 设置上啦最大高度和Footer高度的比率(将会影响可以上啦的最大高度) - */ - @Override - public SmartRefreshLayout setFooterMaxDragRate(float rate) { - this.mFooterMaxDragRate = rate; - this.mFooterExtendHeight = (int) Math.max((mFooterHeight * (mFooterMaxDragRate - 1)), 0); - if (mRefreshFooter != null) { - mRefreshFooter.onInitialized(mKernel, mFooterHeight, mFooterExtendHeight); - } - return this; - } - - /** - * 设置回弹显示插值器 - */ - @Override - public SmartRefreshLayout setReboundInterpolator(Interpolator interpolator) { - this.mReboundInterpolator = interpolator; - return this; - } - - /** - * 设置回弹动画时长 - */ - @Override - public SmartRefreshLayout setReboundDuration(int duration) { - this.mReboundDuration = duration; - return this; - } - - /** - * 设置是否启用上啦加载更多(默认启用) - */ - @Override - public SmartRefreshLayout setEnableLoadmore(boolean enable) { - this.mEnableLoadmore = enable; - return this; - } - - /** - * 是否启用下拉刷新(默认启用) - */ - @Override - public SmartRefreshLayout setEnableRefresh(boolean enable) { - this.mEnableRefresh = enable; - return this; - } - - /** - * 设置是否启用内容视图拖动效果 - */ - @Override - public SmartRefreshLayout setEnableHeaderTranslationContent(boolean enable) { - this.mEnableHeaderTranslationContent = enable; - return this; - } - - /** - * 设置是否启用内容视图拖动效果 - */ - @Override - public SmartRefreshLayout setEnableFooterTranslationContent(boolean enable) { - this.mEnableFooterTranslationContent = enable; - return this; - } - - /** - * 设置是否开启在刷新时候禁止操作内容视图 - */ - @Override - public SmartRefreshLayout setDisableContentWhenRefresh(boolean disable) { - this.mDisableContentWhenRefresh = disable; - return this; - } - - /** - * 设置是否开启在加载时候禁止操作内容视图 - */ - @Override - public SmartRefreshLayout setDisableContentWhenLoading(boolean disable) { - this.mDisableContentWhenLoading = disable; - return this; - } - - /** - * 设置是否监听列表在滚动到底部时触发加载事件 - */ - @Override - public SmartRefreshLayout setEnableAutoLoadmore(boolean enable) { - this.mEnableAutoLoadmore = enable; - return this; - } - - /** - * 设置是否启用越界回弹 - */ - @Override - public SmartRefreshLayout setEnableOverScrollBounce(boolean enable) { - this.mEnableOverScrollBounce = enable; - return this; - } - - /** - * 设置是否开启纯滚动模式 - */ - @Override - public SmartRefreshLayout setEnablePureScrollMode(boolean enable) { - this.mEnablePureScrollMode = enable; - return this; - } /** - * 设置是否在加载更多完成之后滚动内容显示新数据 + * Set the header of RefreshLayout. + * 设置指定的 Header + * @param header RefreshHeader 刷新头 + * @return RefreshLayout */ @Override - public SmartRefreshLayout setEnableScrollContentWhenLoaded(boolean enable) { - this.mEnableScrollContentWhenLoaded = enable; - return this; - } - - /** - * 设置指定的Header - */ - @Override - public SmartRefreshLayout setRefreshHeader(RefreshHeader header) { - if (mRefreshHeader != null) { - removeView(mRefreshHeader.getView()); - } - this.mRefreshHeader = header; - this.mHeaderHeightStatus = mHeaderHeightStatus.unNotify(); - this.addView(mRefreshHeader.getView()); - return this; + public RefreshLayout setRefreshHeader(@NonNull RefreshHeader header) { + return setRefreshHeader(header, MATCH_PARENT, WRAP_CONTENT); } /** - * 设置指定的Header + * Set the header of RefreshLayout. + * 设置指定的 Header + * @param header RefreshHeader 刷新头 + * @param width the width in px, can use MATCH_PARENT and WRAP_CONTENT. + * 宽度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @param height the height in px, can use MATCH_PARENT and WRAP_CONTENT. + * 高度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @return RefreshLayout */ @Override - public SmartRefreshLayout setRefreshHeader(RefreshHeader header, int width, int height) { - if (mRefreshHeader != null) { - removeView(mRefreshHeader.getView()); - } - this.mRefreshHeader = header; - this.mHeaderHeightStatus = mHeaderHeightStatus.unNotify(); - this.addView(mRefreshHeader.getView(), width, height); + public RefreshLayout setRefreshHeader(@NonNull RefreshHeader header, int width, int height) { + super.setRefreshHeader(header, width, height); return this; } /** - * 设置指定的Footer + * Set the footer of RefreshLayout. + * 设置指定的 Footer + * @param footer RefreshFooter 刷新尾巴 + * @return RefreshLayout */ @Override - public SmartRefreshLayout setRefreshFooter(RefreshFooter footer) { - if (mRefreshFooter != null) { - removeView(mRefreshFooter.getView()); - } - this.mRefreshFooter = footer; - this.mFooterHeightStatus = mFooterHeightStatus.unNotify(); - this.addView(mRefreshFooter.getView()); - return this; + public RefreshLayout setRefreshFooter(@NonNull RefreshFooter footer) { + return setRefreshFooter(footer, MATCH_PARENT, WRAP_CONTENT); } /** - * 设置指定的Footer + * Set the footer of RefreshLayout. + * 设置指定的 Footer + * @param footer RefreshFooter 刷新尾巴 + * @param width the width in px, can use MATCH_PARENT and WRAP_CONTENT. + * 宽度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @param height the height in px, can use MATCH_PARENT and WRAP_CONTENT. + * 高度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @return RefreshLayout */ @Override - public SmartRefreshLayout setRefreshFooter(RefreshFooter footer, int width, int height) { - if (mRefreshFooter != null) { - removeView(mRefreshFooter.getView()); - } - this.mRefreshFooter = footer; - this.mFooterHeightStatus = mFooterHeightStatus.unNotify(); - this.addView(mRefreshFooter.getView(), width, height); + public RefreshLayout setRefreshFooter(@NonNull RefreshFooter footer, int width, int height) { + super.setRefreshFooter(footer, width, height); return this; } /** - * 获取底部上啦组件的实现 + * Get footer of RefreshLayout + * 获取当前 Footer + * @return RefreshLayout */ @Nullable @Override public RefreshFooter getRefreshFooter() { - return mRefreshFooter; + return mRefreshFooter instanceof RefreshFooter ? (RefreshFooter) mRefreshFooter : null; } /** - * 获取顶部下拉组件的实现 + * Get header of RefreshLayout + * 获取当前 Header + * @return RefreshLayout */ @Nullable @Override public RefreshHeader getRefreshHeader() { - return mRefreshHeader; + return mRefreshHeader instanceof RefreshHeader ? (RefreshHeader) mRefreshHeader : null; } - /** - * 获取状态 - */ - @Override - public RefreshState getState() { - return mState; - } +// /** +// * Get the current state of RefreshLayout +// * 获取当前状态 +// * @return RefreshLayout +// */ +// @NonNull +// @Override +// public RefreshState getState() { +// return mState; +// } - /** - * 获取实体布局视图 - */ - @Override - public SmartRefreshLayout getLayout() { - return this; - } /** + * Set refresh listener separately. * 单独设置刷新监听器 + * @param listener OnRefreshListener 刷新监听器 + * @return RefreshLayout */ @Override - public SmartRefreshLayout setOnRefreshListener(OnRefreshListener listener) { - this.mRefreshListener = listener; + public RefreshLayout setOnRefreshListener(final OnRefreshListener listener) { + super.setOnRefreshListener(new com.scwang.smart.refresh.layout.listener.OnRefreshListener() { + @Override + public void onRefresh(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout) { + listener.onRefresh(SmartRefreshLayout.this); + } + }); return this; } /** + * Set load more listener separately. * 单独设置加载监听器 + * @param listener OnLoadMoreListener 加载监听器 + * @return RefreshLayout */ @Override - public SmartRefreshLayout setOnLoadmoreListener(OnLoadmoreListener listener) { - this.mLoadmoreListener = listener; + public RefreshLayout setOnLoadMoreListener(final OnLoadMoreListener listener) { + super.setOnLoadMoreListener(new com.scwang.smart.refresh.layout.listener.OnLoadMoreListener() { + @Override + public void onLoadMore(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout) { + listener.onLoadMore(SmartRefreshLayout.this); + } + }); return this; } /** + * Set refresh and load listeners at the same time. * 同时设置刷新和加载监听器 + * @param listener OnRefreshLoadMoreListener 刷新加载监听器 + * @return RefreshLayout */ @Override - public SmartRefreshLayout setOnRefreshLoadmoreListener(OnRefreshLoadmoreListener listener) { - this.mRefreshListener = listener; - this.mLoadmoreListener = listener; - return this; - } + public RefreshLayout setOnRefreshLoadMoreListener(final OnRefreshLoadMoreListener listener) { + super.setOnRefreshLoadMoreListener(new com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener() { + @Override + public void onLoadMore(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout) { + listener.onLoadMore(SmartRefreshLayout.this); + } - /** - * 设置多功能监听器 - */ - @Override - public SmartRefreshLayout setOnMultiPurposeListener(OnMultiPurposeListener listener) { - this.mOnMultiPurposeListener = listener; + @Override + public void onRefresh(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout) { + listener.onRefresh(SmartRefreshLayout.this); + } + }); return this; } /** - * 设置主题颜色 - */ - @Override - public SmartRefreshLayout setPrimaryColorsId(@ColorRes int... primaryColorId) { - int[] colors = new int[primaryColorId.length]; - for (int i = 0; i < primaryColorId.length; i++) { - colors[i] = ContextCompat.getColor(getContext(), primaryColorId[i]); - } - setPrimaryColors(colors); - return this; - } - /** - * 设置主题颜色 + * Set up a multi-function listener. + * Recommended {@link com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener} + * 设置多功能监听器 + * 建议使用 {@link com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener} + * @param listener OnMultiPurposeListener 多功能监听器 + * @return RefreshLayout */ @Override - public SmartRefreshLayout setPrimaryColors(int... colors) { - if (mRefreshHeader != null) { - mRefreshHeader.setPrimaryColors(colors); - } - if (mRefreshFooter != null) { - mRefreshFooter.setPrimaryColors(colors); - } - mPrimaryColors = colors; + public RefreshLayout setOnMultiPurposeListener(OnMultiPurposeListener listener) { + super.setOnMultiListener(new SimpleMultiPurposeListener(listener, this)); return this; } /** - * 设置滚动边界 + * Set the scroll boundary Decider, Can customize when you can refresh. + * Recommended {@link com.scwang.smartrefresh.layout.impl.ScrollBoundaryDeciderAdapter} + * 设置滚动边界判断器 + * 建议使用 {@link com.scwang.smartrefresh.layout.impl.ScrollBoundaryDeciderAdapter} + * @param boundary ScrollBoundaryDecider 判断器 + * @return RefreshLayout */ @Override - public RefreshLayout setRefreshScrollBoundary(RefreshScrollBoundary boundary) { - if (mRefreshContent != null) { - mRefreshContent.setRefreshScrollBoundary(boundary); - } - return this; - } + public RefreshLayout setScrollBoundaryDecider(final ScrollBoundaryDecider boundary) { + super.setScrollBoundaryDecider(new ScrollBoundaryDecider() { + @Override + public boolean canRefresh(View content) { + return boundary.canRefresh(content); + } - /** - * 设置数据全部加载完成,将不能再次触发加载功能 - */ - @Override - public SmartRefreshLayout setLoadmoreFinished(boolean finished) { - mLoadmoreFinished = finished; - if (mRefreshFooter != null) { - mRefreshFooter.setLoadmoreFinished(finished); - } + @Override + public boolean canLoadMore(View content) { + return boundary.canLoadMore(content); + } + }); return this; } /** - * 完成刷新 - */ - @Override - public SmartRefreshLayout finishRefresh(){ - long passTime = System.currentTimeMillis() - mLastRefreshingTime; - return finishRefresh(Math.max(0, 1000 - (int)passTime));//保证刷新动画有1000毫秒的时间 - } - /** - * 完成加载 - */ - @Override - public SmartRefreshLayout finishLoadmore(){ - long passTime = System.currentTimeMillis() - mLastLoadingTime; - return finishLoadmore(Math.max(0, 1000 - (int)passTime));//保证加载动画有1000毫秒的时间 - } - /** - * 完成刷新 - */ - @Override - public SmartRefreshLayout finishRefresh(int delayed){ - return finishRefresh(delayed,true); - } - - /** - * 完成刷新 - */ - @Override - public SmartRefreshLayout finishRefresh(boolean success){ - long passTime = System.currentTimeMillis() - mLastRefreshingTime; - return finishRefresh(Math.max(0, 1000 - (int)passTime),true); - } - - /** - * 完成刷新 + * 设置默认 Header 构建器 + * @param creator Header构建器 */ - @Override - public SmartRefreshLayout finishRefresh(int delayed, final boolean success) { - postDelayed(new Runnable() { + public static void setDefaultRefreshHeaderCreator(@NonNull final DefaultRefreshHeaderCreator creator) { + com.scwang.smart.refresh.layout.SmartRefreshLayout.setDefaultRefreshHeaderCreator(new com.scwang.smart.refresh.layout.listener.DefaultRefreshHeaderCreator() { + @NonNull @Override - public void run() { - if (mState == RefreshState.Refreshing && mRefreshHeader != null) { - int startDelay = mRefreshHeader.onFinish(SmartRefreshLayout.this, success); - if (startDelay == Integer.MAX_VALUE) { - return; - } - SmartRefreshLayout.this.notifyStateChanged(RefreshState.RefreshFinish); - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onHeaderFinish(mRefreshHeader, success); - } - if (mSpinner == 0) { - SmartRefreshLayout.this.resetStatus(); - } else { - SmartRefreshLayout.this.animSpinner(0, startDelay); - } + public com.scwang.smart.refresh.layout.api.RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull com.scwang.smart.refresh.layout.api.RefreshLayout layout) { + if (layout instanceof RefreshLayout) { + return creator.createRefreshHeader(context, (RefreshLayout) layout); + } else { + return new BezierRadarHeader(context); } } - }, delayed); - return this; - } - /** - * 完成加载 - */ - @Override - public SmartRefreshLayout finishLoadmore(int delayed) { - return finishLoadmore(delayed, true); + }); } /** - * 完成加载 - */ - @Override - public SmartRefreshLayout finishLoadmore(boolean success){ - long passTime = System.currentTimeMillis() - mLastLoadingTime; - return finishLoadmore(Math.max(0, 1000 - (int)passTime),true); - } - /** - * 完成加载 + * 设置默认 Footer 构建器 + * @param creator Footer构建器 */ - @Override - public SmartRefreshLayout finishLoadmore(int delayed, final boolean success) { - postDelayed(new Runnable() { + public static void setDefaultRefreshFooterCreator(@NonNull final DefaultRefreshFooterCreator creator) { + com.scwang.smart.refresh.layout.SmartRefreshLayout.setDefaultRefreshFooterCreator(new com.scwang.smart.refresh.layout.listener.DefaultRefreshFooterCreator() { + @NonNull @Override - public void run() { - if (mState == RefreshState.Loading && mRefreshFooter != null) { - int startDelay = mRefreshFooter.onFinish(SmartRefreshLayout.this, success); - if (startDelay == Integer.MAX_VALUE) { - return; - } - SmartRefreshLayout.this.notifyStateChanged(RefreshState.LoadingFinish); - AnimatorUpdateListener updateListener = mRefreshContent.onLoadingFinish(mKernel, mFooterHeight, startDelay, mReboundInterpolator, mReboundDuration); - if (mOnMultiPurposeListener != null) { - mOnMultiPurposeListener.onFooterFinish(mRefreshFooter, success); - } - if (mSpinner == 0) { - SmartRefreshLayout.this.postDelayed(new Runnable() { - @Override - public void run() { - SmartRefreshLayout.this.resetStatus(); - } - }, 500); - } else { - ValueAnimator valueAnimator = SmartRefreshLayout.this.animSpinner(0, startDelay); - if (updateListener != null && valueAnimator != null) { - valueAnimator.addUpdateListener(updateListener); - } - } + public com.scwang.smart.refresh.layout.api.RefreshFooter createRefreshFooter(@NonNull Context context, @NonNull com.scwang.smart.refresh.layout.api.RefreshLayout layout) { + if (layout instanceof RefreshLayout) { + return creator.createRefreshFooter(context, (RefreshLayout) layout); + } else { + return new BallPulseFooter(context); } } - }, delayed); - return this; - } - /** - * 是否正在刷新 - */ - @Override - public boolean isRefreshing() { - return mState == RefreshState.Refreshing; - } - /** - * 是否正在加载 - */ - @Override - public boolean isLoading() { - return mState == RefreshState.Loading; - } - /** - * 自动刷新 - */ - @Override - public boolean autoRefresh() { - return autoRefresh(500); - } - /** - * 自动刷新 - */ - @Override - public boolean autoRefresh(int delayed) { - return autoRefresh(delayed, 1f * (mHeaderHeight + mHeaderExtendHeight / 2) / mHeaderHeight); + }); } - /** - * 自动刷新 - */ - @Override - public boolean autoRefresh(int delayed, final float dragrate) { - if (mState == RefreshState.None && isEnableRefresh()) { - if (reboundAnimator != null) { - reboundAnimator.cancel(); - } - reboundAnimator = new ValueAnimator(); - postDelayed(new Runnable() { - @Override - public void run() { - reboundAnimator = ValueAnimator.ofInt(mSpinner, (int) (mHeaderHeight * dragrate)); - reboundAnimator.setDuration(mReboundDuration); - reboundAnimator.setInterpolator(new DecelerateInterpolator()); - reboundAnimator.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - SmartRefreshLayout.this.moveSpinner((int) animation.getAnimatedValue(), false); - } - }); - reboundAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - setStatePullDownToRefresh(); - } - @Override - public void onAnimationEnd(Animator animation) { - reboundAnimator = null; - if (mState != RefreshState.ReleaseToRefresh) { - setStateReleaseToRefresh(); - } - overSpinner(); - } - }); - reboundAnimator.start(); - } - }, delayed); - return true; - } else { - return false; - } - } - /** - * 自动加载 - */ - @Override - public boolean autoLoadmore() { - return autoLoadmore(500); - } /** - * 自动加载 + * 设置默认 Refresh 初始化器 + * @param initializer 全局初始化器 */ - @Override - public boolean autoLoadmore(int delayed) { - return autoLoadmore(delayed, 1f * (mFooterHeight + mFooterExtendHeight / 2) / mFooterHeight); - } - /** - * 自动加载 - */ - @Override - public boolean autoLoadmore(int delayed, final float dragrate) { - if (mState == RefreshState.None && isEnableLoadmore()) { - if (reboundAnimator != null) { - reboundAnimator.cancel(); - } - reboundAnimator = new ValueAnimator(); - postDelayed(new Runnable() { - @Override - public void run() { - reboundAnimator = ValueAnimator.ofInt(mSpinner, -(int) (mFooterHeight * dragrate)); - reboundAnimator.setDuration(mReboundDuration); - reboundAnimator.setInterpolator(new DecelerateInterpolator()); - reboundAnimator.addUpdateListener(new AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - SmartRefreshLayout.this.moveSpinner((int) animation.getAnimatedValue(), false); - } - }); - reboundAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - setStatePullUpToLoad(); - } - - @Override - public void onAnimationEnd(Animator animation) { - reboundAnimator = null; - if (mState != RefreshState.ReleaseToLoad) { - setStateReleaseToLoad(); - } - overSpinner(); - } - }); - reboundAnimator.start(); + public static void setDefaultRefreshInitializer(@NonNull final DefaultRefreshInitializer initializer) { + com.scwang.smart.refresh.layout.SmartRefreshLayout.setDefaultRefreshInitializer(new com.scwang.smart.refresh.layout.listener.DefaultRefreshInitializer() { + @Override + public void initialize(@NonNull Context context, @NonNull com.scwang.smart.refresh.layout.api.RefreshLayout layout) { + if (layout instanceof RefreshLayout) { + initializer.initialize(context, (RefreshLayout)layout); } - }, delayed); - return true; - } else { - return false; - } - } - - @Override - public boolean isEnableLoadmore() { - return mEnableLoadmore && !mLoadmoreFinished; - } - - @Override - public boolean isLoadmoreFinished() { - return mLoadmoreFinished; - } - - @Override - public boolean isEnableAutoLoadmore() { - return mEnableAutoLoadmore; - } - - @Override - public boolean isEnableRefresh() { - return mEnableRefresh; - } - - @Override - public boolean isEnableOverScrollBounce() { - return mEnableOverScrollBounce; - } - - @Override - public boolean isEnablePureScrollMode() { - return mEnablePureScrollMode; - } - - @Override - public boolean isEnableScrollContentWhenLoaded() { - return mEnableScrollContentWhenLoaded; - } - - /** - * 设置默认Header构建器 - */ - public static void setDefaultRefreshHeaderCreater(@NonNull DefaultRefreshHeaderCreater creater) { - mHeaderCreater = creater; - } - - /** - * 设置默认Footer构建器 - */ - public static void setDefaultRefreshFooterCreater(@NonNull DefaultRefreshFooterCreater creater) { - mFooterCreater = creater; - } - - // - - // - protected class RefreshKernelImpl implements RefreshKernel { - @NonNull - @Override - public RefreshLayout getRefreshLayout() { - return SmartRefreshLayout.this; - } - - @NonNull - @Override - public RefreshContent getRefreshContent() { - return SmartRefreshLayout.this.mRefreshContent; - } - - // - public RefreshKernel setStatePullUpToLoad() { - SmartRefreshLayout.this.setStatePullUpToLoad(); - return this; - } - public RefreshKernel setStateReleaseToLoad() { - SmartRefreshLayout.this.setStateReleaseToLoad(); - return this; - } - public RefreshKernel setStateReleaseToRefresh() { - SmartRefreshLayout.this.setStateReleaseToRefresh(); - return this; - } - public RefreshKernel setStatePullDownToRefresh() { - SmartRefreshLayout.this.setStatePullDownToRefresh(); - return this; - } - public RefreshKernel setStatePullDownCanceled() { - SmartRefreshLayout.this.setStatePullDownCanceled(); - return this; - } - public RefreshKernel setStatePullUpCanceled() { - SmartRefreshLayout.this.setStatePullUpCanceled(); - return this; - } - public RefreshKernel setStateLoding() { - SmartRefreshLayout.this.setStateLoding(); - return this; - } - public RefreshKernel setStateRefresing() { - SmartRefreshLayout.this.setStateRefresing(); - return this; - } - public RefreshKernel resetStatus() { - SmartRefreshLayout.this.resetStatus(); - return this; - } - // - - // - public RefreshKernel overSpinner() { - SmartRefreshLayout.this.overSpinner(); - return this; - } - public RefreshKernel moveSpinnerInfinitely(float dy) { - SmartRefreshLayout.this.moveSpinnerInfinitely(dy); - return this; - } - public RefreshKernel moveSpinner(int spinner, boolean isAnimator) { - SmartRefreshLayout.this.moveSpinner(spinner, isAnimator); - return this; - } - public RefreshKernel animSpinner(int endSpinner) { - SmartRefreshLayout.this.animSpinner(endSpinner); - return this; - } - @Override - public RefreshKernel animSpinnerBounce(int bounceSpinner) { - SmartRefreshLayout.this.animSpinnerBounce(bounceSpinner); - return this; - } - - @Override - public int getSpinner() { - return mSpinner; - } - // - - // - public RefreshKernel requestDrawBackgoundForHeader(int backgroundColor) { - if (mPaint == null && backgroundColor != 0) { - mPaint = new Paint(); } - mHeaderBackgroundColor = backgroundColor; - return this; - } - public RefreshKernel requestDrawBackgoundForFooter(int backgroundColor) { - if (mPaint == null && backgroundColor != 0) { - mPaint = new Paint(); - } - mFooterBackgroundColor = backgroundColor; - return this; - } - // + }); } // + } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshFooterCreater.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshFooterCreater.java deleted file mode 100644 index 05f28236..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshFooterCreater.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.scwang.smartrefresh.layout.api; - -import android.content.Context; -import android.support.annotation.NonNull; - -/** - * 默认Footer创建器 - * Created by SCWANG on 2017/5/26. - */ - -public interface DefaultRefreshFooterCreater { - @NonNull - RefreshFooter createRefreshFooter(Context context, RefreshLayout layout); -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshFooterCreator.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshFooterCreator.java new file mode 100644 index 00000000..16dd939f --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshFooterCreator.java @@ -0,0 +1,13 @@ +package com.scwang.smartrefresh.layout.api; + +import android.content.Context; +import android.support.annotation.NonNull; + +/** + * 默认Footer创建器 + * Created by scwang on 2018/1/26. + */ +public interface DefaultRefreshFooterCreator { + @NonNull + RefreshFooter createRefreshFooter(@NonNull Context context, @NonNull RefreshLayout layout); +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshHeaderCreater.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshHeaderCreater.java deleted file mode 100644 index df579624..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshHeaderCreater.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.scwang.smartrefresh.layout.api; - -import android.content.Context; -import android.support.annotation.NonNull; - -/** - * 默认Header创建器 - * Created by SCWANG on 2017/5/26. - */ - -public interface DefaultRefreshHeaderCreater { - @NonNull - RefreshHeader createRefreshHeader(Context context, RefreshLayout layout); -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshHeaderCreator.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshHeaderCreator.java new file mode 100644 index 00000000..628607ae --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshHeaderCreator.java @@ -0,0 +1,13 @@ +package com.scwang.smartrefresh.layout.api; + +import android.content.Context; +import android.support.annotation.NonNull; + +/** + * 默认Header创建器 + * Created by scwang on 2018/1/26. + */ +public interface DefaultRefreshHeaderCreator { + @NonNull + RefreshHeader createRefreshHeader(@NonNull Context context, @NonNull RefreshLayout layout); +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshInitializer.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshInitializer.java new file mode 100644 index 00000000..90fe2bf5 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/DefaultRefreshInitializer.java @@ -0,0 +1,12 @@ +package com.scwang.smartrefresh.layout.api; + +import android.content.Context; +import android.support.annotation.NonNull; + +/** + * 默认全局初始化器 + * Created by scwang on 2018/5/29 0029. + */ +public interface DefaultRefreshInitializer { + void initialize(@NonNull Context context, @NonNull RefreshLayout layout); +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/OnTwoLevelListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/OnTwoLevelListener.java new file mode 100644 index 00000000..3784f4a1 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/OnTwoLevelListener.java @@ -0,0 +1,15 @@ +package com.scwang.smartrefresh.layout.api; + +import android.support.annotation.NonNull; + +/** + * 二级刷新监听器 + */ +public interface OnTwoLevelListener { + /** + * 二级刷新触发 + * @param refreshLayout 刷新布局 + * @return true 将会展开二楼状态 false 关闭刷新 + */ + boolean onTwoLevel(@NonNull RefreshLayout refreshLayout); +} \ No newline at end of file diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshContent.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshContent.java deleted file mode 100644 index 45bc822a..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshContent.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.scwang.smartrefresh.layout.api; - -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.Interpolator; - -/** - * 刷新内容组件 - * Created by SCWANG on 2017/5/26. - */ - -public interface RefreshContent { - void moveSpinner(int spinner); - boolean canScrollUp(); - boolean canScrollDown(); - int getMeasuredWidth(); - int getMeasuredHeight(); - void measure(int widthSpec, int heightSpec); - void layout(int left, int top, int right, int bottom); - - View getView(); - View getScrollableView(); - ViewGroup.LayoutParams getLayoutParams(); - - void onActionDown(MotionEvent e); - void onActionUpOrCancel(); - - void setupComponent(RefreshKernel kernel, View fixedHeader, View fixedFooter); - void onInitialHeaderAndFooter(int headerHeight, int footerHeight); - void setRefreshScrollBoundary(RefreshScrollBoundary boundary); - - boolean isNestedScrollingChild(MotionEvent e); - - AnimatorUpdateListener onLoadingFinish(RefreshKernel layout, int footerHeight, int startDelay, Interpolator reboundInterpolator, int reboundDuration); - -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshFooter.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshFooter.java index 73bcad60..8983c83e 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshFooter.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshFooter.java @@ -2,30 +2,8 @@ /** * 刷新底部 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ +public interface RefreshFooter extends com.scwang.smart.refresh.layout.api.RefreshFooter { -public interface RefreshFooter extends RefreshInternal { - /** - * 手指拖动下拉(会连续多次调用) - * @param percent 下拉的百分比 值 = offset/footerHeight (0 - percent - (footerHeight+extendHeight) / footerHeight ) - * @param offset 下拉的像素偏移量 0 - offset - (footerHeight+extendHeight) - * @param footerHeight Footer的高度 - * @param extendHeight Footer的扩展高度 - */ - void onPullingUp(float percent,int offset, int footerHeight, int extendHeight); - /** - * 手指释放之后的持续动画(会连续多次调用) - * @param percent 下拉的百分比 值 = offset/footerHeight (0 - percent - (footerHeight+extendHeight) / footerHeight ) - * @param offset 下拉的像素偏移量 0 - offset - (footerHeight+extendHeight) - * @param footerHeight Footer的高度 - * @param extendHeight Footer的扩展高度 - */ - void onPullReleasing(float percent,int offset, int footerHeight, int extendHeight); - - /** - * 设置数据全部加载完成,将不能再次触发加载功能 - * @return true 支持全部加载完成的状态显示 false 不支持 - */ - boolean setLoadmoreFinished(boolean finished); } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshHeader.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshHeader.java index cbe9a5db..8fd9b26b 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshHeader.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshHeader.java @@ -2,25 +2,8 @@ /** * 刷新头部 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ +public interface RefreshHeader extends com.scwang.smart.refresh.layout.api.RefreshHeader { -public interface RefreshHeader extends RefreshInternal { - /** - * 手指拖动下拉(会连续多次调用) - * @param percent 下拉的百分比 值 = offset/headerHeight (0 - percent - (headerHeight+extendHeight) / headerHeight ) - * @param offset 下拉的像素偏移量 0 - offset - (headerHeight+extendHeight) - * @param headerHeight Header的高度 - * @param extendHeight Header的扩展高度 - */ - void onPullingDown(float percent, int offset, int headerHeight, int extendHeight); - - /** - * 手指释放之后的持续动画 - * @param percent 下拉的百分比 值 = offset/headerHeight (0 - percent - (headerHeight+extendHeight) / headerHeight ) - * @param offset 下拉的像素偏移量 0 - offset - (headerHeight+extendHeight) - * @param headerHeight Header的高度 - * @param extendHeight Header的扩展高度 - */ - void onReleasing(float percent, int offset, int headerHeight, int extendHeight); } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshInternal.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshInternal.java index 6f526b1a..e85eb0e9 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshInternal.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshInternal.java @@ -1,56 +1,21 @@ package com.scwang.smartrefresh.layout.api; import android.support.annotation.NonNull; -import android.view.View; +import com.scwang.smart.refresh.layout.api.RefreshComponent; import com.scwang.smartrefresh.layout.constant.SpinnerStyle; -import com.scwang.smartrefresh.layout.listener.OnStateChangedListener; /** * 刷新内部组件 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ +public interface RefreshInternal extends RefreshComponent { -public interface RefreshInternal extends OnStateChangedListener { /** - * 获取实体视图 + * 获取变换方式 {@link SpinnerStyle} 必须返回 非空 + * @return 变换方式 */ @NonNull - View getView(); - - /** - * 获取变换方式 {@link SpinnerStyle} - */ SpinnerStyle getSpinnerStyle(); - - /** - * 设置主题颜色 - * @param colors 对应Xml中配置的 srlPrimaryColor srlAccentColor - */ - void setPrimaryColors(int... colors); - - /** - * 尺寸定义完成 (如果高度不改变(代码修改:setHeader),只调用一次, 在RefreshLayout#onMeasure中调用) - * @param kernel RefreshKernel - * @param height HeaderHeight or FooterHeight - * @param extendHeight extendHeaderHeight or extendFooterHeight - */ - void onInitialized(RefreshKernel kernel, int height, int extendHeight); - - /** - * 开始动画 - * @param layout RefreshLayout - * @param height HeaderHeight or FooterHeight - * @param extendHeight extendHeaderHeight or extendFooterHeight - */ - void onStartAnimator(RefreshLayout layout, int height, int extendHeight); - - /** - * 动画结束 - * @param layout RefreshLayout - * @param success 数据是否成功刷新或加载 - * @return 完成动画所需时间 如果返回 Integer.MAX_VALUE 将取消本次完成事件,继续保持原有状态 - */ - int onFinish(RefreshLayout layout, boolean success); } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshKernel.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshKernel.java index c1499837..c68dd02b 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshKernel.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshKernel.java @@ -1,87 +1,10 @@ package com.scwang.smartrefresh.layout.api; -import android.support.annotation.NonNull; - /** * 刷新布局核心功能接口 * 为功能复杂的 Header 或者 Footer 开放的接口 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ - -public interface RefreshKernel { - - @NonNull - RefreshLayout getRefreshLayout(); - @NonNull - RefreshContent getRefreshContent(); - - // - RefreshKernel setStatePullUpToLoad(); - RefreshKernel setStateReleaseToLoad() ; - RefreshKernel setStateReleaseToRefresh() ; - RefreshKernel setStatePullDownToRefresh() ; - RefreshKernel setStatePullDownCanceled() ; - RefreshKernel setStatePullUpCanceled() ; - RefreshKernel setStateLoding() ; - RefreshKernel setStateRefresing() ; - RefreshKernel resetStatus(); - // - - // - - /** - * 结束视图位移(调用之后,如果没有在初始位移状态,会执行动画回到初始位置) - * moveSpinner 的取名来自 谷歌官方的 @{@link android.support.v4.widget.SwipeRefreshLayout#moveSpinner(float)} - */ - RefreshKernel overSpinner() ; - - /** - * 移动视图到预设距离(dy 会被内部函数计算,将会出现无限接近最大值(height+extendHeader)的阻尼效果) - * moveSpinner 的取名来自 谷歌官方的 @{@link android.support.v4.widget.SwipeRefreshLayout#moveSpinner(float)} - * @param dy 距离 (px) 大于0表示下拉 小于0表示上啦 - */ - RefreshKernel moveSpinnerInfinitely(float dy); - - /** - * 移动视图到指定位置 - * moveSpinner 的取名来自 谷歌官方的 @{@link android.support.v4.widget.SwipeRefreshLayout#moveSpinner(float)} - * @param spinner 位置 (px) - * @param isAnimator 标记是否是动画执行 - */ - RefreshKernel moveSpinner(int spinner, boolean isAnimator); - - /** - * 执行动画使视图位移到指定的 位置 - * moveSpinner 的取名来自 谷歌官方的 @{@link android.support.v4.widget.SwipeRefreshLayout#moveSpinner(float)} - * @param endSpinner 指定的结束位置 (px) - */ - RefreshKernel animSpinner(int endSpinner); - - /** - * 回弹动画 - * @param bounceSpinner 回弹的最大位置 (px) - */ - RefreshKernel animSpinnerBounce(int bounceSpinner); - - /** - * 获取 Spinner - */ - int getSpinner(); - // - - // - - /** - * 指定在下拉时候为 Header 绘制背景 - * @param backgroundColor 背景颜色 - */ - RefreshKernel requestDrawBackgoundForHeader(int backgroundColor); - /** - * 指定在下拉时候为 Footer 绘制背景 - * @param backgroundColor 背景颜色 - */ - RefreshKernel requestDrawBackgoundForFooter(int backgroundColor); - - // +public interface RefreshKernel extends com.scwang.smart.refresh.layout.api.RefreshKernel { } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshLayout.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshLayout.java index 0288db3e..1cdb1cc1 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshLayout.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshLayout.java @@ -1,282 +1,127 @@ package com.scwang.smartrefresh.layout.api; -import android.support.annotation.ColorRes; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.view.NestedScrollingChild; -import android.support.v4.view.NestedScrollingParent; -import android.view.ViewGroup; -import android.view.animation.Interpolator; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.listener.OnLoadmoreListener; +import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener; import com.scwang.smartrefresh.layout.listener.OnMultiPurposeListener; import com.scwang.smartrefresh.layout.listener.OnRefreshListener; -import com.scwang.smartrefresh.layout.listener.OnRefreshLoadmoreListener; +import com.scwang.smartrefresh.layout.listener.OnRefreshLoadMoreListener; /** * 刷新布局 - * Created by SCWANG on 2017/5/26. + * interface of the refresh layout + * Created by scwang on 2017/5/26. */ - -public interface RefreshLayout extends NestedScrollingParent, NestedScrollingChild { - - RefreshLayout setFooterHeight(float dp); - - RefreshLayout setFooterHeightPx(int px); - - RefreshLayout setHeaderHeight(float dp); - - RefreshLayout setHeaderHeightPx(int px); - - /** - * 显示拖动高度/真实拖动高度(默认0.5,阻尼效果) - */ - RefreshLayout setDragRate(float rate); - - /** - * 设置下拉最大高度和Header高度的比率(将会影响可以下拉的最大高度) - */ - RefreshLayout setHeaderMaxDragRate(float rate); - - /** - * 设置上啦最大高度和Footer高度的比率(将会影响可以上啦的最大高度) - */ - RefreshLayout setFooterMaxDragRate(float rate); - - /** - * 设置回弹显示插值器 - */ - RefreshLayout setReboundInterpolator(Interpolator interpolator); - - /** - * 设置回弹动画时长 - */ - RefreshLayout setReboundDuration(int duration); - - /** - * 设置是否启用上啦加载更多(默认启用) - */ - RefreshLayout setEnableLoadmore(boolean enable); +@SuppressWarnings("UnusedReturnValue") +public interface RefreshLayout extends com.scwang.smart.refresh.layout.api.RefreshLayout { /** - * 是否启用下拉刷新(默认启用) + * Set the footer of RefreshLayout. + * 设置指定的 Footer + * @param footer RefreshFooter 刷新尾巴 + * @return RefreshLayout */ - RefreshLayout setEnableRefresh(boolean enable); + RefreshLayout setRefreshFooter(@NonNull RefreshFooter footer); /** - * 设置是否启在下拉Header的同时下拉内容 + * Set the footer of RefreshLayout. + * 设置指定的 Footer + * @param footer RefreshFooter 刷新尾巴 + * @param width the width in px, can use MATCH_PARENT and WRAP_CONTENT. + * 宽度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @param height the height in px, can use MATCH_PARENT and WRAP_CONTENT. + * 高度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @return RefreshLayout */ - RefreshLayout setEnableHeaderTranslationContent(boolean enable); + RefreshLayout setRefreshFooter(@NonNull RefreshFooter footer, int width, int height); /** - * 设置是否启在上拉Footer的同时上拉内容 + * Set the header of RefreshLayout. + * 设置指定的 Header + * @param header RefreshHeader 刷新头 + * @return RefreshLayout */ - RefreshLayout setEnableFooterTranslationContent(boolean enable); + RefreshLayout setRefreshHeader(@NonNull RefreshHeader header); /** - * 设置是否开启在刷新时候禁止操作内容视图 + * Set the header of RefreshLayout. + * 设置指定的 Header + * @param header RefreshHeader 刷新头 + * @param width the width in px, can use MATCH_PARENT and WRAP_CONTENT. + * 宽度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @param height the height in px, can use MATCH_PARENT and WRAP_CONTENT. + * 高度 可以使用 MATCH_PARENT, WRAP_CONTENT + * @return RefreshLayout */ - RefreshLayout setDisableContentWhenRefresh(boolean disable); - - /** - * 设置是否开启在加载时候禁止操作内容视图 - */ - RefreshLayout setDisableContentWhenLoading(boolean disable); - - /** - * 设置是否监听列表在滚动到底部时触发加载事件(默认true) - */ - RefreshLayout setEnableAutoLoadmore(boolean enable); - - /** - * 设置数据全部加载完成,将不能再次触发加载功能 - */ - RefreshLayout setLoadmoreFinished(boolean finished); - - /** - * 设置指定的Header - */ - RefreshLayout setRefreshFooter(RefreshFooter bottom); - - /** - * 设置指定的Header - */ - RefreshLayout setRefreshFooter(RefreshFooter footer, int width, int height); - - /** - * 设置指定的Header - */ - RefreshLayout setRefreshHeader(RefreshHeader header); - - /** - * 设置指定的Header - */ - RefreshLayout setRefreshHeader(RefreshHeader header, int width, int height); - - /** - * 设置是否启用越界回弹 - */ - RefreshLayout setEnableOverScrollBounce(boolean enable); - - /** - * 设置是否开启纯滚动模式 - */ - RefreshLayout setEnablePureScrollMode(boolean enable); - - /** - * 设置是否在加载更多完成之后滚动内容显示新数据 - */ - RefreshLayout setEnableScrollContentWhenLoaded(boolean enable); + RefreshLayout setRefreshHeader(@NonNull RefreshHeader header, int width, int height); /** + * Set refresh listener separately. * 单独设置刷新监听器 + * @param listener OnRefreshListener 刷新监听器 + * @return RefreshLayout */ RefreshLayout setOnRefreshListener(OnRefreshListener listener); /** + * Set load more listener separately. * 单独设置加载监听器 + * @param listener OnLoadMoreListener 加载监听器 + * @return RefreshLayout */ - RefreshLayout setOnLoadmoreListener(OnLoadmoreListener listener); + RefreshLayout setOnLoadMoreListener(OnLoadMoreListener listener); /** + * Set refresh and load listeners at the same time. * 同时设置刷新和加载监听器 + * @param listener OnRefreshLoadMoreListener 刷新加载监听器 + * @return RefreshLayout */ - RefreshLayout setOnRefreshLoadmoreListener(OnRefreshLoadmoreListener listener); + RefreshLayout setOnRefreshLoadMoreListener(OnRefreshLoadMoreListener listener); /** + * Set up a multi-function listener. + * Recommended {@link com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener} * 设置多功能监听器 + * 建议使用 {@link com.scwang.smartrefresh.layout.listener.SimpleMultiPurposeListener} + * @param listener OnMultiPurposeListener 多功能监听器 + * @return RefreshLayout */ RefreshLayout setOnMultiPurposeListener(OnMultiPurposeListener listener); /** - * 设置主题颜色 - */ - RefreshLayout setPrimaryColorsId(@ColorRes int... primaryColorId); - - /** - * 设置主题颜色 - */ - RefreshLayout setPrimaryColors(int... colors); - - /** - * 设置滚动边界 + * Set the scroll boundary Decider, Can customize when you can refresh. + * Recommended {@link com.scwang.smartrefresh.layout.impl.ScrollBoundaryDeciderAdapter} + * 设置滚动边界判断器 + * 建议使用 {@link com.scwang.smartrefresh.layout.impl.ScrollBoundaryDeciderAdapter} + * @param boundary ScrollBoundaryDecider 判断器 + * @return RefreshLayout */ - RefreshLayout setRefreshScrollBoundary(RefreshScrollBoundary boundary); - - /** - * 完成刷新 - */ - RefreshLayout finishRefresh(); - - /** - * 完成加载 - */ - RefreshLayout finishLoadmore(); - - /** - * 完成刷新 - */ - RefreshLayout finishRefresh(int delayed); - - /** - * 完成加载 - * @param success 数据是否成功刷新 (会影响到上次更新时间的改变) - */ - RefreshLayout finishRefresh(boolean success); - - /** - * 完成刷新 - */ - RefreshLayout finishRefresh(int delayed, boolean success); - - /** - * 完成加载 - */ - RefreshLayout finishLoadmore(int delayed); - - /** - * 完成加载 - */ - RefreshLayout finishLoadmore(boolean success); - - /** - * 完成加载 - */ - RefreshLayout finishLoadmore(int delayed, boolean success); + RefreshLayout setScrollBoundaryDecider(ScrollBoundaryDecider boundary); /** + * Get header of RefreshLayout * 获取当前 Header + * @return RefreshLayout */ @Nullable RefreshHeader getRefreshHeader(); /** + * Get footer of RefreshLayout * 获取当前 Footer + * @return RefreshLayout */ @Nullable RefreshFooter getRefreshFooter(); - /** - * 获取当前状态 - */ - RefreshState getState(); - - /** - * 获取实体布局视图 - */ - ViewGroup getLayout(); - - /** - * 是否正在刷新 - */ - boolean isRefreshing(); - - /** - * 是否正在加载 - */ - boolean isLoading(); - - /** - * 自动刷新 - */ - boolean autoRefresh(); - - /** - * 自动刷新 - */ - boolean autoRefresh(int delayed); - - /** - * 自动刷新 - */ - boolean autoRefresh(int delayed, float dragrate); - - /** - * 自动加载 - */ - boolean autoLoadmore(); - - /** - * 自动加载 - */ - boolean autoLoadmore(int delayed); - - /** - * 自动加载 - */ - boolean autoLoadmore(int delayed, float dragrate); - - boolean isEnableRefresh(); - - boolean isEnableLoadmore(); - - boolean isLoadmoreFinished(); - - boolean isEnableAutoLoadmore(); - - boolean isEnableOverScrollBounce(); - - boolean isEnablePureScrollMode(); +// /** +// * Get the current state of RefreshLayout +// * 获取当前状态 +// * @return RefreshLayout +// */ +// @NonNull +// RefreshState getState(); - boolean isEnableScrollContentWhenLoaded(); } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshScrollBoundary.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshScrollBoundary.java deleted file mode 100644 index 8668cf0e..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/RefreshScrollBoundary.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.scwang.smartrefresh.layout.api; - -import android.view.View; - -/** - * 滚动边界 - * Created by SCWANG on 2017/7/8. - */ - -public interface RefreshScrollBoundary { - /** - * 内容是否可以下拉滚动 - * @param content 内容视图 - * @return false 讲会触发下拉刷新 - */ - boolean canPullDown(View content); - /** - * 内容是否可以上拉滚动 - * @param content 内容视图 - * @return false 讲会触发加载更多 - */ - boolean canPullUp(View content); -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/ScrollBoundaryDecider.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/ScrollBoundaryDecider.java new file mode 100644 index 00000000..e5c5dc28 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/api/ScrollBoundaryDecider.java @@ -0,0 +1,8 @@ +package com.scwang.smartrefresh.layout.api; + +/** + * 滚动边界 + * Created by scwang on 2017/7/8. + */ +public interface ScrollBoundaryDecider extends com.scwang.smart.refresh.layout.listener.ScrollBoundaryDecider { +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/DimensionStatus.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/DimensionStatus.java deleted file mode 100644 index 6b363c33..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/DimensionStatus.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.scwang.smartrefresh.layout.constant; - -/** - * 尺寸值的定义状态,用于在值覆盖的时候决定优先级 - * 越往下优先级越高 - */ -public enum DimensionStatus { - DefaultUnNotify(false),//默认值,但是还没通知确认 - Default(true),//默认值 - XmlWrap(true),//Xml计算 - XmlLayoutUnNotify(false),//Xml 的layout 中指定,但是还没通知确认 - XmlLayout(true),//Xml 的layout 中指定 - XmlExact(true),//Xml 的view 指定 - CodeExactUnNotify(false),//代码指定,但是还没通知确认 - CodeExact(true),//代码指定 - DeadLockUnNotify(false),//锁死,但是还没通知确认 - DeadLock(true);//锁死 - public final boolean notifyed; - - DimensionStatus(boolean notifyed) { - this.notifyed = notifyed; - } - - /** - * 转换为未通知状态 - */ - public DimensionStatus unNotify() { - if (notifyed) { - DimensionStatus prev = values()[ordinal() - 1]; - if (!prev.notifyed) { - return prev; - } - return DefaultUnNotify; - } - return this; - } - - /** - * 转换为通知状态 - */ - public DimensionStatus notifyed() { - if (!notifyed) { - return values()[ordinal() + 1]; - } - return this; - } - - /** - * 小于等于 - */ - public boolean canReplaceWith(DimensionStatus status) { - return ordinal() < status.ordinal() || (!notifyed && ordinal() == status.ordinal()); - } - - /** - * 大于等于 - */ - public boolean gteReplaceWith(DimensionStatus status) { - return ordinal() >= status.ordinal(); - } -} \ No newline at end of file diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/RefreshState.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/RefreshState.java index 0af689df..840538aa 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/RefreshState.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/RefreshState.java @@ -1,10 +1,57 @@ package com.scwang.smartrefresh.layout.constant; +/** + * 刷新状态 + */ +@SuppressWarnings("unused") public enum RefreshState { - None, - PullDownToRefresh, PullToUpLoad, - PullDownCanceled, PullUpCanceled, - ReleaseToRefresh, ReleaseToLoad, - Refreshing, Loading, - RefreshFinish, LoadingFinish, + None(0,false,false,false,false,false), + PullDownToRefresh(1,true,false,false,false,false), PullUpToLoad(2,true,false,false,false,false), + PullDownCanceled(1,false,false,false,false,false), PullUpCanceled(2,false,false,false,false,false), + ReleaseToRefresh(1,true,false,false,false,true), ReleaseToLoad(2,true,false,false,false,true), + ReleaseToTwoLevel(1,true,false,false,true,true), TwoLevelReleased(1,false,false,false,true,false), + RefreshReleased(1,false,false,false,false,false), LoadReleased(2,false,false,false,false,false), + Refreshing(1,false,true,false,false,false), Loading(2,false,true,false,false,false), TwoLevel(1, false, true,false,true,false), + RefreshFinish(1,false,false,true,false,false), LoadFinish(2,false,false,true,false,false), TwoLevelFinish(1,false,false,true,true,false); + + public final boolean isHeader; + public final boolean isFooter; + public final boolean isTwoLevel;// 二级刷新 ReleaseToTwoLevel TwoLevelReleased TwoLevel + public final boolean isDragging;// 正在拖动状态:PullDownToRefresh PullUpToLoad ReleaseToRefresh ReleaseToLoad ReleaseToTwoLevel + public final boolean isOpening;// 正在刷新状态:Refreshing Loading TwoLevel + public final boolean isFinishing;//正在完成状态:RefreshFinish LoadFinish TwoLevelFinish + public final boolean isReleaseToOpening;// 释放立马打开 ReleaseToRefresh ReleaseToLoad ReleaseToTwoLevel + + RefreshState(int role, boolean dragging, boolean opening, boolean finishing, boolean twoLevel, boolean releaseToOpening) { + this.isHeader = role == 1; + this.isFooter = role == 2; + this.isDragging = dragging; + this.isOpening = opening; + this.isFinishing = finishing; + this.isTwoLevel = twoLevel; + this.isReleaseToOpening = releaseToOpening; + } + + public static RefreshState from(com.scwang.smart.refresh.layout.constant.RefreshState newState) { + for (RefreshState state : values()) { + if (state.ordinal() == newState.ordinal()) { + return state; + } + } + return None; + } + + public RefreshState toFooter() { + if (isHeader && !isTwoLevel) { + return values()[ordinal() + 1]; + } + return this; + } + + public RefreshState toHeader() { + if (isFooter && !isTwoLevel) { + return values()[ordinal()-1]; + } + return this; + } } \ No newline at end of file diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/SpinnerStyle.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/SpinnerStyle.java index 8af563cd..de41e328 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/SpinnerStyle.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/constant/SpinnerStyle.java @@ -2,12 +2,12 @@ /** * 顶部和底部的组件在拖动时候的变换方式 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ +public class SpinnerStyle extends com.scwang.smart.refresh.layout.constant.SpinnerStyle { + + private SpinnerStyle() { + super(-1, false, false); + } -public enum SpinnerStyle { - Translate,//平行移动 特点: HeaderView高度不会改变, - Scale,//拉伸形变 特点:在下拉和上弹(HeaderView高度改变)时候,会自动触发OnDraw事件 - FixedFront,//固定在前面 特点:HeaderView高度不会改变, - FixedBehind,//固定在背后 特点:HeaderView高度不会改变, } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/BallPulseFooter.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/BallPulseFooter.java index 6a22c83c..effb6069 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/BallPulseFooter.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/BallPulseFooter.java @@ -1,159 +1,46 @@ package com.scwang.smartrefresh.layout.footer; import android.content.Context; -import android.content.res.TypedArray; -import android.support.annotation.AttrRes; -import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v4.graphics.ColorUtils; import android.util.AttributeSet; -import android.view.View; -import android.view.ViewGroup; -import com.scwang.smartrefresh.layout.R; +import com.scwang.smart.refresh.layout.constant.SpinnerStyle; import com.scwang.smartrefresh.layout.api.RefreshFooter; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; -import com.scwang.smartrefresh.layout.footer.ballpulse.BallPulseView; -import com.scwang.smartrefresh.layout.util.DensityUtil; -import static android.view.View.MeasureSpec.AT_MOST; -import static android.view.View.MeasureSpec.getSize; -import static android.view.View.MeasureSpec.makeMeasureSpec; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; /** * 球脉冲底部加载组件 - * Created by SCWANG on 2017/5/30. + * Created by scwang on 2017/5/30. */ +@SuppressWarnings({"unused", "UnusedReturnValue"}) +public class BallPulseFooter extends com.scwang.smart.refresh.footer.BallPulseFooter implements RefreshFooter { -public class BallPulseFooter extends ViewGroup implements RefreshFooter { - - private BallPulseView mBallPulseView; - private SpinnerStyle mSpinnerStyle = SpinnerStyle.Translate; - - // - public BallPulseFooter(@NonNull Context context) { - super(context); - initView(context, null, 0); + // + public BallPulseFooter(Context context) { + this(context, null); } - public BallPulseFooter(@NonNull Context context, @Nullable AttributeSet attrs) { + public BallPulseFooter(Context context, @Nullable AttributeSet attrs) { super(context, attrs); - initView(context, attrs, 0); - } - - public BallPulseFooter(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) { - super(context, attrs, defStyleAttr); - initView(context, attrs, defStyleAttr); - } - - private void initView(Context context, AttributeSet attrs, int defStyleAttr) { - mBallPulseView = new BallPulseView(context); - addView(mBallPulseView, WRAP_CONTENT, WRAP_CONTENT); - setMinimumHeight(DensityUtil.dp2px(60)); - - TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BallPulseFooter); - - int primaryColor = ta.getColor(R.styleable.BallPulseFooter_srlPrimaryColor, 0); - int accentColor = ta.getColor(R.styleable.BallPulseFooter_srlAccentColor, 0); - if (primaryColor != 0) { - mBallPulseView.setNormalColor(primaryColor); - } - if (accentColor != 0) { - mBallPulseView.setAnimatingColor(accentColor); - } - - mSpinnerStyle = SpinnerStyle.values()[ta.getInt(R.styleable.BallPulseFooter_srlClassicsSpinnerStyle, mSpinnerStyle.ordinal())]; - - ta.recycle(); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int widthSpec = makeMeasureSpec(getSize(widthMeasureSpec), AT_MOST); - int heightSpec = makeMeasureSpec(getSize(heightMeasureSpec), AT_MOST); - mBallPulseView.measure(widthSpec, heightSpec); - setMeasuredDimension( - resolveSize(mBallPulseView.getMeasuredWidth(), widthMeasureSpec), - resolveSize(mBallPulseView.getMeasuredHeight(), heightMeasureSpec) - ); - } - - @Override - protected void onLayout(boolean changed, int l, int t, int r, int b) { - int pwidth = getMeasuredWidth(); - int pheight = getMeasuredHeight(); - int cwidth = mBallPulseView.getMeasuredWidth(); - int cheight = mBallPulseView.getMeasuredHeight(); - int left = pwidth / 2 - cwidth / 2; - int top = pheight / 2 - cheight / 2; - mBallPulseView.layout(left, top, left + cwidth, top + cheight); } // - // - @Override - public void onInitialized(RefreshKernel layout, int height, int extendHeight) { - } @Override - public void onPullingUp(float percent, int offset, int footerHeight, int extendHeight) { - } - - @Override - public void onPullReleasing(float percent, int offset, int footerHeight, int extendHeight) { - } - - @Override - public void onStartAnimator(RefreshLayout layout, int footerHeight, int extendHeight) { - mBallPulseView.startAnim(); - } - - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - } - - @Override - public int onFinish(RefreshLayout layout, boolean success) { - mBallPulseView.stopAnim(); - return 0; - } - - @Override - public boolean setLoadmoreFinished(boolean finished) { - return false; - } - - @Override - public void setPrimaryColors(int... colors) { - if (colors.length > 1) { - mBallPulseView.setNormalColor(colors[1]); - mBallPulseView.setAnimatingColor(colors[0]); - } else if (colors.length > 0) { - mBallPulseView.setNormalColor(ColorUtils.compositeColors(0x99ffffff,colors[0])); - mBallPulseView.setAnimatingColor(colors[0]); - } + public BallPulseFooter setSpinnerStyle(SpinnerStyle mSpinnerStyle) { + super.setSpinnerStyle(mSpinnerStyle); + return this; } - @NonNull @Override - public View getView() { + public BallPulseFooter setNormalColor(int color) { + super.setNormalColor(color); return this; } @Override - public SpinnerStyle getSpinnerStyle() { - return mSpinnerStyle; - } - // - - // - public BallPulseFooter setSpinnerStyle(SpinnerStyle mSpinnerStyle) { - this.mSpinnerStyle = mSpinnerStyle; + public BallPulseFooter setAnimatingColor(int color) { + super.setAnimatingColor(color); return this; } - // } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/ClassicsFooter.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/ClassicsFooter.java index eb5ce4ad..4f68fad9 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/ClassicsFooter.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/ClassicsFooter.java @@ -1,252 +1,119 @@ package com.scwang.smartrefresh.layout.footer; import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; -import android.support.annotation.NonNull; -import android.support.v7.widget.AppCompatTextView; import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import com.scwang.smartrefresh.layout.R; +import com.scwang.smart.refresh.layout.constant.SpinnerStyle; import com.scwang.smartrefresh.layout.api.RefreshFooter; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; -import com.scwang.smartrefresh.layout.internal.ProgressDrawable; -import com.scwang.smartrefresh.layout.util.DensityUtil; - -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; /** - * 经典上拉底部组件 - * Created by SCWANG on 2017/5/28. + * 经典上拉底部-兼容【1.x】版本-包名位置 + * Created by scwang on 2017/5/28. */ +@SuppressWarnings({"unused", "UnusedReturnValue"}) +public class ClassicsFooter extends com.scwang.smart.refresh.footer.ClassicsFooter implements RefreshFooter { -public class ClassicsFooter extends LinearLayout implements RefreshFooter { - - public static String REFRESH_FOOTER_PULLUP = "上拉加载更多"; - public static String REFRESH_FOOTER_RELEASE = "释放立即加载"; - public static String REFRESH_FOOTER_LOADING = "正在加载..."; - public static String REFRESH_FOOTER_FINISH = "加载完成"; - public static String REFRESH_FOOTER_ALLLOADED = "全部加载完成"; - - private TextView mBottomText; - private ImageView mProgressView; - private ProgressDrawable mProgressDrawable; - private SpinnerStyle mSpinnerStyle = SpinnerStyle.Translate; - private boolean mLoadmoreFinished = false; - - // public ClassicsFooter(Context context) { super(context); - this.initView(context, null, 0); } public ClassicsFooter(Context context, AttributeSet attrs) { super(context, attrs); - this.initView(context, attrs, 0); } - public ClassicsFooter(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - this.initView(context, attrs, defStyleAttr); + @Override + public ClassicsFooter setSpinnerStyle(SpinnerStyle style) { + super.setSpinnerStyle(style); + return this; } - private void initView(Context context, AttributeSet attrs, int defStyleAttr) { - DensityUtil density = new DensityUtil(); - - setGravity(Gravity.CENTER); - setMinimumHeight(density.dip2px(60)); - - mProgressDrawable = new ProgressDrawable(); - mProgressDrawable.setColor(0xff666666); - mProgressView = new ImageView(context); - mProgressView.setImageDrawable(mProgressDrawable); - LayoutParams lpPathView = new LayoutParams(density.dip2px(16), density.dip2px(16)); - lpPathView.rightMargin = density.dip2px(10); - addView(mProgressView, lpPathView); - - mBottomText = new AppCompatTextView(context, attrs, defStyleAttr); - mBottomText.setTextColor(0xff666666); - mBottomText.setTextSize(16); - mBottomText.setText(REFRESH_FOOTER_PULLUP); - - addView(mBottomText, WRAP_CONTENT, WRAP_CONTENT); - - if (!isInEditMode()) { - mProgressView.setVisibility(GONE); - } - - TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ClassicsFooter); - - mSpinnerStyle = SpinnerStyle.values()[ta.getInt(R.styleable.ClassicsFooter_srlClassicsSpinnerStyle, mSpinnerStyle.ordinal())]; - - if (ta.hasValue(R.styleable.ClassicsFooter_srlPrimaryColor)) { - int primaryColor = ta.getColor(R.styleable.ClassicsFooter_srlPrimaryColor, 0); - if (ta.hasValue(R.styleable.ClassicsFooter_srlAccentColor)) { - int accentColor = ta.getColor(R.styleable.ClassicsFooter_srlAccentColor, 0); - setPrimaryColors(primaryColor, accentColor); - } else { - setPrimaryColors(primaryColor); - } - } else if (ta.hasValue(R.styleable.ClassicsFooter_srlAccentColor)) { - int accentColor = ta.getColor(R.styleable.ClassicsFooter_srlAccentColor, 0); - setPrimaryColors(0, accentColor); - } - - ta.recycle(); + @Override + public ClassicsFooter setPrimaryColor(int primaryColor) { + super.setPrimaryColor(primaryColor); + return this; } - // - - // - @Override - public void onInitialized(RefreshKernel layout, int height, int extendHeight) { - + public ClassicsFooter setAccentColor(int accentColor) { + super.setAccentColor(accentColor); + return this; } @Override - public void onPullingUp(float percent, int offset, int footerHeight, int extendHeight) { - + public ClassicsFooter setPrimaryColorId(int colorId) { + super.setPrimaryColorId(colorId); + return this; } @Override - public void onPullReleasing(float percent, int offset, int headHeight, int extendHeight) { + public ClassicsFooter setAccentColorId(int colorId) { + super.setAccentColorId(colorId); + return this; + } + @Override + public ClassicsFooter setFinishDuration(int delay) { + super.setFinishDuration(delay); + return this; } @Override - public void onStartAnimator(RefreshLayout layout, int headHeight, int extendHeight) { - if (!mLoadmoreFinished) { - mProgressView.setVisibility(VISIBLE); - mProgressDrawable.start(); - } + public ClassicsFooter setTextSizeTitle(float size) { + super.setTextSizeTitle(size); + return this; } @Override - public int onFinish(RefreshLayout layout, boolean success) { - if (!mLoadmoreFinished) { - mProgressDrawable.stop(); - mProgressView.setVisibility(GONE); - mBottomText.setText(REFRESH_FOOTER_FINISH); - return 500; - } - return 0; + public ClassicsFooter setTextSizeTitle(int unit, float size) { + super.setTextSizeTitle(unit, size); + return this; } - /** - * ClassicsFooter 没有主题色 - * ClassicsFooter has no primary colors - */ @Override - public void setPrimaryColors(int... colors) { - if (mSpinnerStyle == SpinnerStyle.FixedBehind) { - if (colors.length > 1) { - setBackgroundColor(colors[0]); - mBottomText.setTextColor(colors[1]); - mProgressDrawable.setColor(colors[1]); - } else if (colors.length > 0) { - setBackgroundColor(colors[0]); - if (colors[0] == 0xffffffff) { - mBottomText.setTextColor(0xff666666); - mProgressDrawable.setColor(0xff666666); - } else { - mBottomText.setTextColor(0xffffffff); - mProgressDrawable.setColor(0xffffffff); - } - } - } + public ClassicsFooter setDrawableMarginRight(float dp) { + super.setDrawableMarginRight(dp); + return this; } - /** - * 设置数据全部加载完成,将不能再次触发加载功能 - */ @Override - public boolean setLoadmoreFinished(boolean finished) { - if (mLoadmoreFinished != finished) { - mLoadmoreFinished = finished; - if (finished) { - mBottomText.setText(REFRESH_FOOTER_ALLLOADED); - } else { - mBottomText.setText(REFRESH_FOOTER_PULLUP); - } - mProgressDrawable.stop(); - mProgressView.setVisibility(GONE); - } - return true; + public ClassicsFooter setDrawableMarginRightPx(int px) { + super.setDrawableMarginRightPx(px); + return this; } - @NonNull - public View getView() { + @Override + public ClassicsFooter setDrawableSize(float dp) { + super.setDrawableSize(dp); return this; } @Override - public SpinnerStyle getSpinnerStyle() { - return mSpinnerStyle; + public ClassicsFooter setDrawableSizePx(int px) { + super.setDrawableSizePx(px); + return this; } @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - if (!mLoadmoreFinished) { - switch (newState) { - case None: - restoreRefreshLayoutBackground(); - case PullToUpLoad: - mBottomText.setText(REFRESH_FOOTER_PULLUP); - break; - case Loading: - mBottomText.setText(REFRESH_FOOTER_LOADING); - break; - case ReleaseToLoad: - mBottomText.setText(REFRESH_FOOTER_RELEASE); - replaceRefreshLayoutBackground(refreshLayout); - break; - } - } + public ClassicsFooter setDrawableArrowSize(float dp) { + super.setDrawableArrowSize(dp); + return this; } - // - // - private Runnable restoreRunable; - private void restoreRefreshLayoutBackground() { - if (restoreRunable != null) { - restoreRunable.run(); - restoreRunable = null; - } - } - - private void replaceRefreshLayoutBackground(final RefreshLayout refreshLayout) { - if (restoreRunable == null && mSpinnerStyle == SpinnerStyle.FixedBehind) { - restoreRunable = new Runnable() { - Drawable drawable = refreshLayout.getLayout().getBackground(); - @Override - public void run() { - refreshLayout.getLayout().setBackgroundDrawable(drawable); - } - }; - refreshLayout.getLayout().setBackgroundDrawable(getBackground()); - } - } - // - - // - public ClassicsFooter setSpinnerStyle(SpinnerStyle style) { - this.mSpinnerStyle = style; + @Override + public ClassicsFooter setDrawableArrowSizePx(int px) { + super.setDrawableArrowSizePx(px); return this; } - public ClassicsFooter setAccentColor(int accentColor) { - mBottomText.setTextColor(accentColor); - mProgressDrawable.setColor(accentColor); + + @Override + public ClassicsFooter setDrawableProgressSize(float dp) { + super.setDrawableProgressSize(dp); return this; } - // + @Override + public ClassicsFooter setDrawableProgressSizePx(int px) { + super.setDrawableProgressSizePx(px); + return this; + } } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/FalsifyFooter.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/FalsifyFooter.java new file mode 100644 index 00000000..1ce4377c --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/FalsifyFooter.java @@ -0,0 +1,26 @@ +package com.scwang.smartrefresh.layout.footer; + +import android.content.Context; +import android.util.AttributeSet; + +import com.scwang.smartrefresh.layout.api.RefreshFooter; + +/** + * 虚假的 Footer + * 用于 正真的 Footer 在 RefreshLayout 外部时, + * Created by scwang on 2017/6/14. + */ +@SuppressWarnings("unused") +public class FalsifyFooter extends com.scwang.smart.refresh.header.FalsifyFooter implements RefreshFooter { + + // + public FalsifyFooter(Context context) { + this(context, null); + } + + public FalsifyFooter(Context context, AttributeSet attrs) { + super(context, attrs); + } + // + +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/ballpulse/BallPulseView.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/ballpulse/BallPulseView.java deleted file mode 100644 index b870eb89..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/footer/ballpulse/BallPulseView.java +++ /dev/null @@ -1,165 +0,0 @@ -package com.scwang.smartrefresh.layout.footer.ballpulse; - -import android.animation.ValueAnimator; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.support.annotation.ColorInt; -import android.util.AttributeSet; -import android.view.View; - -import com.scwang.smartrefresh.layout.util.DensityUtil; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; - -public class BallPulseView extends View { - - public static final int DEFAULT_SIZE = 50; //dp - - private Paint mPaint; - - private int normalColor = 0xffeeeeee; - private int animatingColor = 0xffe75946; - - private float circleSpacing; - private float[] scaleFloats = new float[]{1f, 1f, 1f}; - - - private boolean mIsStarted = false; - private ArrayList mAnimators; - private Map mUpdateListeners = new HashMap<>();; - - // - public BallPulseView(Context context) { - this(context, null); - } - - public BallPulseView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public BallPulseView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - circleSpacing = DensityUtil.dp2px(4); - - mPaint = new Paint(); - mPaint.setColor(Color.WHITE); - mPaint.setStyle(Paint.Style.FILL); - mPaint.setAntiAlias(true); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int default_size = DensityUtil.dp2px(DEFAULT_SIZE); - setMeasuredDimension(resolveSize(default_size, widthMeasureSpec), - resolveSize(default_size, heightMeasureSpec)); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mAnimators != null) for (int i = 0; i < mAnimators.size(); i++) { - mAnimators.get(i).cancel(); - } - } - - @Override - protected void onDraw(Canvas canvas) { - float radius = (Math.min(getWidth(), getHeight()) - circleSpacing * 2) / 6; - float x = getWidth() / 2 - (radius * 2 + circleSpacing); - float y = getHeight() / 2; - for (int i = 0; i < 3; i++) { - canvas.save(); - float translateX = x + (radius * 2) * i + circleSpacing * i; - canvas.translate(translateX, y); - canvas.scale(scaleFloats[i], scaleFloats[i]); - canvas.drawCircle(0, 0, radius, mPaint); - canvas.restore(); - } - } - // - - // - private boolean isStarted() { -// for (ValueAnimator animator : mAnimators) { -// return animator.isStarted(); -// } - return mIsStarted; - } - - private void createAnimators() { - mAnimators = new ArrayList<>(); - int[] delays = new int[]{120, 240, 360}; - for (int i = 0; i < 3; i++) { - final int index = i; - - ValueAnimator scaleAnim = ValueAnimator.ofFloat(1, 0.3f, 1); - - scaleAnim.setDuration(750); - scaleAnim.setRepeatCount(ValueAnimator.INFINITE); - scaleAnim.setStartDelay(delays[i]); - - mUpdateListeners.put(scaleAnim, new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - scaleFloats[index] = (float) animation.getAnimatedValue(); - postInvalidate(); - } - }); - mAnimators.add(scaleAnim); - } - } - // - - // - public void setIndicatorColor(int color) { - mPaint.setColor(color); - } - - public void setNormalColor(@ColorInt int color) { - normalColor = color; - } - - public void setAnimatingColor(@ColorInt int color) { - animatingColor = color; - } - - public void startAnim() { - if (mAnimators == null) createAnimators(); - if (mAnimators == null) return; - if (isStarted()) return; - - for (int i = 0; i < mAnimators.size(); i++) { - ValueAnimator animator = mAnimators.get(i); - - //when the animator restart , add the updateListener again because they was removed by animator stop . - ValueAnimator.AnimatorUpdateListener updateListener = mUpdateListeners.get(animator); - if (updateListener != null) { - animator.addUpdateListener(updateListener); - } - animator.start(); - } - mIsStarted = true; - setIndicatorColor(animatingColor); - } - - public void stopAnim() { - if (mAnimators != null && mIsStarted) { - mIsStarted = false; - for (ValueAnimator animator : mAnimators) { - if (animator != null /*&& animator.isStarted()*/) { - animator.removeAllUpdateListeners(); - animator.end(); - } - } - scaleFloats = new float[]{1f, 1f, 1f}; - } - setIndicatorColor(normalColor); - } - // - -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/BezierRadarHeader.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/BezierRadarHeader.java index 7f78aadc..299c50b1 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/BezierRadarHeader.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/BezierRadarHeader.java @@ -1,42 +1,16 @@ package com.scwang.smartrefresh.layout.header; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; import android.content.Context; -import android.content.res.TypedArray; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; import android.util.AttributeSet; -import android.view.View; -import android.view.animation.DecelerateInterpolator; -import android.widget.FrameLayout; -import com.scwang.smartrefresh.layout.R; import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; -import com.scwang.smartrefresh.layout.header.bezierradar.RippleView; -import com.scwang.smartrefresh.layout.header.bezierradar.RoundDotView; -import com.scwang.smartrefresh.layout.header.bezierradar.RoundProgressView; -import com.scwang.smartrefresh.layout.header.bezierradar.WaveView; -import com.scwang.smartrefresh.layout.util.DensityUtil; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; /** * 贝塞尔曲线类雷达风格刷新组件 - * Created by lcodecore on 2016/10/2. + * Created by scwang on 2017/5/28. */ - -public class BezierRadarHeader extends FrameLayout implements RefreshHeader { - - private WaveView mWaveView; - private RippleView mRippleView; - private RoundDotView mDotView; - private RoundProgressView mProgressView; +@SuppressWarnings({"UnusedReturnValue", "unused"}) +public class BezierRadarHeader extends com.scwang.smart.refresh.header.BezierRadarHeader implements RefreshHeader { // public BezierRadarHeader(Context context) { @@ -44,190 +18,37 @@ public BezierRadarHeader(Context context) { } public BezierRadarHeader(Context context, AttributeSet attrs) { - this(context, attrs,0); - } - - public BezierRadarHeader(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initView(context, attrs, defStyleAttr); - } - - private void initView(Context context, AttributeSet attrs, int defStyleAttr) { - setMinimumHeight(DensityUtil.dp2px(100)); - /** - * 初始化headView - */ - mWaveView = new WaveView(getContext()); - mRippleView = new RippleView(getContext()); - mDotView = new RoundDotView(getContext()); - mProgressView = new RoundProgressView(getContext()); - if (isInEditMode()) { - this.addView(mWaveView, MATCH_PARENT, MATCH_PARENT); - this.addView(mProgressView, MATCH_PARENT, MATCH_PARENT); - mWaveView.setHeadHeight(1000); - } else { - this.addView(mWaveView, MATCH_PARENT, MATCH_PARENT); - this.addView(mDotView, MATCH_PARENT, MATCH_PARENT); - this.addView(mProgressView, MATCH_PARENT, MATCH_PARENT); - this.addView(mRippleView, MATCH_PARENT, MATCH_PARENT); - mProgressView.setScaleX(0); - mProgressView.setScaleY(0); - } - - - TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.BezierRadarHeader); - - int primaryColor = ta.getColor(R.styleable.BezierRadarHeader_srlPrimaryColor, 0); - int accentColor = ta.getColor(R.styleable.BezierRadarHeader_srlAccentColor, 0); - if (primaryColor != 0) { - setPrimaryColor(primaryColor); - } - if (accentColor != 0) { - setAccentColor(primaryColor); - } - - ta.recycle(); + super(context, attrs); } // - // + @Override public BezierRadarHeader setPrimaryColor(int color) { - mWaveView.setWaveColor(color); - mProgressView.setBackColor(color); + super.setPrimaryColor(color); return this; } + @Override public BezierRadarHeader setAccentColor(int color) { - mDotView.setDotColor(color); - mRippleView.setFrontColor(color); - mProgressView.setFrontColor(color); + super.setAccentColor(color); return this; } + @Override public BezierRadarHeader setPrimaryColorId(int colorId) { - setPrimaryColor(ContextCompat.getColor(getContext(), colorId)); + super.setPrimaryColorId(colorId); return this; } + @Override public BezierRadarHeader setAccentColorId(int colorId) { - setAccentColor(ContextCompat.getColor(getContext(), colorId)); + super.setAccentColorId(colorId); return this; } - // - // @Override - public void setPrimaryColors(int... colors) { - if (colors.length > 0) { - setPrimaryColor(colors[0]); - } - if (colors.length > 1) { - setAccentColor(colors[1]); - } - } - - @NonNull - public View getView() { + public BezierRadarHeader setEnableHorizontalDrag(boolean enable) { + super.setEnableHorizontalDrag(enable); return this; } - - @Override - public SpinnerStyle getSpinnerStyle() { - return SpinnerStyle.Scale; - } - - @Override - public void onInitialized(RefreshKernel layout, int height, int extendHeight) { - - } - - @Override - public void onPullingDown(float percent, int offset, int headHeight, int extendHeight) { - mWaveView.setHeadHeight(Math.min(headHeight, offset)); - mWaveView.setWaveHeight((int)(1.9f*Math.max(0, offset - headHeight))); - mDotView.setFraction(percent); - } - - @Override - public void onReleasing(float percent, int offset, int headHeight, int extendHeight) { - onPullingDown(percent, offset, headHeight, extendHeight); - } - - @Override - public void onStartAnimator(RefreshLayout layout, int headHeight, int extendHeight) { - mWaveView.setHeadHeight(headHeight); - ValueAnimator animator = ValueAnimator.ofInt( - mWaveView.getWaveHeight(), 0, - -(int)(mWaveView.getWaveHeight()*0.8),0, - -(int)(mWaveView.getWaveHeight()*0.4f),0); - animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - mWaveView.setWaveHeight((int) animation.getAnimatedValue()/2); - mWaveView.invalidate(); - } - }); - animator.setInterpolator(new DecelerateInterpolator()); - animator.setDuration(800); - animator.start(); - /*处理圈圈进度条**/ - ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, 0); - valueAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - mDotView.setVisibility(INVISIBLE); - mProgressView.animate().scaleX((float) 1.0); - mProgressView.animate().scaleY((float) 1.0); - mProgressView.postDelayed(new Runnable() { - @Override - public void run() { - mProgressView.startAnim(); - } - }, 200); - } - }); - - valueAnimator.setInterpolator(new DecelerateInterpolator()); - valueAnimator.setDuration(300); - valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - mDotView.setAlpha((Float) animation.getAnimatedValue()); - } - }); - valueAnimator.start(); - } - - @Override - public int onFinish(RefreshLayout layout, boolean success) { - mProgressView.stopAnim(); - mProgressView.animate().scaleX(0f); - mProgressView.animate().scaleY(0f); - mRippleView.setVisibility(VISIBLE); - mRippleView.startReveal(); - return 400; - } - - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - switch (newState) { - case None: - mRippleView.setVisibility(GONE); - mDotView.setAlpha(1); - mDotView.setVisibility(VISIBLE); - break; - case PullDownToRefresh: - mProgressView.setScaleX(0); - mProgressView.setScaleY(0); - break; - case PullToUpLoad: - break; - case Refreshing: - break; - case Loading: - break; - } - } - // } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/ClassicsHeader.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/ClassicsHeader.java index a7f60f7a..e60a0d7e 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/ClassicsHeader.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/ClassicsHeader.java @@ -1,311 +1,213 @@ package com.scwang.smartrefresh.layout.header; import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.TypedArray; -import android.graphics.drawable.BitmapDrawable; +import android.graphics.Bitmap; import android.graphics.drawable.Drawable; -import android.support.annotation.NonNull; -import android.support.v4.app.Fragment; -import android.support.v4.app.FragmentActivity; -import android.support.v4.app.FragmentManager; import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import com.scwang.smartrefresh.layout.R; + +import com.scwang.smart.refresh.layout.constant.SpinnerStyle; import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; -import com.scwang.smartrefresh.layout.internal.ProgressDrawable; -import com.scwang.smartrefresh.layout.internal.pathview.PathsView; -import com.scwang.smartrefresh.layout.util.DensityUtil; import java.text.DateFormat; -import java.text.SimpleDateFormat; import java.util.Date; -import java.util.List; -import java.util.Locale; - -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; /** - * 经典下拉头部 - * Created by SCWANG on 2017/5/28. + * 经典下拉头部-兼容【1.x】版本-包名位置 + * Created by scwang on 2017/5/28. */ -public class ClassicsHeader extends RelativeLayout implements RefreshHeader { - - public static String REFRESH_HEADER_PULLDOWN = "下拉可以刷新"; - public static String REFRESH_HEADER_REFRESHING = "正在刷新"; - public static String REFRESH_HEADER_RELEASE = "释放立即刷新"; - public static String REFRESH_HEADER_FINISH = "刷新完成"; - public static String REFRESH_HEADER_FAILED = "刷新失败"; - - private String KEY_LAST_UPDATE_TIME = "LAST_UPDATE_TIME"; - - private Date mLastTime; - private TextView mHeaderText; - private TextView mLastUpdateText; - private PathsView mArrowView; - private ImageView mProgressView; - private ProgressDrawable mProgressDrawable; - private DateFormat mFormat = new SimpleDateFormat("上次更新 M-d HH:mm", Locale.CHINA); - private SpinnerStyle mSpinnerStyle = SpinnerStyle.Translate; - private SharedPreferences mShared; - - // +@SuppressWarnings({"unused", "UnusedReturnValue"}) +public class ClassicsHeader extends com.scwang.smart.refresh.header.ClassicsHeader implements RefreshHeader { + public ClassicsHeader(Context context) { super(context); - this.initView(context, null, 0); } public ClassicsHeader(Context context, AttributeSet attrs) { super(context, attrs); - this.initView(context, attrs, 0); - } - - public ClassicsHeader(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - this.initView(context, attrs, defStyleAttr); - } - - private void initView(Context context, AttributeSet attrs, int defStyleAttr) { - DensityUtil density = new DensityUtil(); - - setMinimumHeight(density.dip2px(80)); - - LinearLayout layout = new LinearLayout(context); - layout.setId(android.R.id.widget_frame); - layout.setGravity(Gravity.CENTER_HORIZONTAL); - layout.setOrientation(LinearLayout.VERTICAL); - mHeaderText = new TextView(context); - mHeaderText.setText(REFRESH_HEADER_PULLDOWN); - mHeaderText.setTextColor(0xff666666); - mHeaderText.setTextSize(16); - - mLastUpdateText = new TextView(context); - mLastUpdateText.setTextColor(0xff7c7c7c); - mLastUpdateText.setTextSize(12); - LinearLayout.LayoutParams lpHeaderText = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); - lpHeaderText.leftMargin = density.dip2px(20); - lpHeaderText.rightMargin = density.dip2px(20); - layout.addView(mHeaderText, lpHeaderText); - LinearLayout.LayoutParams lpUpdateText = new LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT); - layout.addView(mLastUpdateText, lpUpdateText); - - LayoutParams lpHeaderLayout = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT); - lpHeaderLayout.addRule(CENTER_IN_PARENT); - addView(layout,lpHeaderLayout); - - mProgressDrawable = new ProgressDrawable(); - mProgressDrawable.setColor(0xff666666); - mProgressView = new ImageView(context); - mProgressView.setImageDrawable(mProgressDrawable); - LayoutParams lpProgress = new LayoutParams(density.dip2px(20), density.dip2px(20)); - lpProgress.rightMargin = density.dip2px(20); - lpProgress.addRule(CENTER_VERTICAL); - lpProgress.addRule(LEFT_OF, android.R.id.widget_frame); - addView(mProgressView, lpProgress); - - mArrowView = new PathsView(context); - mArrowView.parserColors(0xff666666); - mArrowView.parserPaths("M20,12l-1.41,-1.41L13,16.17V4h-2v12.17l-5.58,-5.59L4,12l8,8 8,-8z"); - addView(mArrowView, lpProgress); - - if (isInEditMode()) { - mArrowView.setVisibility(GONE); - mHeaderText.setText(REFRESH_HEADER_REFRESHING); - } else { - mProgressView.setVisibility(GONE); - } - - TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ClassicsHeader); - - mSpinnerStyle = SpinnerStyle.values()[ta.getInt(R.styleable.ClassicsHeader_srlClassicsSpinnerStyle,mSpinnerStyle.ordinal())]; - - int primaryColor = ta.getColor(R.styleable.ClassicsHeader_srlPrimaryColor, 0); - int accentColor = ta.getColor(R.styleable.ClassicsHeader_srlAccentColor, 0); - if (primaryColor != 0) { - if (accentColor != 0) { - setPrimaryColors(primaryColor, accentColor); - } else { - setPrimaryColors(primaryColor); - } - } else if (accentColor != 0) { - setPrimaryColors(0, accentColor); - } - - ta.recycle(); - - if (context instanceof FragmentActivity) { - FragmentManager manager = ((FragmentActivity) context).getSupportFragmentManager(); - if (manager != null) { - List fragments = manager.getFragments(); - if (fragments != null && fragments.size() > 0) { - setLastUpdateTime(new Date()); - return; - } - } - } - KEY_LAST_UPDATE_TIME += context.getClass().getName(); - mShared = context.getSharedPreferences("ClassicsHeader", Context.MODE_PRIVATE); - setLastUpdateTime(new Date(mShared.getLong(KEY_LAST_UPDATE_TIME, System.currentTimeMillis()))); - } - - // - - // + } + @Override - public void onInitialized(RefreshKernel kernel, int height, int extendHeight) { + public ClassicsHeader setLastUpdateTime(Date time) { + super.setLastUpdateTime(time); + return this; } @Override - public void onPullingDown(float percent, int offset, int headHeight, int extendHeight) { + public ClassicsHeader setTimeFormat(DateFormat format) { + super.setTimeFormat(format); + return this; } @Override - public void onReleasing(float percent, int offset, int headHeight, int extendHeight) { + public ClassicsHeader setLastUpdateText(CharSequence text) { + super.setLastUpdateText(text); + return this; + } + @Override + public ClassicsHeader setAccentColor(int accentColor) { + super.setAccentColor(accentColor); + return this; + } + + @Override + public ClassicsHeader setEnableLastTime(boolean enable) { + super.setEnableLastTime(enable); + return this; + } + + @Override + public ClassicsHeader setTextSizeTime(float size) { + super.setTextSizeTime(size); + return this; } @Override - public void onStartAnimator(RefreshLayout layout, int headHeight, int extendHeight) { - mProgressDrawable.start(); + public ClassicsHeader setTextSizeTime(int unit, float size) { + super.setTextSizeTime(unit, size); + return this; } @Override - public int onFinish(RefreshLayout layout, boolean success) { - mProgressDrawable.stop(); - mProgressView.setVisibility(GONE); - if (success) { - mHeaderText.setText(REFRESH_HEADER_FINISH); - setLastUpdateTime(new Date()); - } else { - mHeaderText.setText(REFRESH_HEADER_FAILED); - } - return 500;//延迟500毫秒之后再弹回 + public ClassicsHeader setTextTimeMarginTop(float dp) { + super.setTextTimeMarginTop(dp); + return this; + } + + @Override + public ClassicsHeader setTextTimeMarginTopPx(int px) { + super.setTextTimeMarginTopPx(px); + return this; } @Override public void setPrimaryColors(int... colors) { - if (colors.length > 1) { - if (!(getBackground() instanceof BitmapDrawable)) { - setBackgroundColor(colors[0]); - } - mArrowView.parserColors(colors[1]); - mHeaderText.setTextColor(colors[1]); - mProgressDrawable.setColor(colors[1]); - mLastUpdateText.setTextColor(colors[1]&0x00ffffff|0x99000000); - } else if (colors.length > 0) { - if (!(getBackground() instanceof BitmapDrawable)) { - setBackgroundColor(colors[0]); - } - if (colors[0] == 0xffffffff) { - mArrowView.parserColors(0xff666666); - mHeaderText.setTextColor(0xff666666); - mProgressDrawable.setColor(0xff666666); - mLastUpdateText.setTextColor(0xff666666&0x00ffffff|0x99000000); - } else { - mArrowView.parserColors(0xffffffff); - mHeaderText.setTextColor(0xffffffff); - mProgressDrawable.setColor(0xffffffff); - mLastUpdateText.setTextColor(0xaaffffff); - } - } - } - - @NonNull - public View getView() { + super.setPrimaryColors(colors); + } + + @Override + public ClassicsHeader setProgressBitmap(Bitmap bitmap) { + super.setProgressBitmap(bitmap); return this; } @Override - public SpinnerStyle getSpinnerStyle() { - return mSpinnerStyle; + public ClassicsHeader setProgressDrawable(Drawable drawable) { + super.setProgressDrawable(drawable); + return this; } @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - switch (newState) { - case None: - restoreRefreshLayoutBackground(); - case PullDownToRefresh: - mHeaderText.setText(REFRESH_HEADER_PULLDOWN); - mArrowView.setVisibility(VISIBLE); - mProgressView.setVisibility(GONE); - mArrowView.animate().rotation(0); - break; - case Refreshing: - mHeaderText.setText(REFRESH_HEADER_REFRESHING); - mProgressView.setVisibility(VISIBLE); - mArrowView.setVisibility(GONE); - break; - case ReleaseToRefresh: - mHeaderText.setText(REFRESH_HEADER_RELEASE); - mArrowView.animate().rotation(180); - replaceRefreshLayoutBackground(refreshLayout); - break; - } - } - // - - // - private Runnable restoreRunable; - private void restoreRefreshLayoutBackground() { - if (restoreRunable != null) { - restoreRunable.run(); - restoreRunable = null; - } - } - - private void replaceRefreshLayoutBackground(final RefreshLayout refreshLayout) { - if (restoreRunable == null && mSpinnerStyle == SpinnerStyle.FixedBehind) { - restoreRunable = new Runnable() { - Drawable drawable = refreshLayout.getLayout().getBackground(); - @Override - public void run() { - refreshLayout.getLayout().setBackgroundDrawable(drawable); - } - }; - refreshLayout.getLayout().setBackgroundDrawable(getBackground()); - } - } - // - - // - public ClassicsHeader setLastUpdateTime(Date time) { - mLastTime = time; - mLastUpdateText.setText(mFormat.format(time)); - if (mShared != null) { - mShared.edit().putLong(KEY_LAST_UPDATE_TIME, time.getTime()).apply(); - } + public ClassicsHeader setProgressResource(int resId) { + super.setProgressResource(resId); return this; } - public ClassicsHeader setTimeFormat(DateFormat format) { - mFormat = format; - mLastUpdateText.setText(mFormat.format(mLastTime)); + @Override + public ClassicsHeader setArrowBitmap(Bitmap bitmap) { + super.setArrowBitmap(bitmap); + return this; + } + + @Override + public ClassicsHeader setArrowDrawable(Drawable drawable) { + super.setArrowDrawable(drawable); + return this; + } + + @Override + public ClassicsHeader setArrowResource(int resId) { + super.setArrowResource(resId); return this; } + @Override public ClassicsHeader setSpinnerStyle(SpinnerStyle style) { - this.mSpinnerStyle = style; + super.setSpinnerStyle(style); return this; } - public ClassicsHeader setAccentColor(int accentColor) { - mArrowView.parserColors(accentColor); - mHeaderText.setTextColor(accentColor); - mProgressDrawable.setColor(accentColor); - mLastUpdateText.setTextColor(accentColor&0x00ffffff|0x99000000); + @Override + public ClassicsHeader setPrimaryColor(int primaryColor) { + super.setPrimaryColor(primaryColor); return this; } - // + @Override + public ClassicsHeader setPrimaryColorId(int colorId) { + super.setPrimaryColorId(colorId); + return this; + } + + @Override + public ClassicsHeader setAccentColorId(int colorId) { + super.setAccentColorId(colorId); + return this; + } + + @Override + public ClassicsHeader setFinishDuration(int delay) { + super.setFinishDuration(delay); + return this; + } + + @Override + public ClassicsHeader setTextSizeTitle(float size) { + super.setTextSizeTitle(size); + return this; + } + + @Override + public ClassicsHeader setTextSizeTitle(int unit, float size) { + super.setTextSizeTitle(unit, size); + return this; + } + + @Override + public ClassicsHeader setDrawableMarginRight(float dp) { + super.setDrawableMarginRight(dp); + return this; + } + + @Override + public ClassicsHeader setDrawableMarginRightPx(int px) { + super.setDrawableMarginRightPx(px); + return this; + } + + @Override + public ClassicsHeader setDrawableSize(float dp) { + super.setDrawableSize(dp); + return this; + } + + @Override + public ClassicsHeader setDrawableSizePx(int px) { + super.setDrawableSizePx(px); + return this; + } + + @Override + public ClassicsHeader setDrawableArrowSize(float dp) { + super.setDrawableArrowSize(dp); + return this; + } + + @Override + public ClassicsHeader setDrawableArrowSizePx(int px) { + super.setDrawableArrowSizePx(px); + return this; + } + + @Override + public ClassicsHeader setDrawableProgressSize(float dp) { + super.setDrawableProgressSize(dp); + return this; + } + + @Override + public ClassicsHeader setDrawableProgressSizePx(int px) { + super.setDrawableProgressSizePx(px); + return this; + } } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/FalsifyHeader.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/FalsifyHeader.java index 69ab7d3e..d105ce53 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/FalsifyHeader.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/FalsifyHeader.java @@ -1,135 +1,26 @@ package com.scwang.smartrefresh.layout.header; -import android.annotation.SuppressLint; -import android.support.annotation.RequiresApi; import android.content.Context; -import android.graphics.Canvas; -import android.graphics.DashPathEffect; -import android.graphics.Paint; -import android.os.Build; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.widget.TextView; import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; -import com.scwang.smartrefresh.layout.util.DensityUtil; - -import static android.view.View.MeasureSpec.EXACTLY; -import static android.view.View.MeasureSpec.makeMeasureSpec; /** * 虚假的 Header * 用于 正真的 Header 在 RefreshLayout 外部时, * 使用本虚假的 FalsifyHeader 填充在 RefreshLayout 内部 - * 具体使用方法 参考 QQ空间风格(QzoneHeader) 和 纸飞机(FlyRefreshHeader) - * Created by SCWANG on 2017/6/14. + * 具体使用方法 参考 纸飞机(FlyRefreshHeader) + * Created by scwang on 2017/6/14. */ - -public class FalsifyHeader extends View implements RefreshHeader { +public class FalsifyHeader extends com.scwang.smart.refresh.header.FalsifyHeader implements RefreshHeader { // public FalsifyHeader(Context context) { - super(context); + this(context, null); } public FalsifyHeader(Context context, AttributeSet attrs) { super(context, attrs); } - - public FalsifyHeader(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - @RequiresApi(Build.VERSION_CODES.LOLLIPOP) - public FalsifyHeader(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec), - resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec)); - } - - @Override@SuppressLint("DrawAllocation") - protected final void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (isInEditMode()) {//这段代码在运行时不会执行,只会在Studio编辑预览时运行,不用在意性能问题 - int d = DensityUtil.dp2px(5); - - Paint paint = new Paint(); - paint.setStyle(Paint.Style.STROKE); - paint.setColor(0x44ffffff); - paint.setStrokeWidth(DensityUtil.dp2px(1)); - paint.setPathEffect(new DashPathEffect(new float[]{d, d, d, d}, 1)); - canvas.drawRect(d, d, getWidth() - d, getBottom() - d, paint); - - TextView textView = new TextView(getContext()); - textView.setText(getClass().getSimpleName()+" 虚假区域\n运行时代表下拉Header的高度【" + DensityUtil.px2dp(getHeight()) + "dp】\n而不会显示任何东西"); - textView.setTextColor(0x44ffffff); - textView.setGravity(Gravity.CENTER); - textView.measure(makeMeasureSpec(getWidth(), EXACTLY), makeMeasureSpec(getHeight(), EXACTLY)); - textView.layout(0, 0, getWidth(), getHeight()); - textView.draw(canvas); - } - } - - // - - // - - @Override - public void onInitialized(RefreshKernel layout, int height, int extendHeight) { - - } - - @Override - public void onPullingDown(float percent, int offset, int headHeight, int extendHeight) { - - } - - @Override - public void onReleasing(float percent, int offset, int headHeight, int extendHeight) { - - } - - @Override - public void onStartAnimator(RefreshLayout layout, int headHeight, int extendHeight) { - - } - - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - - } - - @Override - public int onFinish(RefreshLayout layout, boolean success) { - return 0; - } - - @Override - public void setPrimaryColors(int... colors) { - - } - - @NonNull - @Override - public View getView() { - return this; - } - - @Override - public SpinnerStyle getSpinnerStyle() { - return SpinnerStyle.Scale; - } // - } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/TwoLevelHeader.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/TwoLevelHeader.java new file mode 100644 index 00000000..3905ea59 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/TwoLevelHeader.java @@ -0,0 +1,87 @@ +package com.scwang.smartrefresh.layout.header; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.AttributeSet; + +import com.scwang.smartrefresh.layout.api.OnTwoLevelListener; +import com.scwang.smartrefresh.layout.api.RefreshHeader; +import com.scwang.smartrefresh.layout.api.RefreshLayout; + +/** + * 二级刷新 + * Created by scwang on 2017/5/26. + */ +@SuppressWarnings("UnusedReturnValue") +public class TwoLevelHeader extends com.scwang.smart.refresh.header.TwoLevelHeader implements RefreshHeader { + + + // + public TwoLevelHeader(Context context) { + this(context, null); + } + + public TwoLevelHeader(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + // + + public TwoLevelHeader setOnTwoLevelListener(final OnTwoLevelListener listener) { + super.setOnTwoLevelListener(new com.scwang.smart.refresh.header.listener.OnTwoLevelListener() { + @Override + public boolean onTwoLevel(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout) { + return listener.onTwoLevel((RefreshLayout) refreshLayout); + } + }); + return this; + } + + @Override + public TwoLevelHeader setRefreshHeader(com.scwang.smart.refresh.layout.api.RefreshHeader header) { + super.setRefreshHeader(header); + return this; + } + + @Override + public TwoLevelHeader setRefreshHeader(com.scwang.smart.refresh.layout.api.RefreshHeader header, int width, int height) { + super.setRefreshHeader(header, width, height); + return this; + } + + @Override + public TwoLevelHeader setMaxRate(float rate) { + super.setMaxRate(rate); + return this; + } + + @Override + public TwoLevelHeader setEnablePullToCloseTwoLevel(boolean enabled) { + super.setEnablePullToCloseTwoLevel(enabled); + return this; + } + + @Override + public TwoLevelHeader setFloorRate(float rate) { + super.setFloorRate(rate); + return this; + } + + @Override + public TwoLevelHeader setRefreshRate(float rate) { + super.setRefreshRate(rate); + return this; + } + + @Override + public TwoLevelHeader setEnableTwoLevel(boolean enabled) { + super.setEnableTwoLevel(enabled); + return this; + } + + @Override + public TwoLevelHeader setFloorDuration(int duration) { + super.setFloorDuration(duration); + return this; + } +} \ No newline at end of file diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RippleView.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RippleView.java deleted file mode 100644 index ea7d5bfc..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RippleView.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.scwang.smartrefresh.layout.header.bezierradar; - - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.view.View; - -/** - * cjj - */ -public class RippleView extends View { - - private int mRadius; - private Paint mPaint; - private ValueAnimator mAnimator; - - public RippleView(Context context) { - super(context); - mPaint = new Paint(); - mPaint.setAntiAlias(true); - mPaint.setColor(0xffffffff); - mPaint.setStyle(Paint.Style.FILL); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec), - resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec)); - } - - public void setFrontColor(int color) { - mPaint.setColor(color); - } - - public void startReveal() { - if (mAnimator == null) { - int bigRadius = (int) (Math.sqrt(Math.pow(getHeight(), 2) + Math.pow(getWidth(), 2))); - mAnimator = ValueAnimator.ofInt(0, bigRadius); - mAnimator.setDuration(400); - mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - mRadius = (int) animation.getAnimatedValue(); - invalidate(); - } - }); - mAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - } - }); - } - mAnimator.start(); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - canvas.drawCircle(getWidth() / 2, getHeight() / 2, mRadius, mPaint); - } - -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RoundDotView.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RoundDotView.java deleted file mode 100644 index 5d50e2ae..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RoundDotView.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.scwang.smartrefresh.layout.header.bezierradar; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.view.View; - -import com.scwang.smartrefresh.layout.util.DensityUtil; - -/** - * - * Created by cjj on 2015/8/27. - */ -public class RoundDotView extends View { - - private int num = 7; - private Paint mPath; - private float mRadius; - private float fraction; - - public RoundDotView(Context context) { - super(context); - mPath = new Paint(); - mPath.setAntiAlias(true); - mPath.setColor(Color.WHITE); - mRadius = DensityUtil.dp2px(7); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec), - resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec)); - } - - public void setDotColor(int color) { - mPath.setColor(color); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - int width = getWidth(); - int height = getHeight(); - float wide = (width / num) * fraction-((fraction>1)?((fraction-1)*(width / num)/fraction):0);//y1 = t*(w/n)-(t>1)*((t-1)*(w/n)/t) - float high = height - ((fraction>1)?((fraction-1)*height/2/fraction):0);//y2 = x - (t>1)*((t-1)*x/t); - for (int i = 0 ; i < num; i++) { - float index = 1f + i - (1f + num) / 2;//y3 = (x + 1) - (n + 1)/2; 居中 index 变量:0 1 2 3 4 结果: -2 -1 0 1 2 - float alpha = 255 * (1 - (2 * (Math.abs(index) / num)));//y4 = m * ( 1 - 2 * abs(y3) / n); 横向 alpha 差 - float x = DensityUtil.px2dp(height); - mPath.setAlpha((int) (alpha * (1d - 1d / Math.pow((x / 800d + 1d), 15))));//y5 = y4 * (1-1/((x/800+1)^15));竖直 alpha 差 - float radius = mRadius * (1-1/((x/10+1)));//y6 = mRadius*(1-1/(x/10+1));半径 - canvas.drawCircle(width / 2- radius/2 + wide * index , high / 2, radius, mPath); - } - } - - public void setFraction(float fraction) { - this.fraction = fraction; - } -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RoundProgressView.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RoundProgressView.java deleted file mode 100644 index 159a44b2..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/RoundProgressView.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.scwang.smartrefresh.layout.header.bezierradar; - -import android.animation.ValueAnimator; -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.RectF; -import android.view.View; -import android.view.animation.AccelerateDecelerateInterpolator; - -import com.scwang.smartrefresh.layout.util.DensityUtil; - - -/** - * 中心圆形加载进度视图 - * Created by Administrator on 2015/8/27. - */ -public class RoundProgressView extends View { - - private Paint mPath; - private Paint mPantR; - private ValueAnimator mAnimator; - private int endAngle = 0; - private int stratAngle = 270; - private int mRadius = 0; - private int mOutsideCircle = 0; - private RectF mRect = new RectF(0,0,0,0); - - public RoundProgressView(Context context) { - super(context); - initView(); - } - - private void initView() { - mPath = new Paint(); - mPantR = new Paint(); - mPath.setAntiAlias(true); - mPantR.setAntiAlias(true); - mPath.setColor(Color.WHITE); - mPantR.setColor(0x55000000); - - DensityUtil density = new DensityUtil(); - mRadius = density.dip2px(20); - mOutsideCircle = density.dip2px(7); - mPath.setStrokeWidth(density.dip2px(3)); - mPantR.setStrokeWidth(density.dip2px(3)); - - mAnimator = ValueAnimator.ofInt(0,360); - mAnimator.setDuration(720); - mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - endAngle = (int) animation.getAnimatedValue(); - postInvalidate(); - } - }); - mAnimator.setRepeatCount(ValueAnimator.INFINITE); - mAnimator.setInterpolator(new AccelerateDecelerateInterpolator()); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec), - resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec)); - } - - public void setBackColor(int backColor) { - mPantR.setColor(backColor&0x00ffffff|0x55000000); - } - - public void setFrontColor(int color) { - mPath.setColor(color); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - int width = getWidth(); - int height = getHeight(); - - if (isInEditMode()) { - stratAngle = 0; - endAngle = 270; - } - - mPath.setStyle(Paint.Style.FILL); - canvas.drawCircle(width / 2, height / 2, mRadius, mPath); - - mPath.setStyle(Paint.Style.STROKE);//设置为空心 - canvas.drawCircle(width / 2, height / 2, mRadius + mOutsideCircle, mPath); - - mPantR.setStyle(Paint.Style.FILL); - mRect.set(width/2- mRadius, height/2- mRadius, width/2+ mRadius, height/2+ mRadius); - canvas.drawArc(mRect, stratAngle, endAngle, true, mPantR); - - mRadius += mOutsideCircle; - mPantR.setStyle(Paint.Style.STROKE); - mRect.set(width/2- mRadius, height/2- mRadius, width/2+ mRadius, height/2+ mRadius); - canvas.drawArc(mRect, stratAngle, endAngle, false, mPantR); - mRadius -= mOutsideCircle; - } - - public void startAnim(){ - if (mAnimator !=null) mAnimator.start(); - } - - public void stopAnim(){ - if (mAnimator !=null && mAnimator.isRunning()) mAnimator.cancel(); - } -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/WaveView.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/WaveView.java deleted file mode 100644 index 7a07cc17..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/header/bezierradar/WaveView.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.scwang.smartrefresh.layout.header.bezierradar; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Path; -import android.util.AttributeSet; -import android.view.View; - -/** - * Created by cjj on 2015/8/5. - * 绘制贝塞尔来绘制波浪形 - */ -public class WaveView extends View { - - private int waveHeight; - private int headHeight; - private Path path; - private Paint paint; - - public WaveView(Context context) { - this(context, null, 0); - } - - public WaveView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public WaveView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initView(); - } - - private void initView() { - path = new Path(); - paint = new Paint(); - paint.setColor(0xff1F2426); - paint.setAntiAlias(true); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec), - resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec)); - } - - public void setWaveColor(int color) { - paint.setColor(color); - } - - public int getHeadHeight() { - return headHeight; - } - - public void setHeadHeight(int headHeight) { - this.headHeight = headHeight; - } - - public int getWaveHeight() { - return waveHeight; - } - - public void setWaveHeight(int waveHeight) { - this.waveHeight = waveHeight; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - final int width = getWidth(); - //重置画笔 - path.reset(); - //绘制贝塞尔曲线 - path.lineTo(0, headHeight); - path.quadTo(width / 2, headHeight + waveHeight, width, headHeight); - path.lineTo(width, 0); - canvas.drawPath(path, paint); - } - -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshContentWrapper.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshContentWrapper.java deleted file mode 100644 index 5d6b7edf..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshContentWrapper.java +++ /dev/null @@ -1,707 +0,0 @@ -package com.scwang.smartrefresh.layout.impl; - -import android.animation.ValueAnimator; -import android.animation.ValueAnimator.AnimatorUpdateListener; -import android.content.Context; -import android.database.DataSetObserver; -import android.graphics.PointF; -import android.os.Build; -import android.support.annotation.NonNull; -import android.support.annotation.RequiresApi; -import android.support.design.widget.AppBarLayout; -import android.support.design.widget.CoordinatorLayout; -import android.support.v4.app.Fragment; -import android.support.v4.view.NestedScrollingChild; -import android.support.v4.view.NestedScrollingParent; -import android.support.v4.view.PagerAdapter; -import android.support.v4.view.PagerAdapterWrapper; -import android.support.v4.view.ScrollingView; -import android.support.v4.view.ViewPager; -import android.support.v4.widget.NestedScrollView; -import android.support.v4.widget.Space; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.util.SparseArray; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.MeasureSpec; -import android.view.ViewGroup; -import android.view.animation.Interpolator; -import android.webkit.WebView; -import android.widget.AbsListView; -import android.widget.FrameLayout; -import android.widget.ListView; -import android.widget.ScrollView; - -import com.scwang.smartrefresh.layout.api.RefreshContent; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.api.RefreshScrollBoundary; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.util.ScrollBoundaryUtil; - -import java.util.Collections; -import java.util.Queue; -import java.util.concurrent.LinkedBlockingQueue; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; -import static com.scwang.smartrefresh.layout.util.ScrollBoundaryUtil.isTransformedTouchPointInView; - -/** - * 刷新内容包装 - * Created by SCWANG on 2017/5/26. - */ - -public class RefreshContentWrapper implements RefreshContent { - - private static final String TAG_REFRESH_CONTENT_WRAPPER = "TAG_REFRESH_CONTENT_WRAPPER"; - - private int mHeaderHeight = Integer.MAX_VALUE; - private int mFooterHeight = mHeaderHeight - 1; - private View mContentView; - private View mRealContentView; - private View mScrollableView; - private View mFixedHeader; - private View mFixedFooter; - private boolean mEnableRefresh = true; - private boolean mEnableLoadmore = true; - private MotionEvent mMotionEvent; - private RefreshScrollBoundaryAdapter mBoundaryAdapter = new RefreshScrollBoundaryAdapter(); - - public RefreshContentWrapper(View view) { - this.mContentView = mRealContentView = view; - this.mContentView.setTag(TAG_REFRESH_CONTENT_WRAPPER.hashCode(), TAG_REFRESH_CONTENT_WRAPPER); - } - - public RefreshContentWrapper(Context context) { - this.mContentView = mRealContentView = new View(context); - this.mContentView.setTag(TAG_REFRESH_CONTENT_WRAPPER.hashCode(), TAG_REFRESH_CONTENT_WRAPPER); - } - - public static boolean isTagedContent(View view) { - return TAG_REFRESH_CONTENT_WRAPPER.equals(view.getTag(TAG_REFRESH_CONTENT_WRAPPER.hashCode())); - } - - // - private void findScrollableView(View content, RefreshKernel kernel) { - mScrollableView = findScrollableViewInternal(content, true); - try { - if (mScrollableView instanceof CoordinatorLayout) { - kernel.getRefreshLayout().setNestedScrollingEnabled(false); - wrapperCoordinatorLayout(((CoordinatorLayout) mScrollableView), kernel.getRefreshLayout()); - } - } catch (Throwable e) {//try 不能删除 - e.printStackTrace(); - } - if (mScrollableView instanceof NestedScrollingParent - && !(mScrollableView instanceof NestedScrollingChild)) { - mScrollableView = findScrollableViewInternal(mScrollableView, false); - } - if (mScrollableView instanceof ViewPager) { - wrapperViewPager((ViewPager) this.mScrollableView); - } - if (mScrollableView == null) { - mScrollableView = content; - } - } - - private void wrapperCoordinatorLayout(CoordinatorLayout layout, final RefreshLayout refreshLayout) { - for (int i = layout.getChildCount() - 1; i >= 0; i--) { - View view = layout.getChildAt(i); - if (view instanceof AppBarLayout) { - ((AppBarLayout) view).addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() { - @Override - public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { - mEnableRefresh = verticalOffset >= 0; - mEnableLoadmore = refreshLayout.isEnableLoadmore() && (appBarLayout.getTotalScrollRange() + verticalOffset) <= 0; - } - }); - } - } - } - - private void wrapperViewPager(final ViewPager viewPager) { - wrapperViewPager(viewPager, null); - } - - private void wrapperViewPager(final ViewPager viewPager, final PagerPrimaryAdapter primaryAdapter) { - viewPager.post(new Runnable() { - int count = 0; - PagerPrimaryAdapter mAdapter = primaryAdapter; - @Override - public void run() { - count++; - PagerAdapter adapter = viewPager.getAdapter(); - if (adapter != null) { - if (adapter instanceof PagerPrimaryAdapter) { - if (adapter == primaryAdapter) { - viewPager.postDelayed(this, 500); - } - } else { - if (mAdapter == null) { - mAdapter = new PagerPrimaryAdapter(adapter); - } else { - mAdapter.wrapper(adapter); - } - mAdapter.attachViewPager(viewPager); - } - } else if (count < 10) { - viewPager.postDelayed(this, 500); - } - } - }); - } - - private View findScrollableViewInternal(View content, boolean selfable) { - View scrollableView = null; - Queue views = new LinkedBlockingQueue<>(Collections.singletonList(content)); - while (!views.isEmpty() && scrollableView == null) { - View view = views.poll(); - if (view != null) { - if ((selfable || view != content) && (view instanceof AbsListView - || view instanceof ScrollView - || view instanceof ScrollingView - || view instanceof NestedScrollingChild - || view instanceof NestedScrollingParent - || view instanceof WebView - || view instanceof ViewPager)) { - scrollableView = view; - } else if (view instanceof ViewGroup) { - ViewGroup group = (ViewGroup) view; - for (int j = 0; j < group.getChildCount(); j++) { - views.add(group.getChildAt(j)); - } - } - } - } - return scrollableView; - } - // - - // - @NonNull - public View getView() { - return mContentView; - } - - @Override - public boolean isNestedScrollingChild(MotionEvent e) { - MotionEvent event = MotionEvent.obtain(e); - event.offsetLocation(-mContentView.getLeft(), -mContentView.getTop() - mRealContentView.getTranslationY()); - boolean isNested = isNestedScrollingChild(mContentView, event); - event.recycle(); - return isNested; - } - - private boolean isNestedScrollingChild(View targetView, MotionEvent event) { - if (targetView instanceof NestedScrollingChild - || (Build.VERSION.SDK_INT >= 21 && targetView.isNestedScrollingEnabled())) { - return true; - } - if (targetView instanceof ViewGroup && event != null) { - ViewGroup viewGroup = (ViewGroup) targetView; - final int childCount = viewGroup.getChildCount(); - PointF point = new PointF(); - for (int i = childCount; i > 0; i--) { - View child = viewGroup.getChildAt(i - 1); - if (isTransformedTouchPointInView(viewGroup,child, event.getX(), event.getY() , point)) { - event = MotionEvent.obtain(event); - event.offsetLocation(point.x, point.y); - return isNestedScrollingChild(child, event); - } - } - } - return false; - } - - @Override - public void moveSpinner(int spinner) { - mRealContentView.setTranslationY(spinner); - if (mFixedHeader != null) { - mFixedHeader.setTranslationY(Math.max(0, spinner)); - } - if (mFixedFooter != null) { - mFixedFooter.setTranslationY(Math.min(0, spinner)); - } - } - - @Override - public boolean canScrollUp() { - return !mEnableRefresh || mBoundaryAdapter.canPullDown(mContentView); - } - - @Override - public boolean canScrollDown() { - return !mEnableLoadmore || mBoundaryAdapter.canPullUp(mContentView); - } - - @Override - public void measure(int widthSpec, int heightSpec) { - mContentView.measure(widthSpec, heightSpec); - } - - @Override - public ViewGroup.LayoutParams getLayoutParams() { - return mContentView.getLayoutParams(); - } - - @Override - public int getMeasuredWidth() { - return mContentView.getMeasuredWidth(); - } - - @Override - public int getMeasuredHeight() { - return mContentView.getMeasuredHeight(); - } - - @Override - public void layout(int left, int top, int right, int bottom) { - mContentView.layout(left, top, right, bottom); - } - - @Override - public View getScrollableView() { - return mScrollableView; - } - - @Override - public void onActionDown(MotionEvent e) { - mMotionEvent = MotionEvent.obtain(e); - mMotionEvent.offsetLocation(-mContentView.getLeft(), -mContentView.getTop()); - mBoundaryAdapter.setActionEvent(mMotionEvent); - } - - @Override - public void onActionUpOrCancel() { - mMotionEvent = null; - mBoundaryAdapter.setActionEvent(null); - } - - @Override - public void setupComponent(RefreshKernel kernel, View fixedHeader, View fixedFooter) { - this.findScrollableView(mContentView, kernel); - try { - if (mScrollableView instanceof RecyclerView) { - RecyclerViewScrollComponent component = new RecyclerViewScrollComponent(kernel); - component.attach((RecyclerView) mScrollableView); - } - } catch (Throwable e) { - e.printStackTrace(); - } - if (mScrollableView instanceof AbsListView) { - AbsListViewScrollComponent component = new AbsListViewScrollComponent(kernel); - component.attach(((AbsListView) mScrollableView)); - } else if (mScrollableView instanceof NestedScrollView) { - NestedScrollViewScrollComponent component = new NestedScrollViewScrollComponent(kernel); - component.attach((NestedScrollView) mScrollableView); - } else if (Build.VERSION.SDK_INT >= 23 && mScrollableView != null) { - mScrollableView.setOnScrollChangeListener(new Api23ViewScrollComponent(kernel)); - } - if (Build.VERSION.SDK_INT >= 21 - && mScrollableView instanceof ListView - && !(mScrollableView instanceof NestedScrollingChild)) { - mScrollableView.setNestedScrollingEnabled(true); - } - if (fixedHeader != null || fixedFooter != null) { - mFixedHeader = fixedHeader; - mFixedFooter = fixedFooter; - FrameLayout frameLayout = new FrameLayout(mContentView.getContext()); - kernel.getRefreshLayout().getLayout().removeView(mContentView); - ViewGroup.LayoutParams layoutParams = mContentView.getLayoutParams(); - frameLayout.addView(mContentView, MATCH_PARENT, MATCH_PARENT); - kernel.getRefreshLayout().getLayout().addView(frameLayout, layoutParams); - mContentView = frameLayout; - if (fixedHeader != null) { - fixedHeader.setClickable(true); - ViewGroup.LayoutParams lp = fixedHeader.getLayoutParams(); - ViewGroup parent = (ViewGroup) fixedHeader.getParent(); - int index = parent.indexOfChild(fixedHeader); - parent.removeView(fixedHeader); - lp.height = measureViewHeight(fixedHeader); - parent.addView(new Space(mContentView.getContext()), index, lp); - frameLayout.addView(fixedHeader); - } - if (fixedFooter != null) { - fixedFooter.setClickable(true); - ViewGroup.LayoutParams lp = fixedFooter.getLayoutParams(); - ViewGroup parent = (ViewGroup) fixedFooter.getParent(); - int index = parent.indexOfChild(fixedFooter); - parent.removeView(fixedFooter); - FrameLayout.LayoutParams flp = new FrameLayout.LayoutParams(lp); - lp.height = measureViewHeight(fixedFooter); - parent.addView(new Space(mContentView.getContext()), index, lp); - flp.gravity = Gravity.BOTTOM; - frameLayout.addView(fixedFooter, flp); - } - } - } - - @Override - public void onInitialHeaderAndFooter(int headerHeight, int footerHeight) { - mHeaderHeight = headerHeight; - mFooterHeight = footerHeight; - } - - @Override - public void setRefreshScrollBoundary(RefreshScrollBoundary boundary) { - if (boundary instanceof RefreshScrollBoundaryAdapter) { - mBoundaryAdapter = ((RefreshScrollBoundaryAdapter) boundary); - } else { - mBoundaryAdapter.setRefreshScrollBoundary(boundary); - } - } - - @Override - public AnimatorUpdateListener onLoadingFinish(final RefreshKernel kernel, final int footerHeight, int startDelay, Interpolator interpolator, final int duration) { - if (mScrollableView != null && kernel.getRefreshLayout().isEnableScrollContentWhenLoaded()) { - if (mScrollableView instanceof AbsListView && Build.VERSION.SDK_INT < 19) { - if (startDelay > 0) { - kernel.getRefreshLayout().getLayout().postDelayed(new Runnable() { - @Override - public void run() { - ((AbsListView) mScrollableView).smoothScrollBy(footerHeight, duration); - } - }, startDelay); - } else { - ((AbsListView) mScrollableView).smoothScrollBy(footerHeight, duration); - } - return null; - } - if (!ScrollBoundaryUtil.canScrollDown(mScrollableView)) { - return null; - } - return new AnimatorUpdateListener() { - int lastValue = kernel.getSpinner(); - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int thisValue = (int) animation.getAnimatedValue(); - if (mScrollableView instanceof AbsListView && Build.VERSION.SDK_INT >= 19) { - ((AbsListView) mScrollableView).scrollListBy(thisValue - lastValue); - } else { - mScrollableView.scrollBy(0, thisValue - lastValue); - } - lastValue = thisValue; - } - }; -// if (mScrollableView instanceof RecyclerView) ((RecyclerView) mScrollableView).smoothScrollBy(0, footerHeight, interpolator); -// else if (mScrollableView instanceof ScrollView) ((ScrollView) mScrollableView).smoothScrollBy(0, footerHeight); -// else if (mScrollableView instanceof AbsListView) ((AbsListView) mScrollableView).smoothScrollBy(footerHeight, duration); -// else { -// try { -// Method method = mScrollableView.getClass().getDeclaredMethod("smoothScrollBy", Integer.class, Integer.class); -// method.invoke(mScrollableView, 0, footerHeight); -// } catch (Exception ignored) { -// } -// } - } - return null; - } - // - - // - @RequiresApi(api = Build.VERSION_CODES.M) - private class Api23ViewScrollComponent implements View.OnScrollChangeListener { - long lastTime = 0; - long lastTimeOld = 0; - int lastScrollY = 0; - int lastOldScrollY = 0; - RefreshKernel kernel; - - Api23ViewScrollComponent(RefreshKernel kernel) { - this.kernel = kernel; - } - - @Override - public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { - if (lastScrollY == scrollY && lastOldScrollY == oldScrollY) { - return; - } -// System.out.printf("%d,%d,%d,%d\n", scrollX, scrollY, oldScrollX, oldScrollY); - RefreshLayout layout = kernel.getRefreshLayout(); - boolean overScroll = layout.isEnableOverScrollBounce() || layout.isRefreshing() || layout.isLoading(); - if (scrollY <= 0 && oldScrollY > 0 && mMotionEvent == null && lastTime - lastTimeOld > 1000 && overScroll && layout.isEnableRefresh()) { - //time:16000000 value:160 - final int velocity = (lastOldScrollY - oldScrollY) * 16000 / (int)((lastTime - lastTimeOld)/1000f); -// System.out.println("ValueAnimator - " + (lastTime - lastTimeOld) + " - " + velocity+"("+(lastOldScrollY - oldScrollY)+")"); - kernel.animSpinnerBounce(Math.min(velocity, mHeaderHeight)); - } else if (oldScrollY < scrollY && mMotionEvent == null && overScroll && layout.isEnableLoadmore()) { - if (lastTime - lastTimeOld > 1000 && !ScrollBoundaryUtil.canScrollDown(v)) { - final int velocity = (lastOldScrollY - oldScrollY) * 16000 / (int)((lastTime - lastTimeOld)/1000f); -// System.out.println("ValueAnimator - " + (lastTime - lastTimeOld) + " - " + velocity+"("+(lastOldScrollY - oldScrollY)+")"); - kernel.animSpinnerBounce(Math.max(velocity, -mFooterHeight)); - } - } - lastScrollY = scrollY; - lastOldScrollY = oldScrollY; - lastTimeOld = lastTime; - lastTime = System.nanoTime(); - } - } - - private class NestedScrollViewScrollComponent implements NestedScrollView.OnScrollChangeListener { - long lastTime = 0; - long lastTimeOld = 0; - int lastScrollY = 0; - int lastOldScrollY = 0; - RefreshKernel kernel; - - NestedScrollViewScrollComponent(RefreshKernel kernel) { - this.kernel = kernel; - } - - @Override - public void onScrollChange(NestedScrollView scrollView, int scrollX, int scrollY, int oldScrollX, int oldScrollY) { - if (lastScrollY == scrollY && lastOldScrollY == oldScrollY) { - return; - } - RefreshLayout layout = kernel.getRefreshLayout(); - boolean overScroll = layout.isEnableOverScrollBounce() || layout.isRefreshing() || layout.isLoading(); - if (scrollY <= 0 && oldScrollY > 0 && mMotionEvent == null && lastTime - lastTimeOld > 1000 && overScroll && layout.isEnableRefresh()) { - final int velocity = (lastOldScrollY - oldScrollY) * 16000 / (int)((lastTime - lastTimeOld)/1000f); - kernel.animSpinnerBounce(Math.min(velocity, mHeaderHeight)); - } else if (oldScrollY < scrollY && mMotionEvent == null && layout.isEnableLoadmore()) { - if (!layout.isLoadmoreFinished() && layout.isEnableAutoLoadmore() - && layout.getState() == RefreshState.None - && !ScrollBoundaryUtil.canScrollDown(scrollView)) { - kernel.getRefreshLayout().autoLoadmore(0, 1); - } else if (overScroll && lastTime - lastTimeOld > 1000 && !ScrollBoundaryUtil.canScrollDown(mScrollableView)) { - final int velocity = (lastOldScrollY - oldScrollY) * 16000 / (int)((lastTime - lastTimeOld)/1000f); - kernel.animSpinnerBounce(Math.max(velocity, -mFooterHeight)); - } - } - lastScrollY = scrollY; - lastOldScrollY = oldScrollY; - lastTimeOld = lastTime; - lastTime = System.nanoTime(); - } - - void attach(NestedScrollView scrollView) { - scrollView.setOnScrollChangeListener(this); - } - } - - private class AbsListViewScrollComponent implements AbsListView.OnScrollListener { - - int scrollY; - int scrollDy; - int lastScrolly; - int lastScrollDy; - RefreshKernel kernel; - SparseArray recordSp = new SparseArray<>(0); - - AbsListViewScrollComponent(RefreshKernel kernel) { - this.kernel = kernel; - } - - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - } - - @Override - public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - lastScrolly = scrollY; - lastScrollDy = scrollDy; - scrollY = getScrollY(absListView, firstVisibleItem); - scrollDy = lastScrolly - scrollY; - - final int dy =lastScrollDy + scrollDy; - if (totalItemCount > 0) { - RefreshLayout layout = kernel.getRefreshLayout(); - boolean overScroll = (layout.isEnableOverScrollBounce() || layout.isRefreshing() || layout.isLoading()); - if (mMotionEvent == null && dy > 0 && firstVisibleItem == 0) { - if (overScroll - && layout.isEnableRefresh() - && !ScrollBoundaryUtil.canScrollUp(absListView)) { - kernel.animSpinnerBounce(Math.min(dy, mHeaderHeight)); - } - } else if (dy < 0) { - int lastVisiblePosition = absListView.getLastVisiblePosition(); - if (lastVisiblePosition == totalItemCount - 1 && lastVisiblePosition > 0 - && layout.isEnableLoadmore()) { - if (!layout.isLoadmoreFinished() && layout.isEnableAutoLoadmore() - && layout.getState() == RefreshState.None - && !ScrollBoundaryUtil.canScrollDown(absListView)) { - kernel.getRefreshLayout().autoLoadmore(0, 1); - } else if (mMotionEvent == null && overScroll && !ScrollBoundaryUtil.canScrollDown(absListView)) { - kernel.animSpinnerBounce(Math.max(dy, -mFooterHeight)); - } - } - } - } - - } - - void attach(AbsListView listView) { - listView.setOnScrollListener(this); - } - - private int getScrollY(AbsListView view, int firstVisibleItem) { - View firstView = view.getChildAt(0); - if (null != firstView) { - ItemRecod itemRecord = recordSp.get(firstVisibleItem); - if (null == itemRecord) { - itemRecord = new ItemRecod(); - } - itemRecord.height = firstView.getHeight(); - itemRecord.top = firstView.getTop(); - recordSp.append(firstVisibleItem, itemRecord); - - int height = 0,lastheight = 0; - for (int i = 0; i < firstVisibleItem; i++) { - ItemRecod itemRecod = recordSp.get(i); - if (itemRecod != null) { - height += itemRecod.height; - lastheight = itemRecod.height; - } else { - height += lastheight; - } - } - ItemRecod itemRecod = recordSp.get(firstVisibleItem); - if (null == itemRecod) { - itemRecod = new ItemRecod(); - } - return height - itemRecod.top; - } - return 0; - } - - class ItemRecod { - int height = 0; - int top = 0; - } - } - - private class RecyclerViewScrollComponent extends RecyclerView.OnScrollListener { - int lastDy; - long lastFlingTime; - RefreshKernel kernel; - - RecyclerViewScrollComponent(RefreshKernel kernel) { - this.kernel = kernel; - } - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - RefreshLayout layout = kernel.getRefreshLayout(); - if (newState == RecyclerView.SCROLL_STATE_IDLE && mMotionEvent == null) { - boolean intime = System.currentTimeMillis() - lastFlingTime < 1000; - boolean overScroll = layout.isEnableOverScrollBounce() || layout.isRefreshing() || layout.isLoading(); - if (lastDy < -1 && intime && overScroll && layout.isEnableRefresh()) { - kernel.animSpinnerBounce(Math.min(-lastDy * 2, mHeaderHeight)); - } else if (layout.isEnableLoadmore() - && !layout.isLoadmoreFinished() - && layout.isEnableAutoLoadmore() - && layout.getState() == RefreshState.None) { -// RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); -// if (manager instanceof LinearLayoutManager) { -// LinearLayoutManager linearManager = ((LinearLayoutManager) manager); -// int lastVisiblePosition = linearManager.findLastVisibleItemPosition(); -// if(lastVisiblePosition >= linearManager.getItemCount() - 1){ -// kernel.getRefreshLayout().autoLoadmore(0,1); -// } -// } - } else if (lastDy > 1 && intime && overScroll && layout.isEnableLoadmore()) { - kernel.animSpinnerBounce(Math.max(-lastDy * 2, -mFooterHeight)); - } - lastDy = 0; - } - } - - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - lastDy = dy; - RefreshLayout layout = kernel.getRefreshLayout(); - if (dy > 0 - && layout.isEnableLoadmore() - && !layout.isLoadmoreFinished() - && layout.isEnableAutoLoadmore() - && layout.getState() == RefreshState.None ){ - RecyclerView.LayoutManager manager = recyclerView.getLayoutManager(); - if (manager instanceof LinearLayoutManager) { - LinearLayoutManager linearManager = ((LinearLayoutManager) manager); - int lastVisiblePosition = linearManager.findLastVisibleItemPosition(); - if(lastVisiblePosition >= linearManager.getItemCount() - 1 - && lastVisiblePosition > 0 - && !ScrollBoundaryUtil.canScrollDown(recyclerView)){ - kernel.getRefreshLayout().autoLoadmore(0,1); - } - } - } - } - - void attach(RecyclerView recyclerView) { - recyclerView.addOnScrollListener(this); - recyclerView.setOnFlingListener(new RecyclerView.OnFlingListener() { - @Override - public boolean onFling(int velocityX, int velocityY) { - lastFlingTime = System.currentTimeMillis(); - return false; - } - }); - } - } - // - - // - private static int measureViewHeight(View view) { - ViewGroup.LayoutParams p = view.getLayoutParams(); - if (p == null) { - p = new ViewGroup.LayoutParams(MATCH_PARENT,WRAP_CONTENT); - } - int childHeightSpec; - int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, p.width); - if (p.height > 0) { - childHeightSpec = MeasureSpec.makeMeasureSpec(p.height, MeasureSpec.EXACTLY); - } else { - childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - } - view.measure(childWidthSpec, childHeightSpec); - return view.getMeasuredHeight(); - } - // - - private class PagerPrimaryAdapter extends PagerAdapterWrapper { - private ViewPager mViewPager; - - PagerPrimaryAdapter(PagerAdapter wrapped) { - super(wrapped); - } - - void wrapper(PagerAdapter adapter) { - wrapped = adapter; - } - - @Override - public void attachViewPager(ViewPager viewPager) { - mViewPager = viewPager; - super.attachViewPager(viewPager); - } - - @Override - public void setViewPagerObserver(DataSetObserver observer) { - super.setViewPagerObserver(observer); - if (observer == null) { - wrapperViewPager(mViewPager, this); - } - } - - @Override - public void setPrimaryItem(ViewGroup container, int position, Object object) { - super.setPrimaryItem(container, position, object); - if (object instanceof View) { - mScrollableView = ((View) object); - } else if (object instanceof Fragment) { - mScrollableView = ((Fragment) object).getView(); - } - if (mScrollableView != null) { - mScrollableView = findScrollableViewInternal(mScrollableView, true); - if (mScrollableView instanceof NestedScrollingParent - && !(mScrollableView instanceof NestedScrollingChild)) { - mScrollableView = findScrollableViewInternal(mScrollableView, false); - } - } - } - } -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshFooterWrapper.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshFooterWrapper.java index bdc6755a..6bf8f505 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshFooterWrapper.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshFooterWrapper.java @@ -1,92 +1,20 @@ package com.scwang.smartrefresh.layout.impl; -import android.support.annotation.NonNull; +import android.annotation.SuppressLint; import android.view.View; -import android.view.ViewGroup; import com.scwang.smartrefresh.layout.api.RefreshFooter; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.internal.InternalAbstract; /** * 刷新底部包装 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ - -public class RefreshFooterWrapper implements RefreshFooter { - - private static final String TAG_REFRESH_FOOTER_WRAPPER = "TAG_REFRESH_FOOTER_WRAPPER"; - - private View mWrapperView; - private SpinnerStyle mSpinnerStyle; +@SuppressLint("ViewConstructor") +public class RefreshFooterWrapper extends InternalAbstract implements RefreshFooter { public RefreshFooterWrapper(View wrapper) { - this.mWrapperView = wrapper; - this.mWrapperView.setTag(TAG_REFRESH_FOOTER_WRAPPER.hashCode(), TAG_REFRESH_FOOTER_WRAPPER); - } - - public static boolean isTagedFooter(View view) { - return TAG_REFRESH_FOOTER_WRAPPER.equals(view.getTag(TAG_REFRESH_FOOTER_WRAPPER.hashCode())); - } - - @NonNull - public View getView() { - return mWrapperView; + super(wrapper); } - @Override - public int onFinish(RefreshLayout layout, boolean success) { - return 0; - } - - @Override - public void setPrimaryColors(int... colors) { - - } - - @Override - public SpinnerStyle getSpinnerStyle() { - if (mSpinnerStyle != null) { - return mSpinnerStyle; - } - ViewGroup.LayoutParams params = mWrapperView.getLayoutParams(); - if (params != null) { - if (params.height == 0) { - return mSpinnerStyle = SpinnerStyle.Scale; - } - } - return mSpinnerStyle = SpinnerStyle.Translate; - } - - @Override - public void onInitialized(RefreshKernel layout, int height, int extendHeight) { - - } - - @Override - public void onPullingUp(float percent, int offset, int footerHeight, int extendHeight) { - - } - - @Override - public void onPullReleasing(float percent, int offset, int footerHeight, int extendHeight) { - - } - - @Override - public void onStartAnimator(RefreshLayout layout, int footerHeight, int extendHeight) { - - } - - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - - } - - @Override - public boolean setLoadmoreFinished(boolean finished) { - return false; - } } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshHeaderWrapper.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshHeaderWrapper.java index 7048128d..3f1c1893 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshHeaderWrapper.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshHeaderWrapper.java @@ -1,87 +1,20 @@ package com.scwang.smartrefresh.layout.impl; -import android.support.annotation.NonNull; +import android.annotation.SuppressLint; import android.view.View; -import android.view.ViewGroup; import com.scwang.smartrefresh.layout.api.RefreshHeader; -import com.scwang.smartrefresh.layout.api.RefreshKernel; -import com.scwang.smartrefresh.layout.api.RefreshLayout; -import com.scwang.smartrefresh.layout.constant.RefreshState; -import com.scwang.smartrefresh.layout.constant.SpinnerStyle; +import com.scwang.smartrefresh.layout.internal.InternalAbstract; /** * 刷新头部包装 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ - -public class RefreshHeaderWrapper implements RefreshHeader { - - private static final String TAG_REFRESH_HEADER_WRAPPER = "TAG_REFRESH_HEADER_WRAPPER"; - - private View mWrapperView; - private SpinnerStyle mSpinnerStyle; +@SuppressLint("ViewConstructor") +public class RefreshHeaderWrapper extends InternalAbstract implements RefreshHeader { public RefreshHeaderWrapper(View wrapper) { - this.mWrapperView = wrapper; - this.mWrapperView.setTag(TAG_REFRESH_HEADER_WRAPPER.hashCode(), TAG_REFRESH_HEADER_WRAPPER); - } - - public static boolean isTagedHeader(View view) { - return TAG_REFRESH_HEADER_WRAPPER.equals(view.getTag(TAG_REFRESH_HEADER_WRAPPER.hashCode())); - } - @NonNull - public View getView() { - return mWrapperView; - } - - @Override - public int onFinish(RefreshLayout layout, boolean success) { - return 0; - } - - @Override - public void setPrimaryColors(int... colors) { - + super(wrapper); } - @NonNull - @Override - public SpinnerStyle getSpinnerStyle() { - if (mSpinnerStyle != null) { - return mSpinnerStyle; - } - ViewGroup.LayoutParams params = mWrapperView.getLayoutParams(); - if (params != null) { - if (params.height == ViewGroup.LayoutParams.MATCH_PARENT) { - return mSpinnerStyle = SpinnerStyle.Scale; - } - } - return mSpinnerStyle = SpinnerStyle.Translate; - } - - @Override - public void onInitialized(RefreshKernel layout, int height, int extendHeight) { - - } - - @Override - public void onPullingDown(float percent, int offset, int headHeight, int extendHeight) { - - } - - @Override - public void onReleasing(float percent, int offset, int headHeight, int extendHeight) { - - } - - @Override - public void onStartAnimator(RefreshLayout layout, int headHeight, int extendHeight) { - - } - - @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { - - } } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshScrollBoundaryAdapter.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshScrollBoundaryAdapter.java deleted file mode 100644 index 6aded476..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/RefreshScrollBoundaryAdapter.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.scwang.smartrefresh.layout.impl; - -import android.view.MotionEvent; -import android.view.View; - -import com.scwang.smartrefresh.layout.api.RefreshScrollBoundary; - -import static com.scwang.smartrefresh.layout.util.ScrollBoundaryUtil.canScrollDown; -import static com.scwang.smartrefresh.layout.util.ScrollBoundaryUtil.canScrollUp; - -/** - * 滚动边界 - * Created by SCWANG on 2017/7/8. - */ - -public class RefreshScrollBoundaryAdapter implements RefreshScrollBoundary { - - // - MotionEvent mActionEvent; - RefreshScrollBoundary boundary; - - void setRefreshScrollBoundary(RefreshScrollBoundary boundary){ - this.boundary = boundary; - } - - void setActionEvent(MotionEvent event) { - mActionEvent = event; - } - // - - // - @Override - public boolean canPullDown(View content) { - if (boundary != null) { - return boundary.canPullDown(content); - } - return canScrollUp(content, mActionEvent); - } - - @Override - public boolean canPullUp(View content) { - if (boundary != null) { - return boundary.canPullUp(content); - } - return canScrollDown(content, mActionEvent); - } - // -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/ScrollBoundaryDeciderAdapter.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/ScrollBoundaryDeciderAdapter.java new file mode 100644 index 00000000..fabaecc5 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/impl/ScrollBoundaryDeciderAdapter.java @@ -0,0 +1,12 @@ +package com.scwang.smartrefresh.layout.impl; + +import com.scwang.smart.refresh.layout.simple.SimpleBoundaryDecider; +import com.scwang.smartrefresh.layout.api.ScrollBoundaryDecider; + +/** + * 滚动边界 + * Created by scwang on 2017/7/8. + */ +public class ScrollBoundaryDeciderAdapter extends SimpleBoundaryDecider implements ScrollBoundaryDecider { + +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/ArrowDrawable.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/ArrowDrawable.java new file mode 100644 index 00000000..4d8ba11e --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/ArrowDrawable.java @@ -0,0 +1,10 @@ +package com.scwang.smartrefresh.layout.internal; + +/** + * 箭头图像 + * Created by scwang on 2018/2/5. + */ +@SuppressWarnings("unused") +public class ArrowDrawable extends com.scwang.smart.refresh.classics.ArrowDrawable { + +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/InternalAbstract.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/InternalAbstract.java new file mode 100644 index 00000000..35df9d41 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/InternalAbstract.java @@ -0,0 +1,33 @@ +package com.scwang.smartrefresh.layout.internal; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.util.AttributeSet; +import android.view.View; + +import com.scwang.smart.refresh.layout.simple.SimpleComponent; +import com.scwang.smartrefresh.layout.api.RefreshInternal; + +/** + * Internal 初步实现 + * 实现 Header 和 Footer 时,继承 InternalAbstract 的话可以少写很多接口方法 + * Created by scwang on 2018/2/6. + */ +public abstract class InternalAbstract extends SimpleComponent { + + + protected InternalAbstract(@NonNull View wrapped) { + super(wrapped); + } + + protected InternalAbstract(@NonNull View wrappedView, @Nullable RefreshInternal wrappedInternal) { + super(wrappedView, wrappedInternal); + } + + protected InternalAbstract(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/PaintDrawable.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/PaintDrawable.java new file mode 100644 index 00000000..53ad8bd3 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/PaintDrawable.java @@ -0,0 +1,9 @@ +package com.scwang.smartrefresh.layout.internal; + +/** + * 画笔 Drawable + * Created by scwang on 2017/6/16. + */ +public abstract class PaintDrawable extends com.scwang.smart.drawable.PaintDrawable { + +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/ProgressDrawable.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/ProgressDrawable.java index 338b8bd8..43c7e49b 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/ProgressDrawable.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/ProgressDrawable.java @@ -1,117 +1,9 @@ package com.scwang.smartrefresh.layout.internal; -import android.animation.ValueAnimator; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Animatable; -import android.graphics.drawable.Drawable; -import android.support.annotation.NonNull; -import android.view.animation.LinearInterpolator; - /** * 旋转动画 - * Created by SCWANG on 2017/6/16. + * Created by scwang on 2017/6/16. */ +public class ProgressDrawable extends com.scwang.smart.drawable.ProgressDrawable { -public class ProgressDrawable extends Drawable implements Animatable { - - private int mProgressDegree = 0; - private ValueAnimator mValueAnimator; - private Path mPath = new Path(); - private Paint mPaint = new Paint(); - - public ProgressDrawable() { - mPaint.setStyle(Paint.Style.FILL); - mPaint.setAntiAlias(true); - mPaint.setColor(0xffaaaaaa); - setupAnimators(); - } - - public void setColor(int color) { - mPaint.setColor(color); - } - - // - @Override - public void draw(@NonNull Canvas canvas) { - Rect bounds = getBounds(); - int width = bounds.width(); - int height = bounds.height(); - canvas.save(); - canvas.rotate(mProgressDegree, (width) / 2, (height) / 2); - final int r = Math.max(1, width / 20); - for (int i = 0; i < 12; i++) { - mPath.reset(); - mPath.addCircle(width - r, height / 2, r, Path.Direction.CW); - mPath.addRect(width - 5 * r, height / 2 - r, width - r, height / 2 + r, Path.Direction.CW); - mPath.addCircle(width - 5 * r, height / 2, r, Path.Direction.CW); - mPaint.setAlpha((i+5) * 0x11); - canvas.rotate(30, (width) / 2, (height) / 2); - canvas.drawPath(mPath, mPaint); - } - canvas.restore(); - } - - @Override - public void setAlpha(int alpha) { - mPaint.setAlpha(alpha); - } - - @Override - public void setColorFilter(ColorFilter cf) { - mPaint.setColorFilter(cf); - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - // - - private void setupAnimators() { - mValueAnimator = ValueAnimator.ofInt(30, 3600); - mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int value = (int) animation.getAnimatedValue(); - mProgressDegree = 30 * (value / 30); - invalidateSelf(); - } - }); - mValueAnimator.setDuration(10000); - mValueAnimator.setInterpolator(new LinearInterpolator()); - mValueAnimator.setRepeatCount(ValueAnimator.INFINITE); - mValueAnimator.setRepeatMode(ValueAnimator.RESTART); - } - - @Override - public void start() { - if (!mValueAnimator.isRunning()) { - mValueAnimator.start(); - } - } - - @Override - public void stop() { - if (mValueAnimator.isRunning()) { - mValueAnimator.cancel(); - } - } - - @Override - public boolean isRunning() { - return mValueAnimator.isRunning(); - } - - public int width() { - return getBounds().width(); - } - - public int height() { - return getBounds().height(); - } } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/pathview/PathsView.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/pathview/PathsView.java deleted file mode 100644 index f7486051..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/internal/pathview/PathsView.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.scwang.smartrefresh.layout.internal.pathview; - -import android.content.Context; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.view.View; - -/** - * 路径视图 - * Created by SCWANG on 2017/5/29. - */ - -public class PathsView extends View { - - protected PathsDrawable mPathsDrawable = new PathsDrawable(); - - public PathsView(Context context) { - super(context); - this.initView(context, null, 0); - } - - public PathsView(Context context, AttributeSet attrs) { - super(context, attrs); - this.initView(context, attrs, 0); - } - - public PathsView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - this.initView(context, attrs, defStyleAttr); - } - - private void initView(Context context, AttributeSet attrs, int defStyleAttr) { - mPathsDrawable = new PathsDrawable(); - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - if (getTag() instanceof String) { - parserPaths(getTag().toString()); - } - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(resolveSize(mPathsDrawable.width()+getPaddingLeft()+getPaddingRight(), widthMeasureSpec), - resolveSize(mPathsDrawable.height()+getPaddingTop()+getPaddingBottom(), heightMeasureSpec)); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - mPathsDrawable.setBounds(getPaddingLeft(), getPaddingTop(), - Math.max((right - left) - getPaddingRight(), getPaddingLeft()), - Math.max((bottom - top) - getPaddingTop(), getPaddingTop())); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - mPathsDrawable.draw(canvas); - } - - public void parserPaths(String... paths) { - mPathsDrawable.parserPaths(paths); - } - - public void parserColors(int... colors) { - mPathsDrawable.parserColors(colors); - } - - -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/AnimationEndListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/AnimationEndListener.java deleted file mode 100644 index ada3fb38..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/AnimationEndListener.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.scwang.smartrefresh.layout.listener; - -/** - * 动画 - * Created by SCWANG on 2017/6/21. - */ - -public interface AnimationEndListener { - void onAnimationEnd(); -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnLoadMoreListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnLoadMoreListener.java new file mode 100644 index 00000000..85b96bcc --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnLoadMoreListener.java @@ -0,0 +1,13 @@ +package com.scwang.smartrefresh.layout.listener; + +import android.support.annotation.NonNull; + +import com.scwang.smartrefresh.layout.api.RefreshLayout; + +/** + * 加载更多监听器 + * Created by scwang on 2017/5/26. + */ +public interface OnLoadMoreListener { + void onLoadMore(@NonNull RefreshLayout refreshLayout); +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnLoadmoreListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnLoadmoreListener.java deleted file mode 100644 index 99732b85..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnLoadmoreListener.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.scwang.smartrefresh.layout.listener; - -import com.scwang.smartrefresh.layout.api.RefreshLayout; - -/** - * 加载更多监听器 - * Created by SCWANG on 2017/5/26. - */ - -public interface OnLoadmoreListener { - void onLoadmore(RefreshLayout refreshlayout); -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnMultiPurposeListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnMultiPurposeListener.java index 2ae0727d..6f16d289 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnMultiPurposeListener.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnMultiPurposeListener.java @@ -5,17 +5,36 @@ /** * 多功能监听器 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ +public interface OnMultiPurposeListener extends OnRefreshLoadMoreListener, OnStateChangedListener { + /** + * 手指拖动下拉(会连续多次调用,添加isDragging并取代之前的onPulling、onReleasing) + * @param header 头部 + * @param isDragging true 手指正在拖动 false 回弹动画 + * @param percent 下拉的百分比 值 = offset/footerHeight (0 - percent - (footerHeight+maxDragHeight) / footerHeight ) + * @param offset 下拉的像素偏移量 0 - offset - (footerHeight+maxDragHeight) + * @param headerHeight 高度 HeaderHeight or FooterHeight + * @param maxDragHeight 最大拖动高度 + */ + void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight); -public interface OnMultiPurposeListener extends OnRefreshLoadmoreListener, OnStateChangedListener { - void onHeaderPulling(RefreshHeader header, float percent, int offset, int headerHeight, int extendHeight); - void onHeaderReleasing(RefreshHeader header, float percent, int offset, int headerHeight, int extendHeight); - void onHeaderStartAnimator(RefreshHeader header, int headerHeight, int extendHeight); + void onHeaderReleased(RefreshHeader header, int headerHeight, int maxDragHeight); + void onHeaderStartAnimator(RefreshHeader header, int headerHeight, int maxDragHeight); void onHeaderFinish(RefreshHeader header, boolean success); - void onFooterPulling(RefreshFooter footer, float percent, int offset, int footerHeight, int extendHeight); - void onFooterReleasing(RefreshFooter footer, float percent, int offset, int footerHeight, int extendHeight); - void onFooterStartAnimator(RefreshFooter footer, int footerHeight, int extendHeight); + /** + * 手指拖动上拉(会连续多次调用,添加isDragging并取代之前的onPulling、onReleasing) + * @param footer 尾部 + * @param isDragging true 手指正在拖动 false 回弹动画 + * @param percent 下拉的百分比 值 = offset/footerHeight (0 - percent - (footerHeight+maxDragHeight) / footerHeight ) + * @param offset 下拉的像素偏移量 0 - offset - (footerHeight+maxDragHeight) + * @param footerHeight 高度 HeaderHeight or FooterHeight + * @param maxDragHeight 最大拖动高度 + */ + void onFooterMoving(RefreshFooter footer, boolean isDragging, float percent, int offset, int footerHeight, int maxDragHeight); + + void onFooterReleased(RefreshFooter footer, int footerHeight, int maxDragHeight); + void onFooterStartAnimator(RefreshFooter footer, int footerHeight, int maxDragHeight); void onFooterFinish(RefreshFooter footer, boolean success); } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshListener.java index 4da064f6..149d74ab 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshListener.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshListener.java @@ -1,12 +1,13 @@ package com.scwang.smartrefresh.layout.listener; +import android.support.annotation.NonNull; + import com.scwang.smartrefresh.layout.api.RefreshLayout; /** * 刷新监听器 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ - public interface OnRefreshListener { - void onRefresh(RefreshLayout refreshlayout); + void onRefresh(@NonNull RefreshLayout refreshLayout); } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshLoadMoreListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshLoadMoreListener.java new file mode 100644 index 00000000..60394b77 --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshLoadMoreListener.java @@ -0,0 +1,8 @@ +package com.scwang.smartrefresh.layout.listener; + +/** + * 刷新加载组合监听器 + * Created by scwang on 2017/5/26. + */ +public interface OnRefreshLoadMoreListener extends OnRefreshListener, OnLoadMoreListener { +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshLoadmoreListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshLoadmoreListener.java deleted file mode 100644 index ab45c27c..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnRefreshLoadmoreListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.scwang.smartrefresh.layout.listener; - -/** - * 刷新加载组合监听器 - * Created by SCWANG on 2017/5/26. - */ - -public interface OnRefreshLoadmoreListener extends OnRefreshListener, OnLoadmoreListener{ -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnStateChangedListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnStateChangedListener.java index e492011a..4ba6ad67 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnStateChangedListener.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/OnStateChangedListener.java @@ -1,20 +1,27 @@ package com.scwang.smartrefresh.layout.listener; +import android.support.annotation.NonNull; +import android.support.annotation.RestrictTo; + import com.scwang.smartrefresh.layout.api.RefreshLayout; import com.scwang.smartrefresh.layout.constant.RefreshState; +import static android.support.annotation.RestrictTo.Scope.LIBRARY; +import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; +import static android.support.annotation.RestrictTo.Scope.SUBCLASSES; + /** * 刷新状态改变监听器 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ - public interface OnStateChangedListener { /** - * 状态改变事件 {@link RefreshState} + * 【仅限框架内调用】状态改变事件 {@link RefreshState} * @param refreshLayout RefreshLayout * @param oldState 改变之前的状态 * @param newState 改变之后的状态 */ - void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState); + @RestrictTo({LIBRARY,LIBRARY_GROUP,SUBCLASSES}) + void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState); } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/SimpleMultiPurposeListener.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/SimpleMultiPurposeListener.java index e356313f..97a43065 100644 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/SimpleMultiPurposeListener.java +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/listener/SimpleMultiPurposeListener.java @@ -1,5 +1,8 @@ package com.scwang.smartrefresh.layout.listener; +import android.support.annotation.NonNull; + +import com.scwang.smart.refresh.layout.listener.OnMultiListener; import com.scwang.smartrefresh.layout.api.RefreshFooter; import com.scwang.smartrefresh.layout.api.RefreshHeader; import com.scwang.smartrefresh.layout.api.RefreshLayout; @@ -7,63 +10,173 @@ /** * 多功能监听器 - * Created by SCWANG on 2017/5/26. + * Created by scwang on 2017/5/26. */ +public class SimpleMultiPurposeListener implements OnMultiPurposeListener, OnMultiListener { + + private RefreshLayout refreshLayout; + private OnMultiPurposeListener listener; + + public SimpleMultiPurposeListener() { + + } -public class SimpleMultiPurposeListener implements OnMultiPurposeListener { + public SimpleMultiPurposeListener(OnMultiPurposeListener listener, RefreshLayout refreshLayout) { + this.listener = listener; + this.refreshLayout = refreshLayout; + } @Override - public void onHeaderPulling(RefreshHeader header, float percent, int offset, int headerHeight, int extendHeight) { + public void onHeaderMoving(RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) { + if (listener != null) { + listener.onHeaderMoving(header, isDragging, percent, offset, headerHeight, maxDragHeight); + } + } + @Override + public void onHeaderReleased(RefreshHeader header, int headerHeight, int maxDragHeight) { + if (listener != null) { + listener.onHeaderReleased(header, headerHeight, maxDragHeight); + } } @Override - public void onHeaderReleasing(RefreshHeader header, float percent, int offset, int footerHeight, int extendHeight) { + public void onHeaderStartAnimator(RefreshHeader header, int footerHeight, int maxDragHeight) { + if (listener != null) { + listener.onHeaderStartAnimator(header, footerHeight, maxDragHeight); + } + } + @Override + public void onHeaderFinish(RefreshHeader header, boolean success) { + if (listener != null) { + listener.onHeaderFinish(header, success); + } } @Override - public void onHeaderStartAnimator(RefreshHeader header, int footerHeight, int extendHeight) { + public void onFooterMoving(RefreshFooter footer, boolean isDragging, float percent, int offset, int footerHeight, int maxDragHeight) { + if (listener != null) { + listener.onFooterMoving(footer, isDragging, percent, offset, footerHeight, maxDragHeight); + } + } + @Override + public void onFooterReleased(RefreshFooter footer, int footerHeight, int maxDragHeight) { + if (listener != null) { + listener.onFooterReleased(footer, footerHeight, maxDragHeight); + } } @Override - public void onHeaderFinish(RefreshHeader header, boolean success) { + public void onFooterStartAnimator(RefreshFooter footer, int headerHeight, int maxDragHeight) { + if (listener != null) { + listener.onFooterStartAnimator(footer, headerHeight, maxDragHeight); + } + } + @Override + public void onFooterFinish(RefreshFooter footer, boolean success) { + if (listener != null) { + listener.onFooterFinish(footer, success); + } } @Override - public void onFooterPulling(RefreshFooter footer, float percent, int offset, int footerHeight, int extendHeight) { + public void onRefresh(@NonNull RefreshLayout refreshLayout) { + if (listener != null) { + listener.onRefresh(refreshLayout); + } + } + @Override + public void onLoadMore(@NonNull RefreshLayout refreshLayout) { + if (listener != null) { + listener.onLoadMore(refreshLayout); + } } @Override - public void onFooterReleasing(RefreshFooter footer, float percent, int offset, int footerHeight, int extendHeight) { + public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) { + if (listener != null) { + listener.onStateChanged(refreshLayout, oldState, newState); + } + } + @Override + public void onHeaderMoving(com.scwang.smart.refresh.layout.api.RefreshHeader header, boolean isDragging, float percent, int offset, int headerHeight, int maxDragHeight) { + if (refreshLayout != null) { + onHeaderMoving(refreshLayout.getRefreshHeader(), isDragging, percent, offset, headerHeight, maxDragHeight); + } } @Override - public void onFooterStartAnimator(RefreshFooter footer, int headHeight, int extendHeight) { + public void onHeaderReleased(com.scwang.smart.refresh.layout.api.RefreshHeader header, int headerHeight, int maxDragHeight) { + if (refreshLayout != null) { + onHeaderReleased(refreshLayout.getRefreshHeader(), headerHeight, maxDragHeight); + } + } + @Override + public void onHeaderStartAnimator(com.scwang.smart.refresh.layout.api.RefreshHeader header, int headerHeight, int maxDragHeight) { + if (refreshLayout != null) { + onHeaderStartAnimator(refreshLayout.getRefreshHeader(), headerHeight, maxDragHeight); + } } @Override - public void onFooterFinish(RefreshFooter footer, boolean success) { + public void onHeaderFinish(com.scwang.smart.refresh.layout.api.RefreshHeader header, boolean success) { + if (refreshLayout != null) { + onHeaderFinish(refreshLayout.getRefreshHeader(), success); + } + } + @Override + public void onFooterMoving(com.scwang.smart.refresh.layout.api.RefreshFooter footer, boolean isDragging, float percent, int offset, int footerHeight, int maxDragHeight) { + if (refreshLayout != null) { + onFooterMoving(refreshLayout.getRefreshFooter(), isDragging, percent, offset, footerHeight, maxDragHeight); + } } @Override - public void onRefresh(RefreshLayout refreshlayout) { + public void onFooterReleased(com.scwang.smart.refresh.layout.api.RefreshFooter footer, int footerHeight, int maxDragHeight) { + if (refreshLayout != null) { + onFooterReleased(refreshLayout.getRefreshFooter(), footerHeight, maxDragHeight); + } + } + @Override + public void onFooterStartAnimator(com.scwang.smart.refresh.layout.api.RefreshFooter footer, int footerHeight, int maxDragHeight) { + if (refreshLayout != null) { + onFooterStartAnimator(refreshLayout.getRefreshFooter(), footerHeight, maxDragHeight); + } } @Override - public void onLoadmore(RefreshLayout refreshlayout) { + public void onFooterFinish(com.scwang.smart.refresh.layout.api.RefreshFooter footer, boolean success) { + if (refreshLayout != null) { + onFooterFinish(refreshLayout.getRefreshFooter(), success); + } + } + @Override + public void onLoadMore(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout) { + if (this.refreshLayout != null) { + onLoadMore(this.refreshLayout); + } } @Override - public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { + public void onRefresh(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout) { + if (this.refreshLayout != null) { + onRefresh(this.refreshLayout); + } + } + @Override + public void onStateChanged(@NonNull com.scwang.smart.refresh.layout.api.RefreshLayout refreshLayout, @NonNull com.scwang.smart.refresh.layout.constant.RefreshState oldState, @NonNull com.scwang.smart.refresh.layout.constant.RefreshState newState) { + if (this.refreshLayout != null) { + onStateChanged(this.refreshLayout, RefreshState.from(oldState), RefreshState.from(newState)); + } } } diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/DensityUtil.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/DensityUtil.java deleted file mode 100644 index 248d6c45..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/DensityUtil.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.scwang.smartrefresh.layout.util; - -import android.content.res.Resources; - -public class DensityUtil { - - float density; - - public DensityUtil() { - density = Resources.getSystem().getDisplayMetrics().density; - } - - /** - * 根据手机的分辨率从 dp 的单位 转成为 px(像素) - */ - public static int dp2px(float dpValue) { - return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density); - } - - /** - * 根据手机的分辨率从 px(像素) 的单位 转成为 dp - */ - public static float px2dp(float pxValue) { - return (pxValue / Resources.getSystem().getDisplayMetrics().density); - } - - /** - * 根据手机的分辨率从 dp 的单位 转成为 px(像素) - */ - public int dip2px(float dpValue) { - return (int) (0.5f + dpValue * density); - } - - /** - * 根据手机的分辨率从 px(像素) 的单位 转成为 dp - */ - public float px2dip(float pxValue) { - return (pxValue / density); - } -} \ No newline at end of file diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/ScrollBoundaryUtil.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/ScrollBoundaryUtil.java deleted file mode 100644 index a520b350..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/ScrollBoundaryUtil.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.scwang.smartrefresh.layout.util; - -import android.graphics.PointF; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AbsListView; - -/** - * 滚动边界 - * Created by SCWANG on 2017/7/8. - */ - -public class ScrollBoundaryUtil { - - // - public static boolean canScrollUp(View targetView, MotionEvent event) { - if (canScrollUp(targetView)) { - return true; - } - if (targetView instanceof ViewGroup && event != null) { - ViewGroup viewGroup = (ViewGroup) targetView; - final int childCount = viewGroup.getChildCount(); - PointF point = new PointF(); - for (int i = childCount; i > 0; i--) { - View child = viewGroup.getChildAt(i - 1); - if (isTransformedTouchPointInView(viewGroup,child, event.getX(), event.getY() , point)) { - event = MotionEvent.obtain(event); - event.offsetLocation(point.x, point.y); - return canScrollUp(child, event); - } - } - } - return false; - } - - public static boolean canScrollUp(View targetView) { - if (android.os.Build.VERSION.SDK_INT < 14) { - if (targetView instanceof AbsListView) { - final AbsListView absListView = (AbsListView) targetView; - return absListView.getChildCount() > 0 - && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0) - .getTop() < absListView.getPaddingTop()); - } else { - return targetView.getScrollY() > 0; - } - } else { - return targetView.canScrollVertically(-1); - } - } - - public static boolean canScrollDown(View targetView, MotionEvent event) { - if (canScrollDown(targetView)) { - return true; - } - if (targetView instanceof ViewGroup && event != null) { - ViewGroup viewGroup = (ViewGroup) targetView; - final int childCount = viewGroup.getChildCount(); - PointF point = new PointF(); - for (int i = 0; i < childCount; i++) { - View child = viewGroup.getChildAt(i); - if (isTransformedTouchPointInView(viewGroup,child, event.getX(), event.getY() , point)) { - event = MotionEvent.obtain(event); - event.offsetLocation(point.x, point.y); - return canScrollDown(child, event); - } - } - } - return false; - } - - public static boolean canScrollDown(View targetView) { - if (android.os.Build.VERSION.SDK_INT < 14) { - if (targetView instanceof AbsListView) { - final AbsListView absListView = (AbsListView) targetView; - return absListView.getChildCount() > 0 - && (absListView.getLastVisiblePosition() < absListView.getChildCount() - 1 - || absListView.getChildAt(absListView.getChildCount() - 1).getBottom() > absListView.getPaddingBottom()); - } else { - return targetView.getScrollY() < 0; - } - } else { - return targetView.canScrollVertically(1); - } - } - - // - - // - - public static boolean pointInView(View view, float localX, float localY, float slop) { - final float left = /*Math.max(view.getPaddingLeft(), 0)*/ - slop; - final float top = /*Math.max(view.getPaddingTop(), 0)*/ - slop; - final float width = view.getWidth()/* - Math.max(view.getPaddingLeft(), 0) - Math.max(view.getPaddingRight(), 0)*/; - final float height = view.getHeight()/* - Math.max(view.getPaddingTop(), 0) - Math.max(view.getPaddingBottom(), 0)*/; - return localX >= left && localY >= top && localX < ((width) + slop) && - localY < ((height) + slop); - } - - public static boolean isTransformedTouchPointInView(ViewGroup group, View child, float x, float y,PointF outLocalPoint) { - final float[] point = new float[2]; - point[0] = x; - point[1] = y; - transformPointToViewLocal(group, child, point); - final boolean isInView = pointInView(child, point[0], point[1], 0); - if (isInView && outLocalPoint != null) { - outLocalPoint.set(point[0]-x, point[1]-y); - } - return isInView; - } - - public static void transformPointToViewLocal(ViewGroup group, View child, float[] point) { - point[0] += group.getScrollX() - child.getLeft(); - point[1] += group.getScrollY() - child.getTop(); - } - // -} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/SmartUtil.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/SmartUtil.java new file mode 100644 index 00000000..571ef74e --- /dev/null +++ b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/SmartUtil.java @@ -0,0 +1,13 @@ +package com.scwang.smartrefresh.layout.util; + +/** + * SmartUtil + * Created by scwang on 2018/3/5. + */ +public class SmartUtil extends com.scwang.smart.refresh.layout.util.SmartUtil { + + private SmartUtil(int type) { + super(type); + } + +} diff --git a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/ViscousFluidInterpolator.java b/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/ViscousFluidInterpolator.java deleted file mode 100644 index eada0ad5..00000000 --- a/refresh-layout/src/main/java/com/scwang/smartrefresh/layout/util/ViscousFluidInterpolator.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.scwang.smartrefresh.layout.util; - -import android.view.animation.Interpolator; - -public class ViscousFluidInterpolator implements Interpolator { - /** Controls the viscous fluid effect (how much of it). */ - private static final float VISCOUS_FLUID_SCALE = 8.0f; - - private static final float VISCOUS_FLUID_NORMALIZE; - private static final float VISCOUS_FLUID_OFFSET; - - static { - - // must be set to 1.0 (used in viscousFluid()) - VISCOUS_FLUID_NORMALIZE = 1.0f / viscousFluid(1.0f); - // account for very small floating-point error - VISCOUS_FLUID_OFFSET = 1.0f - VISCOUS_FLUID_NORMALIZE * viscousFluid(1.0f); - } - - private static float viscousFluid(float x) { - x *= VISCOUS_FLUID_SCALE; - if (x < 1.0f) { - x -= (1.0f - (float)Math.exp(-x)); - } else { - float start = 0.36787944117f; // 1/e == exp(-1) - x = 1.0f - (float)Math.exp(1.0f - x); - x = start + x * (1.0f - start); - } - return x; - } - - @Override - public float getInterpolation(float input) { - final float interpolated = VISCOUS_FLUID_NORMALIZE * viscousFluid(input); - if (interpolated > 0) { - return interpolated + VISCOUS_FLUID_OFFSET; - } - return interpolated; - } - } \ No newline at end of file diff --git a/refresh-layout/src/main/res/values/attrs.xml b/refresh-layout/src/main/res/values/attrs.xml deleted file mode 100644 index f1e7397b..00000000 --- a/refresh-layout/src/main/res/values/attrs.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/refresh-layout/src/main/res/values/strings.xml b/refresh-layout/src/main/res/values/strings.xml deleted file mode 100644 index b5b95a55..00000000 --- a/refresh-layout/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - SmartRefreshLayout - diff --git a/settings.gradle b/settings.gradle index 9f7d4300..faa1e53f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,13 @@ -include ':app', ':refresh-layout', ':refresh-header', ':refresh-footer' +include ':app'//, ':app-design' +include ':refresh-layout', ':refresh-header', ':refresh-footer' + +include ':refresh-drawable-paint' +include ':refresh-drawable-path' +include ':refresh-layout-kernel' +include ':refresh-footer-ball' +include ':refresh-footer-classics' +include ':refresh-header-classics' +include ':refresh-header-falsify' +include ':refresh-header-radar' +include ':refresh-header-material' +include ':refresh-header-two-level'